Skip to content

Commit 41d7370

Browse files
committed
upd: hooks逻辑差进去
1 parent 1029e89 commit 41d7370

File tree

1 file changed

+202
-9
lines changed
  • packages/traction-widget/components/Charts

1 file changed

+202
-9
lines changed

packages/traction-widget/components/Charts/Charts.vue

Lines changed: 202 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@
2626
</template>
2727

2828
<script setup lang="ts">
29-
import { ref } from 'vue';
29+
import { ref, onMounted, onUnmounted, watch, markRaw } from 'vue';
3030
import { FDatePicker, FButton } from '@fesjs/fes-design';
3131
import { ReloadOutlined } from '@fesjs/fes-design/icon';
32-
import { useChart, type ChartConfig } from './useChart';
32+
import type { EChartsOption, TooltipComponentFormatterCallback } from 'echarts';
33+
import echarts from './useEcharts';
3334
import {
3435
getYear, getMonth, getDate, subDays, differenceInDays,
3536
format,
@@ -38,6 +39,24 @@ import { useLocale } from '../hooks/useLocale';
3839
3940
const locale = useLocale();
4041
const chartsLocale = locale.Charts;
42+
43+
interface BarStyle {
44+
color: string;
45+
borderColor: string;
46+
}
47+
48+
interface ChartConfig {
49+
title: string;
50+
series: {
51+
field: string;
52+
name: string;
53+
itemStyle: BarStyle;
54+
}[];
55+
fetchData: (startTime: number, endTime: number) => Promise<any[]>;
56+
xAxisField: string;
57+
tooltipFormatter?: (params: any[]) => string;
58+
}
59+
4160
interface Props {
4261
chartId: string;
4362
config: ChartConfig;
@@ -83,13 +102,187 @@ const updateDays = (newDays: number) => {
83102
endDate.value = _endDate.getTime();
84103
};
85104
86-
// 图表相关
87-
const { loading, updateChart } = useChart(
88-
props.chartId,
89-
props.config,
90-
startDate,
91-
endDate
92-
);
105+
// 图表相关逻辑
106+
let chartInstance: echarts.ECharts | null = null;
107+
const loading = ref(false);
108+
109+
const initChart = () => {
110+
const chartDom = document.getElementById(props.chartId);
111+
const instance = echarts.getInstanceByDom(chartDom as HTMLElement);
112+
if (instance) {
113+
instance.dispose();
114+
}
115+
if (chartDom) {
116+
chartInstance = markRaw(echarts.init(chartDom));
117+
}
118+
};
119+
120+
const transformData = (data: any[]) => {
121+
const xAxisData = data.map(item => item[props.config.xAxisField]);
122+
// 计算每个系列的总和
123+
const seriesTotal = props.config.series.reduce((acc, series) => {
124+
const total = data.reduce((sum, item) => sum + (Number(item[series.field]) || 0), 0);
125+
acc[series.name] = total;
126+
return acc;
127+
}, {} as Record<string, number>);
128+
129+
// 计算最大值来确定左侧留白
130+
let maxSum = 0;
131+
let leftGridSize = 16; // 基础留白大小
132+
133+
data.forEach(item => {
134+
// 计算所有系列的当前数据点总和
135+
const currentSum = props.config.series.reduce((sum, series) => {
136+
return sum + (item[series.field] || 0);
137+
}, 0);
138+
maxSum = Math.max(maxSum, currentSum);
139+
});
140+
141+
// 根据最大值的位数调整留白
142+
const maxSumLen = String(maxSum).length;
143+
if (maxSumLen > 0) {
144+
leftGridSize += (maxSumLen - 1) * 8;
145+
}
146+
147+
const series = props.config.series.map(item => ({
148+
name: item.name,
149+
type: 'bar' as const,
150+
data: data.map(d => d[item.field]),
151+
itemStyle: item.itemStyle,
152+
emphasis: {
153+
focus: 'series' as const
154+
}
155+
}));
156+
157+
return {
158+
xAxisData,
159+
series,
160+
leftGridSize,
161+
seriesTotal
162+
};
163+
};
164+
165+
const genTooltipStr = (tempData: any[]) => {
166+
const showList = tempData.map((item: { value: any; seriesName: any; }) => ({
167+
value: item.value,
168+
name: item.seriesName
169+
}));
170+
const dateStr = showList.length ? `${chartsLocale.date}${tempData[0].name} <br />` : '';
171+
const total = showList.reduce((pre: any, cur: { value: any; }) => pre + cur.value, 0);
172+
const totalStr = showList.length ? `${chartsLocale.total}${total} <br />` : '';
173+
const showListStr = showList.reduce((pre: any, cur: { name: any; value: any; }) =>
174+
`${pre}${cur.name}: ${cur.value}<br />`, '');
175+
return dateStr + totalStr + showListStr;
176+
};
177+
178+
const updateChart = async () => {
179+
if (!chartInstance) return;
180+
181+
try {
182+
loading.value = true;
183+
const data = await props.config.fetchData(startDate.value, endDate.value);
184+
const { xAxisData, series, leftGridSize, seriesTotal } = transformData(data);
185+
186+
const option: EChartsOption = {
187+
backgroundColor: '#fff',
188+
grid: {
189+
top: 17,
190+
right: 0,
191+
left: leftGridSize,
192+
bottom: 95,
193+
containLabel: true
194+
},
195+
tooltip: {
196+
trigger: 'axis',
197+
axisPointer: {
198+
type: "shadow",
199+
},
200+
formatter: ((params) => {
201+
const formattedParams = params as any[];
202+
return props.config.tooltipFormatter
203+
? props.config.tooltipFormatter(formattedParams)
204+
: genTooltipStr(formattedParams);
205+
}) as TooltipComponentFormatterCallback<any>
206+
},
207+
dataZoom: {
208+
type: 'slider',
209+
startValue: 0,
210+
endValue: 6,
211+
xAxisIndex: [0],
212+
handleSize: 0,
213+
height: 5,
214+
bottom: 70,
215+
borderColor: 'transparent',
216+
fillerColor: 'transparent',
217+
backgroundColor: 'transparent',
218+
showDataShadow: false,
219+
showDetail: false,
220+
realtime: true,
221+
filterMode: 'filter'
222+
},
223+
legend: {
224+
bottom: 0,
225+
icon: 'rect',
226+
height: 20,
227+
itemWidth: 10,
228+
itemHeight: 10,
229+
itemGap: 32,
230+
itemStyle: {
231+
borderWidth: 1
232+
},
233+
formatter: (name) => {
234+
return `${name}(${seriesTotal[name]})`;
235+
},
236+
data: props.config.series.map(item => ({
237+
name: item.name,
238+
itemStyle: item.itemStyle
239+
}))
240+
},
241+
xAxis: [{
242+
type: 'category',
243+
axisTick: { show: false },
244+
axisLine: { show: false },
245+
data: xAxisData
246+
}],
247+
yAxis: [{
248+
type: 'value',
249+
splitLine: {
250+
lineStyle: {
251+
width: 1,
252+
color: '#F1F1F2'
253+
}
254+
}
255+
}],
256+
series
257+
};
258+
259+
chartInstance.setOption(option);
260+
} finally {
261+
loading.value = false;
262+
}
263+
};
264+
265+
const handleResize = () => {
266+
chartInstance?.resize();
267+
};
268+
269+
// 监听日期变化
270+
watch([startDate, endDate], () => {
271+
updateChart();
272+
}, {
273+
immediate: true
274+
});
275+
276+
onMounted(() => {
277+
initChart();
278+
updateChart();
279+
window.addEventListener('resize', handleResize);
280+
});
281+
282+
onUnmounted(() => {
283+
window.removeEventListener('resize', handleResize);
284+
chartInstance?.dispose();
285+
});
93286
94287
const lastUpdateTime = ref(format(new Date(), 'yyyy-MM-dd HH:mm:ss'));
95288

0 commit comments

Comments
 (0)