Compare commits

..

No commits in common. "d225f1be79c9b043f416f219841abfee61eeb962" and "6529454bb3b5459a5d555901d6a82aa778695e89" have entirely different histories.

4 changed files with 153 additions and 114 deletions

View File

@ -2,17 +2,22 @@
<div class="map-center-warp"> <div class="map-center-warp">
<!-- <img :src="getAssetsFile('images/vsualized/gmmap.png')" class="map-img" /> --> <!-- <img :src="getAssetsFile('images/vsualized/gmmap.png')" class="map-img" /> -->
<div class="map-pos"> <div class="map-pos">
<custom-echart-maps height="100%" width="100%" :option="chartsData.option" :geo="geoData" :name="mapName" /> <custom-echart-maps
:chart-data="chartsData.valData"
height="100%"
width="100%"
:option="chartsData.option"
:geo="geoData"
:name="mapName"
@click="mapClick"
/>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { isEmpty, getAssetsFile } from '@/utils'; import { isEmpty, getAssetsFile } from '@/utils';
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import geoJsonData from '../components/530926geo.json'; // import geoJsonData from '../components/530926geo.json'; //
const route = useRoute();
var aspectScale = 0.8807505292367753; var aspectScale = 0.8807505292367753;
// var iconUrl = 'http://localhost:9529/sub-government-screen-service/src/assets/images/vsualized/home/partbg.png'; // var iconUrl = 'http://localhost:9529/sub-government-screen-service/src/assets/images/vsualized/home/partbg.png';
// var iconUrl = getAssetsFile('images/vsualized/gmmap.png').href; // var iconUrl = getAssetsFile('images/vsualized/gmmap.png').href;
@ -20,7 +25,8 @@ var iconUrl = getAssetsFile('images/vsualized/gmmap2.png').href;
const isShow = ref(false); const isShow = ref(false);
let geoData = geoJsonData; let geoData = geoJsonData;
let mapName = ref('ZJ' + route.name); let mapName = ref('ZJ');
const info = ref({});
const chartsData = reactive({ const chartsData = reactive({
option: { option: {
title: { title: {
@ -50,12 +56,11 @@ const chartsData = reactive({
geo3D: { geo3D: {
map: mapName.value, map: mapName.value,
roam: true, roam: true,
zoom: 1, zoom: 1.2,
left: '30px',
show: true, show: true,
zlevel: -1, // zlevel: -1, //
viewControl: { viewControl: {
distance: 115, distance: 110,
alpha: 60, alpha: 60,
beta: 0, beta: 0,
minBeta: -360, minBeta: -360,
@ -98,56 +103,132 @@ const chartsData = reactive({
}, },
}, },
series: [ series: [
//
{ {
type: 'map3D', name: '闪烁散点',
map: mapName.value, type: 'effectScatter', // 使 effectScatter
zoom: 1, coordinateSystem: 'geo',
left: '30px', data: [
viewControl: { //
distance: 115, {
alpha: 60, name: '孟定镇',
beta: 0, value: [99.081993, 23.554045, 100], // , ,
minBeta: -360, itemStyle: {
maxBeta: 720, color: '#FF0000', //
// 使 },
// rotateSensitivity: 0, },
// zoomSensitivity: 0, {
// panSensitivity: 0, name: '勐永镇',
}, value: [99.406653, 23.534142, 80], // , ,
itemStyle: { itemStyle: {
// color: '#00FF00', //
color: 'rgba(75,255,180,0.2)', // },
opacity: 1, // [ default: 1 ] },
borderWidth: 1.5, // (线) [ default: 0 ] ],
borderColor: '#4bffb4', // [ default: #333 ] symbolSize: function (val) {
return val[2] ? val[2] / 10 : 10; //
}, },
label: { label: {
show: true, formatter: '{b}',
distance: 0, position: 'right',
color: '#000', show: false,
padding: [6, 4, 2, 4],
borderRadius: 4,
backgroundColor: 'rgba(255,255,255,0.2)',
textStyle: {
fontSize: 12,
color: '#E87813', //
borderWidth: 0,
borderColor: '#000',
},
}, },
emphasis: { rippleEffect: {
// period: 4, //
label: { scale: 3, //
show: true, brushType: 'stroke', // 'stroke' 'fill'
color: '#fff',
},
itemStyle: {
color: 'rgba(75,255,180,0.3)', //
},
}, },
hoverAnimation: false,
}, },
], ],
}, },
valData: [
{
map: mapName.value,
roam: true,
zoom: 0.9,
show: true,
itemStyle: {
//
color: 'rgba(75,255,180,0.2)', //
opacity: 1, // [ default: 1 ]
borderWidth: 1.5, // (线) [ default: 0 ]
borderColor: 'rgba(92, 184, 238, 1)', // [ default: #333 ]
},
label: {
show: true,
distance: 0,
color: '#000',
padding: [6, 4, 2, 4],
borderRadius: 4,
backgroundColor: 'rgba(255,255,255,.66)',
textStyle: {
fontSize: 12,
color: '#E87813', //
borderWidth: 0,
borderColor: '#000',
},
},
// emphasis: {
// //
// label: {
// show: true,
// color: '#fff',
// },
// itemStyle: {
// // show: false,
// areaColor: {
// type: 'linear',
// x: 0,
// y: 0,
// x2: 1,
// y2: 0,
// colorStops: [
// { offset: 0, color: '#4bffb4' },
// { offset: 1, color: '#4bffb4' },
// ],
// },
// },
// },
},
//
{
name: '闪烁散点',
type: 'effectScatter', // 使 effectScatter
coordinateSystem: 'geo',
data: [
//
{
name: '孟定镇',
value: [99.081993, 23.554045, 100], // , ,
itemStyle: {
color: '#FF0000', //
},
},
{
name: '贺派乡',
value: [99.406653, 23.534142, 80], // , ,
itemStyle: {
color: '#00FF00', //
},
},
],
symbolSize: function (val) {
return val[2] ? val[2] / 10 : 10; //
},
label: {
formatter: '{b}',
position: 'right',
show: false,
},
rippleEffect: {
period: 4, //
scale: 3, //
brushType: 'stroke', // 'stroke' 'fill'
},
hoverAnimation: false,
},
],
}); });
const mapClick = (data) => { const mapClick = (data) => {

View File

@ -1,5 +1,5 @@
<template> <template>
<div ref="chartMap" :style="{ height, width }"></div> <div ref="chartRef" :style="{ height, width }"></div>
</template> </template>
<script> <script>
import { ref, reactive, watch, watchEffect } from 'vue'; import { ref, reactive, watch, watchEffect } from 'vue';
@ -42,13 +42,13 @@ export default {
}, },
emits: ['click'], emits: ['click'],
setup(props, { emit }) { setup(props, { emit }) {
const chartMap = ref(null); const chartRef = ref(null);
const { setOptions, getInstance, resize, regMap, startAutoPlay, onMapClick } = useEcharts(chartMap); const { setOptions, getInstance, resize, registerMap, startAutoPlay } = useEcharts(chartRef);
const option = reactive({}); const option = reactive({
// series: [],
});
watchEffect(() => { watchEffect(() => {
regMap(props.name, props.geo);
console.info('watchEffect');
props.chartData && initCharts(); props.chartData && initCharts();
}); });
@ -66,22 +66,25 @@ export default {
if (props.option) { if (props.option) {
Object.assign(option, cloneDeep(props.option)); Object.assign(option, cloneDeep(props.option));
} }
// option.series = props.chartData;
setOptions(option); setOptions(option);
onMapClick(({ name, data }) => {
console.info('onMapClick点击区域:', name);
// console.info('onMapClick:', data);
// emit('click', { name, data });
});
startAutoPlay({ startAutoPlay({
interval: 2000, interval: 2000,
seriesIndex: 0, seriesIndex: 0,
showTooltip: true, showTooltip: true,
}); });
registerMap(props.name, props.geo);
resize(); resize();
getInstance()?.off('click', onClick);
getInstance()?.on('click', onClick);
} }
return { chartMap }; function onClick(params) {
console.info('地图onClick', params);
emit('click', params);
}
return { chartRef };
}, },
}; };
</script> </script>

View File

@ -1,4 +1,4 @@
import { unref, nextTick, watch, computed, ref, markRaw } from 'vue'; import { unref, nextTick, watch, computed, ref } from 'vue';
import { useDebounceFn, tryOnUnmounted } from '@vueuse/core'; import { useDebounceFn, tryOnUnmounted } from '@vueuse/core';
import { useTimeoutFn } from './useTimeout'; import { useTimeoutFn } from './useTimeout';
import { useEventListener } from './useEventListener'; import { useEventListener } from './useEventListener';
@ -11,8 +11,6 @@ export const useEcharts = (elRef, theme = 'default') => {
const currentIndex = ref(-1); const currentIndex = ref(-1);
const dataLength = ref(0); const dataLength = ref(0);
let mapClickHandler = null;
// 新增方法 - 启动轮播 // 新增方法 - 启动轮播
const startAutoPlay = (options = {}) => { const startAutoPlay = (options = {}) => {
const { const {
@ -62,7 +60,6 @@ export const useEcharts = (elRef, theme = 'default') => {
const getDarkMode = computed(() => { const getDarkMode = computed(() => {
return theme === 'default' ? 'dark' : theme; return theme === 'default' ? 'dark' : theme;
}); });
let chartInstance = null; let chartInstance = null;
let resizeFn = resize; let resizeFn = resize;
const cacheOptions = ref({}); const cacheOptions = ref({});
@ -92,8 +89,7 @@ export const useEcharts = (elRef, theme = 'default') => {
return; return;
} }
chartInstance = markRaw(echarts.init(el, t)); chartInstance = echarts.init(el, t);
const { removeEvent } = useEventListener({ const { removeEvent } = useEventListener({
el: window, el: window,
name: 'resize', name: 'resize',
@ -109,34 +105,6 @@ export const useEcharts = (elRef, theme = 'default') => {
}); });
} }
function handleMapClick(params) {
// 过滤非地图区域的点击事件
if (params.componentType === 'geo3D' || params.componentType === 'geo') {
// 获取点击区域信息
const mapName = params.name;
const regionData = params.data || {};
// 执行注册的回调函数
if (typeof mapClickHandler === 'function') {
mapClickHandler({
name: mapName,
data: regionData,
coordinates: params.event?.event?.point,
// originalParams: params
});
}
}
}
function onMapClick(handler) {
mapClickHandler = handler;
// 返回解绑方法
return () => {
mapClickHandler = null;
};
}
function setOptions(options = {}, clear = true) { function setOptions(options = {}, clear = true) {
const mergedOptions = { const mergedOptions = {
animation: true, animation: true,
@ -162,11 +130,8 @@ export const useEcharts = (elRef, theme = 'default') => {
if (!chartInstance) return; if (!chartInstance) return;
} }
clear && chartInstance?.clear(); clear && chartInstance?.clear();
chartInstance?.setOption(unref(getOptions));
// 立即绑定事件 chartInstance?.setOption(unref(getOptions));
chartInstance.off('click');
chartInstance.on('click', handleMapClick);
}, 30); }, 30);
}); });
} }
@ -180,16 +145,12 @@ export const useEcharts = (elRef, theme = 'default') => {
* @param {string} mapName - 地图名称 * @param {string} mapName - 地图名称
* @param {object} geoJSON - GeoJSON 数据 * @param {object} geoJSON - GeoJSON 数据
*/ */
function regMap(mapName, geoJSON) { function registerMap(mapName, geoJSON) {
if (!mapName || !geoJSON) { if (!mapName || !geoJSON) {
console.warn('地图名称或 GeoJSON 数据无效'); console.warn('地图名称或 GeoJSON 数据无效');
return; return;
} }
echarts.registerMap(mapName, geoJSON);
console.info('getMap', echarts.getMap(mapName));
if (!echarts.getMap(mapName)) {
echarts.registerMap(mapName, geoJSON, { override: true });
}
} }
watch( watch(
@ -206,9 +167,6 @@ export const useEcharts = (elRef, theme = 'default') => {
tryOnUnmounted(() => { tryOnUnmounted(() => {
stopAutoPlay(); // 清理定时器 stopAutoPlay(); // 清理定时器
if (!chartInstance) return; if (!chartInstance) return;
if (chartInstance) {
chartInstance.off('click', handleMapClick);
}
removeResizeFn(); removeResizeFn();
chartInstance.dispose(); chartInstance.dispose();
chartInstance = null; chartInstance = null;
@ -226,9 +184,8 @@ export const useEcharts = (elRef, theme = 'default') => {
resize, resize,
echarts, echarts,
getInstance: () => chartInstance, getInstance: () => chartInstance,
regMap, registerMap,
startAutoPlay, // 暴露轮播方法 startAutoPlay, // 暴露轮播方法
stopAutoPlay, stopAutoPlay,
onMapClick,
}; };
}; };

View File

@ -31,7 +31,6 @@ import {
TimelineComponent, TimelineComponent,
CalendarComponent, CalendarComponent,
GraphicComponent, GraphicComponent,
GeoComponent,
} from 'echarts/components'; } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers'; import { CanvasRenderer } from 'echarts/renderers';
@ -62,7 +61,6 @@ echarts.use([
GaugeChart, GaugeChart,
ScatterChart, ScatterChart,
EffectScatterChart, EffectScatterChart,
GeoComponent,
]); ]);
export default echarts; export default echarts;