CviLux_fe/src/components/chart/EffectScatter.vue
2025-07-28 16:49:44 +08:00

94 lines
2.2 KiB
Vue

<script setup>
import * as echarts from "echarts";
import { onMounted, ref, markRaw, nextTick } from "vue";
import axios from "axios";
const props = defineProps({
option: Object,
className: String,
id: String,
svg: Object,
getCoordinate: {
type: Function,
default: null,
},
});
let chart = ref(null);
let dom = ref(null);
let currentClickPosition = ref([]);
async function updateSvg(svg, option) {
if (!chart.value && dom.value && svg) {
init();
} else {
clear();
}
axios.get(svg.path).then(async ({ data }) => {
echarts.registerMap(svg.full_name, { svg: data });
await nextTick();
// 延遲執行以避免在主進程中調用 setOption
setTimeout(() => {
if (chart.value && !chart.value.isDisposed()) {
chart.value.setOption(option);
}
}, 0);
if (props.getCoordinate) {
chart.value.getZr().on("click", function (params) {
var pixelPoint = [params.offsetX, params.offsetY];
var dataPoint = chart.value.convertFromPixel(
{ geoIndex: 0 },
pixelPoint
);
currentClickPosition.value = dataPoint;
props.getCoordinate(dataPoint);
const updatedData = option.series.data
.filter(
(point) => !(point.itemStyle && point.itemStyle.color === "#0000FF")
)
.concat({
value: dataPoint, // 當前座標值
itemStyle: { color: "#0000FF" }, // 設為藍色
});
setTimeout(() => {
if (chart.value && !chart.value.isDisposed()) {
chart.value.setOption({
series: {
data: updatedData,
},
});
}
}, 0);
});
}
});
console.log("updateSvg", svg.path);
}
function clear() {
chart.value.clear();
}
function init() {
const curChart = echarts.init(dom.value);
chart.value = markRaw(curChart);
}
onMounted(() => {
if (!chart.value && dom.value && props.svg) {
init();
}
});
defineExpose({
chart,
currentClickPosition,
updateSvg,
});
</script>
<template>
<div :id="id" class="min-h-[70vh] max-h-fit w-full" ref="dom"></div>
</template>
<style lang="scss" scoped></style>