@oiij/e-charts
Version:
A Vue Composable for ECharts
106 lines (104 loc) • 2.73 kB
JavaScript
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 };