UNPKG

@oiij/e-charts

Version:

A Vue Composable for ECharts

106 lines (104 loc) 2.73 kB
import { createEventHook, useDebounceFn, useElementSize } from "@vueuse/core"; import { BarChart, LineChart, PieChart } from "echarts/charts"; import { DatasetComponent, GridComponent, LegendComponent, TitleComponent, ToolboxComponent, TooltipComponent, TransformComponent } from "echarts/components"; import { init, use } from "echarts/core"; import { LabelLayout, UniversalTransition } from "echarts/features"; import { CanvasRenderer } from "echarts/renderers"; import { onUnmounted, ref, shallowRef, toValue, watch, watchEffect } from "vue"; //#region src/index.ts const baseChat = [ BarChart, LineChart, PieChart ]; use([ TitleComponent, LegendComponent, TooltipComponent, GridComponent, DatasetComponent, TransformComponent, ToolboxComponent, LabelLayout, UniversalTransition, CanvasRenderer, ...baseChat ]); function register(ext) { use(ext); } function useECharts(options, darkMode, initOptions) { const domRef = shallowRef(); const eChart = shallowRef(null); const optionsRef = ref(toValue(options)); watchEffect(() => { optionsRef.value = toValue(options); }); const { width, height } = useElementSize(domRef); const onRenderEvent = createEventHook(); const onUpdateEvent = createEventHook(); const onResizeEvent = createEventHook(); const onDisposeEvent = createEventHook(); function setOption(updateOptions) { if (eChart.value) { eChart.value.setOption(updateOptions); onUpdateEvent.trigger(updateOptions); } } function render() { if (domRef.value) { if (eChart.value) { resize(); return; } const theme = darkMode?.value ? "dark" : "default"; if (optionsRef.value) { eChart.value = init(domRef.value, theme, { ...initOptions }); setOption(optionsRef.value); onRenderEvent.trigger(eChart.value); } } } const renderDebounce = useDebounceFn(render, 100); function resize() { if (eChart.value) { eChart.value.resize(); onResizeEvent.trigger({ width: width.value, height: height.value }); } } const resizeDebounce = useDebounceFn(resize, 100); function destroy() { eChart.value?.dispose(); eChart.value = null; onDisposeEvent.trigger(); } watch([width, height], ([width$1, height$1]) => { if (width$1 > 0 && height$1 > 0) if (eChart.value) resizeDebounce(); else renderDebounce(); }); watch(optionsRef, (v) => { if (v) if (eChart.value) setOption(v); else render(); }); watchEffect(() => { destroy(); render(); }); onUnmounted(() => { destroy(); }); return { domRef, eChart, options: optionsRef, onRender: onRenderEvent.on, onUpdate: onUpdateEvent.on, onResize: onResizeEvent.on, onDispose: onDisposeEvent.on }; } //#endregion export { baseChat, register, useECharts };