Files
console-dev/app/components/ChartBox.vue
T
2026-11-06 00:04:38 +08:00

88 lines
2.2 KiB
Vue

<script setup>
import { computed, onMounted, onBeforeUnmount, ref } from "vue";
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { LineChart } from "echarts/charts";
import {
GridComponent,
TooltipComponent,
LegendComponent,
} from "echarts/components";
import VChart from "vue-echarts";
import { t as useTheme } from "~/lib/useTheme.js";
import "~/assets/styles/ChartBox.CYP_mhat.css";
use([
CanvasRenderer,
LineChart,
GridComponent,
TooltipComponent,
LegendComponent,
]);
const props = defineProps({
option: { type: Object, required: true },
height: { default: 140 },
loading: Boolean,
});
const theme = useTheme();
const container = ref(null);
const visible = ref(false);
let observer;
onMounted(() => {
observer = new ResizeObserver(([entry]) => {
if (entry?.contentRect.width > 0 && entry.contentRect.height > 0)
visible.value = true;
});
if (container.value) observer.observe(container.value);
});
onBeforeUnmount(() => observer?.disconnect());
const themedOption = computed(() => {
const dark = theme.isDark.value;
const color = dark ? "#a1a1aa" : "#94a3b8";
const grid = dark ? "rgba(255,255,255,.08)" : "rgba(0,0,0,.06)";
const axis = {
axisLine: { lineStyle: { color: grid } },
axisLabel: { color, fontSize: 11 },
};
const apply = (value, y = false) => ({
...axis,
...value,
...(y ? { splitLine: { lineStyle: { color: grid } } } : {}),
});
return {
textStyle: { color },
...props.option,
xAxis: Array.isArray(props.option.xAxis)
? props.option.xAxis.map((value) => apply(value))
: apply(props.option.xAxis),
yAxis: Array.isArray(props.option.yAxis)
? props.option.yAxis.map((value) => apply(value, true))
: apply(props.option.yAxis, true),
};
});
</script>
<template>
<div ref="container" class="chart-box" :style="{ height: `${height}px` }">
<VChart
v-if="visible"
:option="themedOption"
:loading="loading"
autoresize
class="chart"
/>
</div>
</template>
<style scoped>
.chart-box {
width: 100%;
min-width: 0;
overflow: hidden;
}
.chart {
width: 100%;
height: 100%;
}
</style>