| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <script lang="ts" setup>
- import * as echarts from 'echarts'
- import {
- ANIMATION,
- ChartData,
- createLegend,
- createTooltip,
- FONT_FAMILY,
- formatDateLabel,
- formatSeriesName,
- THEME
- } from '@/utils/kb'
- import { IotStatApi } from '@/api/pms/stat'
- const chartData = ref<ChartData>({
- xAxis: [],
- series: []
- })
- const chartRef = ref<HTMLDivElement>()
- let chart: echarts.ECharts | null = null
- function getChartOption(data: ChartData): echarts.EChartsOption {
- const xAxisData = data.xAxis || []
- const seriesData = data.series || []
- return {
- ...ANIMATION,
- grid: { ...THEME.grid, top: 36 },
- tooltip: createTooltip({
- trigger: 'axis',
- axisPointer: {
- type: 'line'
- }
- }),
- legend: createLegend(
- { top: 5 },
- seriesData.map((item) => formatSeriesName(item.name))
- ),
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: xAxisData,
- axisLine: {
- show: false
- },
- axisTick: {
- show: false
- },
- axisLabel: {
- color: THEME.text.regular,
- fontSize: 14,
- fontFamily: FONT_FAMILY,
- formatter(value: string) {
- return formatDateLabel(value)
- }
- }
- },
- yAxis: [
- {
- type: 'value',
- splitNumber: 4,
- axisLabel: {
- color: THEME.text.regular,
- fontSize: 12,
- fontFamily: FONT_FAMILY
- },
- splitLine: {
- lineStyle: {
- color: THEME.split,
- type: 'dashed'
- }
- },
- axisLine: {
- lineStyle: {
- color: THEME.split
- }
- },
- position: 'left'
- },
- {
- type: 'value',
- splitNumber: 4,
- axisLabel: {
- color: THEME.text.regular,
- fontSize: 12,
- fontFamily: FONT_FAMILY
- },
- splitLine: {
- show: false
- },
- axisLine: {
- lineStyle: {
- color: THEME.split
- }
- },
- position: 'right'
- }
- ],
- series: seriesData.map((item, index) => {
- const colorList = Object.values(THEME.color)
- const color = colorList[index % colorList.length]
- const yAxisIndex = index < 2 ? 0 : 1
- return {
- name: formatSeriesName(item.name),
- type: 'line',
- smooth: true,
- data: item.data,
- yAxisIndex,
- symbol: 'circle',
- symbolSize: 8,
- showSymbol: true,
- lineStyle: {
- width: 2,
- color: color.line
- },
- itemStyle: {
- color: color.line
- },
- areaStyle: {
- color: color.bg
- },
- emphasis: {
- focus: 'series',
- scale: true
- }
- }
- })
- }
- }
- function initChart() {
- if (!chartRef.value) return
- if (chart) {
- chart.dispose()
- }
- chart = echarts.init(chartRef.value, undefined, {
- renderer: 'svg'
- })
- renderChart()
- }
- function renderChart() {
- if (!chart) return
- const data = chartData.value || []
- chart.setOption(getChartOption(data), true)
- }
- function resizeChart() {
- chart?.resize()
- }
- function destroyChart() {
- if (chart) {
- chart.dispose()
- chart = null
- }
- }
- async function loadChart() {
- try {
- const res = await IotStatApi.getOrderSeven()
- chartData.value = {
- xAxis: res.xAxis || [],
- series: (res.series || []).map((item) => ({
- name: item.name,
- data: item.data || []
- }))
- }
- renderChart()
- } catch (error) {
- console.error('获取近7日工单趋势失败:', error)
- chartData.value = {
- xAxis: [],
- series: []
- }
- renderChart()
- }
- }
- onMounted(() => {
- initChart()
- loadChart()
- window.addEventListener('resize', resizeChart)
- window.addEventListener('homekb:resize', resizeChart)
- })
- onUnmounted(() => {
- window.removeEventListener('resize', resizeChart)
- window.removeEventListener('homekb:resize', resizeChart)
- destroyChart()
- })
- </script>
- <template>
- <div class="panel flex flex-col">
- <div class="panel-title">
- <div class="icon-decorator">
- <span></span>
- <span></span>
- </div>
- 工单数量统计
- </div>
- <div ref="chartRef" class="flex-1 min-h-0"></div>
- </div>
- </template>
- <style lang="scss" scoped>
- @import url('@/styles/kb.scss');
- </style>
|