209 lines
6.5 KiB
Vue
209 lines
6.5 KiB
Vue
<template>
|
|
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, onBeforeUnmount, useTemplateRef, watch } from "vue";
|
|
import * as echarts from "echarts";
|
|
import dayjs from "dayjs";
|
|
|
|
const props = defineProps({
|
|
labels: {
|
|
type: Object,
|
|
default: () => [],
|
|
},
|
|
data: {
|
|
type: Object,
|
|
default: () => [
|
|
{ text: "荤菜", name: "hc", values: [0, 0, 0, 0, 0, 0, 0, 0] },
|
|
{ text: "素菜", name: "sc", values: [0, 0, 0, 0, 0, 0, 0, 0] },
|
|
{ text: "主食", name: "zs", values: [0, 0, 0, 0, 0, 0, 0, 0] },
|
|
],
|
|
},
|
|
});
|
|
|
|
const chartRef = useTemplateRef("chartRef");
|
|
let chartInstance = null;
|
|
|
|
watch(
|
|
() => [props.data, props.labels],
|
|
(val) => {
|
|
if (!chartInstance) return;
|
|
chartInstance.setOption({
|
|
xAxis: {
|
|
data: props.labels?.map((v) => v.split("|")[1]) ?? [],
|
|
},
|
|
series: props.data.map((item, i) => {
|
|
return {
|
|
type: "bar",
|
|
stack: 'total',
|
|
name: item.text,
|
|
showBackground: false,
|
|
barGap: "50%",
|
|
itemStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: linearGradientColors[i][2] },
|
|
{ offset: 0.5, color: linearGradientColors[i][1] },
|
|
{ offset: 1, color: linearGradientColors[i][0] },
|
|
]),
|
|
borderColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: linearGradientColors[i][0] },
|
|
{ offset: 0.7, color: linearGradientColors[i][1] },
|
|
{ offset: 1, color: linearGradientColors[i][0] },
|
|
]),
|
|
},
|
|
emphasis: {
|
|
itemStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: linearGradientColors[i][2] },
|
|
{ offset: 0.5, color: linearGradientColors[i][0] },
|
|
{ offset: 1, color: linearGradientColors[i][1] },
|
|
]),
|
|
},
|
|
},
|
|
data: item.values,
|
|
};
|
|
}),
|
|
});
|
|
},
|
|
{ deep: true }
|
|
);
|
|
|
|
const colors = ["#287CE7", "#F4CF3D", "#30C6DC"];
|
|
const linearGradientColors = [
|
|
["#01A5FA", "#086BA5", "#0E385A"],
|
|
["#E0B60D", "#78752F", "#143750"],
|
|
["#15D1C4", "#117883", "#0F3654"],
|
|
];
|
|
|
|
const option = {
|
|
backgroundColor: "transparent",
|
|
grid: {
|
|
top: "14%",
|
|
left: "0%",
|
|
right: "0%",
|
|
bottom: "4%",
|
|
containLabel: true,
|
|
},
|
|
tooltip: {
|
|
trigger: "axis",
|
|
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
|
borderColor: "#000000",
|
|
borderWidth: 1,
|
|
textStyle: {
|
|
color: "#ffffff",
|
|
fontSize: 12,
|
|
},
|
|
padding: 10,
|
|
valueFormatter: (value) => `${value}份`,
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: [],
|
|
axisLabel: {
|
|
color: "#ffffff",
|
|
fontSize: 10,
|
|
},
|
|
axisLine: {
|
|
lineStyle: {
|
|
color: "#21303C",
|
|
},
|
|
},
|
|
},
|
|
yAxis: {
|
|
min: 0,
|
|
axisLine: {
|
|
lineStyle: {
|
|
color: "#00ffff",
|
|
},
|
|
},
|
|
axisLabel: {
|
|
color: "#ffffff",
|
|
fontSize: 10,
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
color: "rgba(255, 255, 255, 0.2)",
|
|
},
|
|
},
|
|
},
|
|
legend: {
|
|
icon: "rect",
|
|
right: 0,
|
|
top: 0,
|
|
itemWidth: 10,
|
|
itemHeight: 8,
|
|
itemGap: 16,
|
|
textStyle: { color: "#ffffff", fontSize: 9 },
|
|
itemStyle: { borderWidth: 0, borderColor: "transparent" },
|
|
data: props.data.map((item, i) => {
|
|
return { name: item.text, itemStyle: { color: colors[i], borderWidth: 0, borderColor: "transparent" } };
|
|
}),
|
|
},
|
|
series: props.data.map((item, i) => {
|
|
return {
|
|
type: "bar",
|
|
stack: 'total',
|
|
name: item.text,
|
|
showBackground: false,
|
|
barGap: "50%",
|
|
itemStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: linearGradientColors[i][2] },
|
|
{ offset: 0.5, color: linearGradientColors[i][1] },
|
|
{ offset: 1, color: linearGradientColors[i][0] },
|
|
]),
|
|
borderColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: linearGradientColors[i][0] },
|
|
{ offset: 0.7, color: linearGradientColors[i][1] },
|
|
{ offset: 1, color: linearGradientColors[i][0] },
|
|
]),
|
|
},
|
|
emphasis: {
|
|
itemStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{ offset: 0, color: linearGradientColors[i][2] },
|
|
{ offset: 0.5, color: linearGradientColors[i][0] },
|
|
{ offset: 1, color: linearGradientColors[i][1] },
|
|
]),
|
|
},
|
|
},
|
|
data: item.values,
|
|
};
|
|
}),
|
|
};
|
|
|
|
const resizeHandler = () => {
|
|
if (chartInstance) chartInstance.resize();
|
|
};
|
|
|
|
onMounted(() => {
|
|
if (!chartRef.value) return;
|
|
chartInstance = echarts.init(chartRef.value);
|
|
chartInstance.setOption(option);
|
|
window.addEventListener("resize", resizeHandler);
|
|
|
|
chartInstance.on("click", function (params) {
|
|
const target = props.labels[params.dataIndex];
|
|
if (!target) return;
|
|
const [timeStr, _] = target.split("|");
|
|
const _params = {
|
|
swingTimeList: [
|
|
dayjs(timeStr).startOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
|
dayjs(timeStr).endOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
|
],
|
|
};
|
|
console.log(`|点击跳转|-|打卡统计|-|本周|params:|{${JSON.stringify(_params)}}|`);
|
|
jumpAdminPath("door_reign_record", _params);
|
|
});
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener("resize", resizeHandler);
|
|
if (chartInstance) {
|
|
chartInstance.dispose();
|
|
chartInstance = null;
|
|
}
|
|
});
|
|
</script>
|