Showing
4 changed files
with
326 additions
and
33 deletions
src/packages/components/external/Charts/Lines/OverrideLineForDeviceHistoryQuery/helper.ts
0 → 100644
1 | +import dayjs, { Dayjs } from 'dayjs'; | |
2 | + | |
3 | +enum TimeUnit { | |
4 | + SECOND = 'second', | |
5 | + MINUTE = 'MINUTE', | |
6 | + HOUR = 'HOUR', | |
7 | + DAY = 'DAY', | |
8 | +} | |
9 | + | |
10 | +const unitMapping = { | |
11 | + [TimeUnit.SECOND]: '秒', | |
12 | + [TimeUnit.MINUTE]: '分', | |
13 | + [TimeUnit.HOUR]: '小时', | |
14 | + [TimeUnit.DAY]: '天', | |
15 | +}; | |
16 | + | |
17 | +const unitConversion = { | |
18 | + [TimeUnit.SECOND]: 1 * 1000, | |
19 | + [TimeUnit.MINUTE]: 1 * 60 * 1000, | |
20 | + [TimeUnit.HOUR]: 1 * 60 * 60 * 1000, | |
21 | + [TimeUnit.DAY]: 1 * 60 * 60 * 24 * 1000, | |
22 | +}; | |
23 | + | |
24 | +export const intervalOption = [ | |
25 | + { | |
26 | + id: 1, | |
27 | + unit: TimeUnit.SECOND, | |
28 | + linkage: [{ id: 1, unit: TimeUnit.SECOND }], | |
29 | + }, | |
30 | + { | |
31 | + id: 5, | |
32 | + unit: TimeUnit.SECOND, | |
33 | + linkage: [{ id: 1, unit: TimeUnit.SECOND }], | |
34 | + }, | |
35 | + { | |
36 | + id: 10, | |
37 | + unit: TimeUnit.SECOND, | |
38 | + linkage: [{ id: 1, unit: TimeUnit.SECOND }], | |
39 | + }, | |
40 | + { | |
41 | + id: 15, | |
42 | + unit: TimeUnit.SECOND, | |
43 | + linkage: [{ id: 1, unit: TimeUnit.SECOND }], | |
44 | + }, | |
45 | + { | |
46 | + id: 30, | |
47 | + unit: TimeUnit.SECOND, | |
48 | + linkage: [{ id: 1, unit: TimeUnit.SECOND }], | |
49 | + }, | |
50 | + { | |
51 | + id: 1, | |
52 | + unit: TimeUnit.MINUTE, | |
53 | + linkage: [ | |
54 | + { id: 1, unit: TimeUnit.SECOND }, | |
55 | + { id: 5, unit: TimeUnit.SECOND }, | |
56 | + ], | |
57 | + }, | |
58 | + { | |
59 | + id: 2, | |
60 | + unit: TimeUnit.MINUTE, | |
61 | + linkage: [ | |
62 | + { id: 1, unit: TimeUnit.SECOND }, | |
63 | + { id: 5, unit: TimeUnit.SECOND }, | |
64 | + { id: 10, unit: TimeUnit.SECOND }, | |
65 | + { id: 15, unit: TimeUnit.SECOND }, | |
66 | + ], | |
67 | + }, | |
68 | + { | |
69 | + id: 5, | |
70 | + unit: TimeUnit.MINUTE, | |
71 | + linkage: [ | |
72 | + { id: 1, unit: TimeUnit.SECOND }, | |
73 | + { id: 5, unit: TimeUnit.SECOND }, | |
74 | + { id: 10, unit: TimeUnit.SECOND }, | |
75 | + { id: 15, unit: TimeUnit.SECOND }, | |
76 | + { id: 30, unit: TimeUnit.SECOND }, | |
77 | + ], | |
78 | + }, | |
79 | + { | |
80 | + id: 10, | |
81 | + unit: TimeUnit.MINUTE, | |
82 | + linkage: [ | |
83 | + { id: 5, unit: TimeUnit.SECOND }, | |
84 | + { id: 10, unit: TimeUnit.SECOND }, | |
85 | + { id: 15, unit: TimeUnit.SECOND }, | |
86 | + { id: 30, unit: TimeUnit.SECOND }, | |
87 | + { id: 1, unit: TimeUnit.MINUTE }, | |
88 | + ], | |
89 | + }, | |
90 | + { | |
91 | + id: 15, | |
92 | + unit: TimeUnit.MINUTE, | |
93 | + linkage: [ | |
94 | + { id: 5, unit: TimeUnit.SECOND }, | |
95 | + { id: 10, unit: TimeUnit.SECOND }, | |
96 | + { id: 15, unit: TimeUnit.SECOND }, | |
97 | + { id: 30, unit: TimeUnit.SECOND }, | |
98 | + { id: 1, unit: TimeUnit.MINUTE }, | |
99 | + { id: 2, unit: TimeUnit.MINUTE }, | |
100 | + ], | |
101 | + }, | |
102 | + { | |
103 | + id: 30, | |
104 | + unit: TimeUnit.MINUTE, | |
105 | + linkage: [ | |
106 | + { id: 5, unit: TimeUnit.SECOND }, | |
107 | + { id: 10, unit: TimeUnit.SECOND }, | |
108 | + { id: 15, unit: TimeUnit.SECOND }, | |
109 | + { id: 30, unit: TimeUnit.SECOND }, | |
110 | + { id: 1, unit: TimeUnit.MINUTE }, | |
111 | + { id: 2, unit: TimeUnit.MINUTE }, | |
112 | + ], | |
113 | + }, | |
114 | + { | |
115 | + id: 1, | |
116 | + unit: TimeUnit.HOUR, | |
117 | + linkage: [ | |
118 | + { id: 10, unit: TimeUnit.SECOND }, | |
119 | + { id: 15, unit: TimeUnit.SECOND }, | |
120 | + { id: 30, unit: TimeUnit.SECOND }, | |
121 | + { id: 1, unit: TimeUnit.MINUTE }, | |
122 | + { id: 2, unit: TimeUnit.MINUTE }, | |
123 | + { id: 5, unit: TimeUnit.MINUTE }, | |
124 | + ], | |
125 | + }, | |
126 | + { | |
127 | + id: 2, | |
128 | + unit: TimeUnit.HOUR, | |
129 | + linkage: [ | |
130 | + { id: 15, unit: TimeUnit.SECOND }, | |
131 | + { id: 30, unit: TimeUnit.SECOND }, | |
132 | + { id: 1, unit: TimeUnit.MINUTE }, | |
133 | + { id: 2, unit: TimeUnit.MINUTE }, | |
134 | + { id: 5, unit: TimeUnit.MINUTE }, | |
135 | + { id: 10, unit: TimeUnit.MINUTE }, | |
136 | + { id: 15, unit: TimeUnit.MINUTE }, | |
137 | + ], | |
138 | + }, | |
139 | + { | |
140 | + id: 5, | |
141 | + unit: TimeUnit.HOUR, | |
142 | + linkage: [ | |
143 | + { id: 1, unit: TimeUnit.MINUTE }, | |
144 | + { id: 2, unit: TimeUnit.MINUTE }, | |
145 | + { id: 5, unit: TimeUnit.MINUTE }, | |
146 | + { id: 10, unit: TimeUnit.MINUTE }, | |
147 | + { id: 15, unit: TimeUnit.MINUTE }, | |
148 | + { id: 30, unit: TimeUnit.MINUTE }, | |
149 | + ], | |
150 | + }, | |
151 | + { | |
152 | + id: 10, | |
153 | + unit: TimeUnit.HOUR, | |
154 | + linkage: [ | |
155 | + { id: 2, unit: TimeUnit.MINUTE }, | |
156 | + { id: 5, unit: TimeUnit.MINUTE }, | |
157 | + { id: 10, unit: TimeUnit.MINUTE }, | |
158 | + { id: 15, unit: TimeUnit.MINUTE }, | |
159 | + { id: 30, unit: TimeUnit.MINUTE }, | |
160 | + { id: 1, unit: TimeUnit.HOUR }, | |
161 | + ], | |
162 | + }, | |
163 | + { | |
164 | + id: 12, | |
165 | + unit: TimeUnit.HOUR, | |
166 | + linkage: [ | |
167 | + { id: 2, unit: TimeUnit.MINUTE }, | |
168 | + { id: 5, unit: TimeUnit.MINUTE }, | |
169 | + { id: 10, unit: TimeUnit.MINUTE }, | |
170 | + { id: 15, unit: TimeUnit.MINUTE }, | |
171 | + { id: 30, unit: TimeUnit.MINUTE }, | |
172 | + { id: 1, unit: TimeUnit.HOUR }, | |
173 | + ], | |
174 | + }, | |
175 | + { | |
176 | + id: 1, | |
177 | + unit: TimeUnit.DAY, | |
178 | + linkage: [ | |
179 | + { id: 5, unit: TimeUnit.MINUTE }, | |
180 | + { id: 10, unit: TimeUnit.MINUTE }, | |
181 | + { id: 15, unit: TimeUnit.MINUTE }, | |
182 | + { id: 30, unit: TimeUnit.MINUTE }, | |
183 | + { id: 1, unit: TimeUnit.HOUR }, | |
184 | + { id: 2, unit: TimeUnit.HOUR }, | |
185 | + ], | |
186 | + }, | |
187 | + { | |
188 | + id: 7, | |
189 | + unit: TimeUnit.DAY, | |
190 | + linkage: [ | |
191 | + { id: 30, unit: TimeUnit.MINUTE }, | |
192 | + { id: 1, unit: TimeUnit.HOUR }, | |
193 | + { id: 2, unit: TimeUnit.HOUR }, | |
194 | + { id: 5, unit: TimeUnit.HOUR }, | |
195 | + { id: 10, unit: TimeUnit.HOUR }, | |
196 | + { id: 12, unit: TimeUnit.HOUR }, | |
197 | + { id: 1, unit: TimeUnit.DAY }, | |
198 | + ], | |
199 | + }, | |
200 | + { | |
201 | + id: 30, | |
202 | + unit: TimeUnit.DAY, | |
203 | + linkage: [ | |
204 | + { id: 2, unit: TimeUnit.HOUR }, | |
205 | + { id: 5, unit: TimeUnit.HOUR }, | |
206 | + { id: 10, unit: TimeUnit.HOUR }, | |
207 | + { id: 12, unit: TimeUnit.HOUR }, | |
208 | + { id: 1, unit: TimeUnit.DAY }, | |
209 | + ], | |
210 | + }, | |
211 | +].map((item) => { | |
212 | + return { | |
213 | + value: item.id * unitConversion[item.unit], | |
214 | + label: item.id + unitMapping[item.unit], | |
215 | + linkage: item.linkage.map((item) => { | |
216 | + return { | |
217 | + value: item.id * unitConversion[item.unit], | |
218 | + label: item.id + unitMapping[item.unit], | |
219 | + }; | |
220 | + }), | |
221 | + }; | |
222 | +}); | |
223 | + | |
224 | +const rangeIntervalOption = [ | |
225 | + { | |
226 | + id: 90, | |
227 | + unit: TimeUnit.DAY, | |
228 | + linkage: [ | |
229 | + { id: 5, unit: TimeUnit.HOUR }, | |
230 | + { id: 10, unit: TimeUnit.HOUR }, | |
231 | + { id: 12, unit: TimeUnit.HOUR }, | |
232 | + { id: 1, unit: TimeUnit.DAY }, | |
233 | + { id: 7, unit: TimeUnit.DAY }, | |
234 | + ], | |
235 | + }, | |
236 | + { | |
237 | + id: 180, | |
238 | + unit: TimeUnit.DAY, | |
239 | + linkage: [ | |
240 | + { id: 10, unit: TimeUnit.HOUR }, | |
241 | + { id: 12, unit: TimeUnit.HOUR }, | |
242 | + { id: 1, unit: TimeUnit.DAY }, | |
243 | + { id: 7, unit: TimeUnit.DAY }, | |
244 | + ], | |
245 | + }, | |
246 | + { | |
247 | + id: 360, | |
248 | + unit: TimeUnit.DAY, | |
249 | + linkage: [ | |
250 | + { id: 1, unit: TimeUnit.DAY }, | |
251 | + { id: 7, unit: TimeUnit.DAY }, | |
252 | + { id: 30, unit: TimeUnit.DAY }, | |
253 | + ], | |
254 | + }, | |
255 | +].map((item) => { | |
256 | + return { | |
257 | + value: item.id * unitConversion[item.unit], | |
258 | + label: item.id + unitMapping[item.unit], | |
259 | + linkage: item.linkage.map((item) => { | |
260 | + return { | |
261 | + value: item.id * unitConversion[item.unit], | |
262 | + label: item.id + unitMapping[item.unit], | |
263 | + }; | |
264 | + }), | |
265 | + }; | |
266 | +}); | |
267 | + | |
268 | +/** | |
269 | + * @description | |
270 | + * @param {number} value | |
271 | + * @returns | |
272 | + */ | |
273 | +export function getPacketIntervalByValue(value: number) { | |
274 | + return intervalOption.find((item) => item.value === value)?.linkage || []; | |
275 | +} | |
276 | + | |
277 | +export function getPacketIntervalByRange( | |
278 | + [start, end] = [null, null] as [Nullable<Dayjs>, Nullable<Dayjs>] | |
279 | +) { | |
280 | + start = typeof start === 'number' ? dayjs(start) : start | |
281 | + end = typeof end === 'number' ? dayjs(end) : end | |
282 | + | |
283 | + if (start && end) { | |
284 | + const value = end.diff(start, 'ms'); | |
285 | + let options: { value: number; label: string }[] = []; | |
286 | + for (const item of [...intervalOption, ...rangeIntervalOption]) { | |
287 | + if (item.value <= value) continue; | |
288 | + if (item.value >= value) { | |
289 | + options = item.linkage; | |
290 | + break; | |
291 | + } | |
292 | + } | |
293 | + return options; | |
294 | + } | |
295 | + return []; | |
296 | +} | ... | ... |
1 | 1 | <template> |
2 | 2 | <div> |
3 | 3 | <n-space vertical> |
4 | - <n-space> | |
5 | - <n-date-picker | |
6 | - size="small" | |
7 | - :to="true" | |
8 | - clearable | |
9 | - v-model:value="queryCondition.timeRange" | |
10 | - type="datetimerange" | |
11 | - :shortcuts="rangeShortcuts" | |
12 | - /> | |
13 | - <n-select :style="`width:160px`" v-model:value="queryCondition.agg" :options="aggOptions" clearable /> | |
14 | - <n-input-number | |
15 | - :min="7" | |
16 | - :max="50000" | |
17 | - :style="`width:160px`" | |
18 | - v-if="queryCondition.agg === 'NONE'" | |
19 | - v-model:value="queryCondition.limit" | |
20 | - clearable | |
21 | - /> | |
22 | - </n-space> | |
4 | + <div class="form"> | |
5 | + <n-date-picker size="small" :to="true" clearable v-model:value="queryCondition.timeRange" type="datetimerange" | |
6 | + :shortcuts="rangeShortcuts" format="yyyy-MM-dd" @change="queryCondition.interval = null" /> | |
7 | + <n-select v-model:value="queryCondition.agg" size="small" :options="aggOptions" clearable | |
8 | + @change="handleAggChange" /> | |
9 | + <n-input-number :min="7" :max="50000" size="small" v-if="queryCondition.agg === 'NONE'" | |
10 | + v-model:value="queryCondition.limit" clearable /> | |
11 | + <n-select v-if="queryCondition.agg !== 'NONE'" size="small" v-model:value="queryCondition.interval" | |
12 | + :options="getPacketIntervalByRange(queryCondition.timeRange)" /> | |
13 | + </div> | |
23 | 14 | </n-space> |
24 | - <v-chart | |
25 | - ref="vChartRef" | |
26 | - :init-options="initOptions" | |
27 | - :theme="themeColor" | |
28 | - :option="option" | |
29 | - :manual-update="isPreview()" | |
15 | + <v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()" | |
30 | 16 | :update-options="{ |
31 | 17 | replaceMerge: replaceMergeArr |
32 | - }" | |
33 | - autoresize | |
34 | - @mouseover="handleHighlight" | |
35 | - @mouseout="handleDownplay" | |
36 | - > | |
18 | + }" autoresize @mouseover="handleHighlight" @mouseout="handleDownplay"> | |
37 | 19 | </v-chart> |
38 | 20 | </div> |
39 | 21 | </template> |
... | ... | @@ -58,6 +40,7 @@ import { useFullScreen } from '../../utls/fullScreen' |
58 | 40 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' |
59 | 41 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' |
60 | 42 | import { useChartInteract } from '@/hooks/external/useChartSelectDeviceInteract.hook' |
43 | +import { getPacketIntervalByRange } from './helper' | |
61 | 44 | |
62 | 45 | const props = defineProps({ |
63 | 46 | themeSetting: { |
... | ... | @@ -273,6 +256,10 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (n |
273 | 256 | updateVChart(newData) |
274 | 257 | }) |
275 | 258 | |
259 | +const handleAggChange = (value: string) => { | |
260 | + if (value === 'NONE') queryCondition.value.interval = null | |
261 | +} | |
262 | + | |
276 | 263 | onMounted(() => { |
277 | 264 | seriesDataMaxLength = dataJson.source.length |
278 | 265 | if (props.chartConfig.option.isCarousel) { |
... | ... | @@ -287,7 +274,8 @@ watch( |
287 | 274 | startTs: newValue.timeRange.at(-2), |
288 | 275 | endTs: newValue.timeRange.at(-1), |
289 | 276 | limit: newValue.limit, |
290 | - agg: newValue.agg | |
277 | + agg: newValue.agg, | |
278 | + interval: newValue.interval | |
291 | 279 | } |
292 | 280 | if (newValue.agg !== 'NONE') { |
293 | 281 | Reflect.deleteProperty(obj, 'limit') |
... | ... | @@ -304,4 +292,13 @@ const onChange = (v: object) => { |
304 | 292 | // 存储到联动数据 |
305 | 293 | useChartInteract(props.chartConfig, useChartEditStore, { data: v }) |
306 | 294 | } |
295 | + | |
307 | 296 | </script> |
297 | + | |
298 | +<style lang="scss" scoped> | |
299 | +.form { | |
300 | + display: grid; | |
301 | + grid-template-columns: 2fr 1fr 1fr; | |
302 | + gap: 8px; | |
303 | +} | |
304 | +</style> | ... | ... |