Commit 3a96054fcbe777886058d355d11ffbc4c6d16a21

Authored by fengtao
1 parent 90d831c0

perf: 优化接口调用历史折线图显示

1   -<script setup lang="ts">
2   - import { Descriptions, Progress, Skeleton, Tooltip, DescriptionsItem } from 'ant-design-vue';
3   -
4   - defineProps({
5   - seriesData: {
6   - type: Array as PropType<Recordable[]>,
7   - default: () => [],
8   - },
9   - });
10   -</script>
11   -<template>
12   - <div class="m-16">
13   - <Skeleton active :paragraph="{ rows: 10 }" :loading="!seriesData">
14   - <Descriptions :column="1">
15   - <template v-for="(item, index) in seriesData" :key="item.label">
16   - <DescriptionsItem>
17   - <span
18   - class="mr-2 item-span"
19   - :style="{
20   - color:
21   - index === 0
22   - ? '#f0a16e'
23   - : index === 1
24   - ? '#868585'
25   - : index === 2
26   - ? '#e78739'
27   - : '#4e84f5',
28   - backgroundColor:
29   - index === 0 ? '#FAD672' : index === 1 ? '#CBCAC9' : index === 2 ? '#F1B889' : '',
30   - borderColor:
31   - index === 0
32   - ? '#fdee7d'
33   - : index === 1
34   - ? '#e6e6e5'
35   - : index === 2
36   - ? '#f8c296'
37   - : '#0b55f1',
38   - }"
39   - >{{ index + 1 }}</span
40   - >
41   - <div class="flex justify-between" style="width: 100%">
42   - <div class="label-span">
43   - <Tooltip :title="item.label">
44   - {{ item.label }}
45   - </Tooltip>
46   - </div>
47   - <div class="flex w-7/10">
48   - <Progress
49   - :showInfo="false"
50   - size="small"
51   - style="width: 70%"
52   - :percent="(item.value / seriesData[0].value) * 100"
53   - :strokeWidth="12"
54   - :strokeColor="
55   - index === 0
56   - ? '#ea5b42'
57   - : index === 1
58   - ? '#666'
59   - : index === 2
60   - ? '#e4751a'
61   - : '#b5b6b6'
62   - "
63   - />
64   - <span
65   - class="ml-2"
66   - :style="{ color: index === 0 ? '#EA5B42' : index === 2 ? '#E4751A' : '#666' }"
67   - >
68   - {{ item.value }}
69   - </span>
70   - </div>
71   - </div>
72   - </DescriptionsItem>
73   - </template>
74   - </Descriptions>
75   - </Skeleton>
76   - </div>
77   -</template>
78   -
79   -<style scoped lang="less">
80   - .item-span {
81   - width: 1.4rem;
82   - height: 1.25rem;
83   - border: 1px solid;
84   - color: #0b55f1;
85   - border-radius: 50%;
86   - display: flex;
87   - align-items: center;
88   - justify-content: center;
89   - }
90   -
91   - .label-span {
92   - width: 10rem;
93   - white-space: nowrap;
94   - text-overflow: ellipsis;
95   - overflow: hidden;
96   - word-break: break-all;
97   - }
98   -</style>
... ... @@ -37,7 +37,7 @@
37 37 },
38 38 legend: {
39 39 top: 'bottom',
40   - padding: 5,
  40 + type: 'scroll',
41 41 },
42 42 title: [
43 43 {
... ...
... ... @@ -3,6 +3,7 @@
3 3 import { useECharts } from '/@/hooks/web/useECharts';
4 4 import { useAppStore } from '/@/store/modules/app';
5 5 import { useI18n } from '/@/hooks/web/useI18n';
  6 + import { Empty } from 'ant-design-vue';
6 7
7 8 const { t } = useI18n();
8 9
... ... @@ -21,10 +22,11 @@
21 22
22 23 const timeRangeList = ref([
23 24 { label: `1${t('home.index.timeUnit.hour')}`, value: 'hour', interval: 1000 * 60 * 5 },
  25 + { label: `1${t('home.index.timeUnit.day')}`, value: 'day', interval: 1000 * 60 * 60 * 1 },
24 26 {
25 27 label: `7${t('home.index.timeUnit.day')}`,
26 28 value: 'week',
27   - interval: 1000 * 60 * 60 * 2,
  29 + interval: 1000 * 60 * 60 * 1,
28 30 },
29 31 {
30 32 label: `30${t('home.index.timeUnit.day')}`,
... ... @@ -95,13 +97,17 @@
95 97 },
96 98 {
97 99 deep: true,
  100 + immediate: true,
98 101 }
99 102 );
100 103
101 104 onMounted(() => {
102 105 setOptions(getOptions());
103 106 //自适应
104   - window.addEventListener('resize', () => resize());
  107 + window.addEventListener('resize', () => {
  108 + resize();
  109 + setOptions(getOptions());
  110 + });
105 111 });
106 112
107 113 const handleTimeRangeChange = (e: any) => {
... ... @@ -122,7 +128,10 @@
122 128 </template>
123 129 </a-radio-group>
124 130 </template>
125   - <div ref="chartRef" class="w-full h-80"></div>
  131 + <div v-show="seriesData.length" ref="chartRef" class="w-full h-80"></div>
  132 + <div v-show="!seriesData.length" class="w-full h-72 flex justify-center items-center"
  133 + ><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE"
  134 + /></div>
126 135 </a-card>
127 136 </template>
128 137
... ...
... ... @@ -76,15 +76,89 @@
76 76 ?.map((topItem) => topItem.value)
77 77 ?.reduce((sum, curr) => sum + curr);
78 78 // 相加总共
79   - chartData.pieChartData.push({
80   - name: '其他应用',
81   - value: res.tops.length <= 5 ? 0 : otherApplicationCount,
82   - });
  79 + if (res.tops && res.tops.length > 5) {
  80 + chartData.pieChartData.push({
  81 + name: '其他应用',
  82 + value: otherApplicationCount,
  83 + });
  84 + }
83 85 }
84 86 };
85 87
  88 + //1小时->5分钟间隔 1天->2小时间隔 7天->1天间隔 30天->1天间隔
  89 + const timeFormat = (type, config) => {
  90 + let startT: any = null;
  91 + let endT: any = null;
  92 + let interval: any = null; //分割间隔
  93 + if (type == 'hour') {
  94 + interval = 5;
  95 + startT = moment().subtract(1, config.text);
  96 + endT = moment().format('HH:mm');
  97 + } else if (type == 'day') {
  98 + interval = 2;
  99 + startT = moment().subtract(1, config.text);
  100 + endT = moment().format('HH:mm');
  101 + } else if (type == 'week') {
  102 + interval = 1;
  103 + startT = moment().subtract(1, config.text);
  104 + endT = moment().format('HH:mm');
  105 + } else if (type == 'month') {
  106 + interval = 1;
  107 + startT = moment().subtract(1, config.text);
  108 + endT = moment().format('HH:mm');
  109 + }
  110 + let starTime = moment(startT, 'HH:mm');
  111 + let endTime = moment(endT, 'HH:mm');
  112 + let diff = endTime.diff(starTime, config.diffText);
  113 + let num = Math.ceil(diff / interval);
  114 + let times: any = [];
  115 + for (let i = 1; i <= num; i++) {
  116 + let timeFrom = starTime.clone().add((i - 1) * interval, config.timeText) as any;
  117 + times.push(timeFrom.format('YYYY-MM-DD HH:mm'));
  118 + }
  119 + return times;
  120 + };
  121 +
  122 + const configTime = [
  123 + {
  124 + name: 'hour',
  125 + value: {
  126 + text: 'hours',
  127 + diffText: 'minutes',
  128 + timeText: 'minutes',
  129 + },
  130 + },
  131 + {
  132 + name: 'day',
  133 + value: {
  134 + text: 'days',
  135 + diffText: 'hours',
  136 + timeText: 'hours',
  137 + },
  138 + },
  139 + {
  140 + name: 'week',
  141 + value: {
  142 + text: 'weeks',
  143 + diffText: 'days',
  144 + timeText: 'days',
  145 + },
  146 + },
  147 + {
  148 + name: 'month',
  149 + value: {
  150 + text: 'months',
  151 + diffText: 'days',
  152 + timeText: 'days',
  153 + },
  154 + },
  155 + ];
  156 + //代码保留
  157 +
86 158 // 接口调用历史
87 159 const getClassify = async (type?: string) => {
  160 + const findValue = configTime.find((configItem) => configItem.name === type)?.value;
  161 + timeFormat(type, findValue);
88 162 const res = (await getApplicationRecordClassify(type)) as any as ClassifyItemType[];
89 163 chartData.timeLineChartData = res?.map((classifyItem: ClassifyItemType) => ({
90 164 type: 'line',
... ... @@ -125,15 +199,9 @@
125 199 </div>
126 200 <div>
127 201 <TimeLineChart
128   - v-if="chartData.timeLineChartData.length"
129 202 @emitTimeRange="handleReceiveTimeRange"
130 203 :seriesData="chartData.timeLineChartData"
131 204 />
132   - <a-card v-else :title="t('application.record.text.timeLineTitle')" class="w-full h-120">
133   - <div class="w-full h-72 flex justify-center items-center"
134   - ><Empty :image="Empty.PRESENTED_IMAGE_SIMPLE"
135   - /></div>
136   - </a-card>
137 205 </div>
138 206 <div>
139 207 <a-card class="w-full h-140">
... ...