st-comp 0.0.133 → 0.0.135
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/KlineBasic.cjs +1 -1
- package/es/KlineBasic.js +707 -640
- package/es/style.css +1 -1
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +194 -194
- package/lib/{index-53e2cd6c.js → index-4f204e72.js} +20341 -20274
- package/lib/{python-cb6db8ac.js → python-4729ac83.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/KlineBasic/index.vue +284 -153
- package/packages/KlineBasic/utils.js +39 -20
- package/src/pages/KlineBasic/api.js +1 -1
- package/src/pages/KlineBasic/index.vue +1 -0
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="klineBasic">
|
|
3
3
|
<div class="klineBasic-tips">
|
|
4
|
-
<KlineTips
|
|
4
|
+
<KlineTips
|
|
5
|
+
:data="chartData"
|
|
6
|
+
:activeIndex="activeIndex"
|
|
7
|
+
/>
|
|
5
8
|
</div>
|
|
6
9
|
<div
|
|
7
10
|
class="klineBasic-main"
|
|
8
11
|
:style="{ height: config.showSubChart ? '70%' : '100%' }"
|
|
9
12
|
>
|
|
10
13
|
<Contextmenu @closeContextMenuCallBack="closeContextMenuCallBack">
|
|
11
|
-
<div
|
|
14
|
+
<div
|
|
15
|
+
ref="klineBasicMainRef"
|
|
16
|
+
style="height: 100%"
|
|
17
|
+
></div>
|
|
12
18
|
<template #popover>
|
|
13
19
|
<el-menu
|
|
14
20
|
:style="{
|
|
@@ -31,7 +37,10 @@
|
|
|
31
37
|
</template>
|
|
32
38
|
</Contextmenu>
|
|
33
39
|
</div>
|
|
34
|
-
<div
|
|
40
|
+
<div
|
|
41
|
+
class="klineBasic-sub"
|
|
42
|
+
v-if="config.showSubChart"
|
|
43
|
+
>
|
|
35
44
|
<KlineSub
|
|
36
45
|
ref="klineSubRef"
|
|
37
46
|
v-model="subIndicator"
|
|
@@ -40,17 +49,21 @@
|
|
|
40
49
|
:subIndicatorList="indicatorStore?.subIndicatorList"
|
|
41
50
|
/>
|
|
42
51
|
</div>
|
|
43
|
-
<div
|
|
52
|
+
<div
|
|
53
|
+
class="klineBasic-empty"
|
|
54
|
+
v-if="isEmpty"
|
|
55
|
+
>
|
|
44
56
|
<el-empty
|
|
45
57
|
class="klineBasic-empty-content"
|
|
46
58
|
description="暂无数据"
|
|
47
59
|
/>
|
|
48
60
|
</div>
|
|
49
|
-
<div
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
<div
|
|
61
|
+
<div
|
|
62
|
+
class="klineBasic-error"
|
|
63
|
+
v-if="isError"
|
|
64
|
+
>
|
|
65
|
+
<div class="klineBasic-error-content">加载失败,请刷新重试</div>
|
|
66
|
+
<div style="text-align: center">
|
|
54
67
|
<el-button @click="getMainData">刷新</el-button>
|
|
55
68
|
</div>
|
|
56
69
|
</div>
|
|
@@ -81,57 +94,57 @@
|
|
|
81
94
|
</template>
|
|
82
95
|
|
|
83
96
|
<script setup>
|
|
84
|
-
import { onMounted, onUnmounted, ref, watch, computed } from "vue"
|
|
85
|
-
import * as echarts from "echarts"
|
|
86
|
-
import dayjs from "dayjs"
|
|
87
|
-
import { initRequestByEnv, getKlineBasic, getKline, getWarningLine, addWarningLine, updateWarningLine, deleteWarningLine } from
|
|
88
|
-
import { addResizeListener } from
|
|
89
|
-
import { getMainOptions, getWarningLineOptions } from
|
|
90
|
-
import KlineTips from
|
|
91
|
-
import KlineSub from
|
|
92
|
-
import Contextmenu from
|
|
97
|
+
import { onMounted, onUnmounted, ref, watch, computed } from "vue";
|
|
98
|
+
import * as echarts from "echarts";
|
|
99
|
+
import dayjs from "dayjs";
|
|
100
|
+
import { initRequestByEnv, getKlineBasic, getKline, getWarningLine, addWarningLine, updateWarningLine, deleteWarningLine } from "./api";
|
|
101
|
+
import { addResizeListener } from "st-func";
|
|
102
|
+
import { getMainOptions, getWarningLineOptions } from "./utils";
|
|
103
|
+
import KlineTips from "./components/KlineTips/index.vue";
|
|
104
|
+
import KlineSub from "./components/KlineSub/index.vue";
|
|
105
|
+
import Contextmenu from "./components/Contextmenu/index.vue";
|
|
93
106
|
|
|
94
|
-
const defaultMenuData = [{ label: "画线预警", key: "drawWarningLine" }]
|
|
107
|
+
const defaultMenuData = [{ label: "画线预警", key: "drawWarningLine" }];
|
|
95
108
|
|
|
96
109
|
let resizeRo = null; // dom元素监听事件
|
|
97
|
-
let mainChartIns = null // 主图实例
|
|
110
|
+
let mainChartIns = null; // 主图实例
|
|
98
111
|
|
|
99
|
-
let highlightTimer // 高亮事件定时器
|
|
100
|
-
let mainDataZoomTimer // datazoom事件定时器
|
|
112
|
+
let highlightTimer; // 高亮事件定时器
|
|
113
|
+
let mainDataZoomTimer; // datazoom事件定时器
|
|
101
114
|
|
|
102
115
|
let isLoadHistory = false; // 是否正在加载历史数据
|
|
103
116
|
let isloadAllHistory = false; // 是否加载完全部历史数据
|
|
104
117
|
|
|
105
|
-
const emit = defineEmits([
|
|
118
|
+
const emit = defineEmits(["change", "getFactorData"]);
|
|
106
119
|
|
|
107
120
|
const props = defineProps({
|
|
108
121
|
variety: {
|
|
109
122
|
type: [String, Number],
|
|
110
|
-
default: () => null
|
|
123
|
+
default: () => null,
|
|
111
124
|
}, // 品种代码
|
|
112
125
|
varietyName: {
|
|
113
126
|
type: [String, Number],
|
|
114
|
-
default: () => null
|
|
127
|
+
default: () => null,
|
|
115
128
|
}, // 品种名称
|
|
116
129
|
featureId: {
|
|
117
130
|
type: [String, Number],
|
|
118
|
-
default: () => null
|
|
131
|
+
default: () => null,
|
|
119
132
|
}, // 合约id
|
|
120
133
|
featureType: {
|
|
121
134
|
type: [String, Number],
|
|
122
|
-
default: () => null
|
|
135
|
+
default: () => null,
|
|
123
136
|
}, // 合约类型
|
|
124
137
|
cycle: {
|
|
125
138
|
type: [String, Number],
|
|
126
|
-
default: () => null
|
|
139
|
+
default: () => null,
|
|
127
140
|
}, // 周期id
|
|
128
141
|
mainIndicator: {
|
|
129
142
|
type: String,
|
|
130
|
-
default: () =>
|
|
143
|
+
default: () => "",
|
|
131
144
|
}, // 主图指标名称
|
|
132
145
|
indicatorStore: {
|
|
133
146
|
type: Object,
|
|
134
|
-
default: () => null
|
|
147
|
+
default: () => null,
|
|
135
148
|
}, // 指标配置Store
|
|
136
149
|
startTime: {
|
|
137
150
|
type: String,
|
|
@@ -147,30 +160,34 @@ const props = defineProps({
|
|
|
147
160
|
}, // 复权方式,前复权-1,不复权-0
|
|
148
161
|
config: {
|
|
149
162
|
type: Object,
|
|
150
|
-
default: () => ({})
|
|
163
|
+
default: () => ({}),
|
|
151
164
|
}, // 配置
|
|
152
165
|
env: {
|
|
153
166
|
type: Object,
|
|
154
|
-
default: () => ({})
|
|
167
|
+
default: () => ({}),
|
|
155
168
|
}, // 环境变量
|
|
156
|
-
|
|
169
|
+
brushRange: {
|
|
170
|
+
type: [Array, null],
|
|
171
|
+
default: () => null,
|
|
172
|
+
}, // 时段框选
|
|
173
|
+
});
|
|
157
174
|
|
|
158
|
-
const isEmpty = ref(false) // 是否无数据
|
|
159
|
-
const isError = ref(false) // 是否异常
|
|
175
|
+
const isEmpty = ref(false); // 是否无数据
|
|
176
|
+
const isError = ref(false); // 是否异常
|
|
160
177
|
|
|
161
|
-
const klineBasicMainRef = ref(null) // 主图Dom元素
|
|
162
|
-
const klineSubRef = ref(null) // 副图组件元素
|
|
163
|
-
const subIndicator = ref(
|
|
164
|
-
const activeIndex = ref(0) // 当前选中的k线
|
|
178
|
+
const klineBasicMainRef = ref(null); // 主图Dom元素
|
|
179
|
+
const klineSubRef = ref(null); // 副图组件元素
|
|
180
|
+
const subIndicator = ref("VOL"); // 副图指标
|
|
181
|
+
const activeIndex = ref(0); // 当前选中的k线
|
|
165
182
|
|
|
166
|
-
const chartData = ref({}) // 图表数据
|
|
183
|
+
const chartData = ref({}); // 图表数据
|
|
167
184
|
|
|
168
|
-
const warningLineData = ref([]) // 预警线数据
|
|
185
|
+
const warningLineData = ref([]); // 预警线数据
|
|
169
186
|
const warningItem = ref({}); // 右键点击的预警线
|
|
170
187
|
const warningLineChangeVisible = ref(false); // 修改预警线价格弹窗visible
|
|
171
|
-
const warningLineChangeValue = ref(
|
|
188
|
+
const warningLineChangeValue = ref(""); // 修改预警线价格弹窗value
|
|
172
189
|
|
|
173
|
-
const menuData = ref([
|
|
190
|
+
const menuData = ref([...defaultMenuData]); // 右键菜单
|
|
174
191
|
|
|
175
192
|
const config = computed(() => {
|
|
176
193
|
return {
|
|
@@ -185,48 +202,45 @@ const config = computed(() => {
|
|
|
185
202
|
showWarningLine: true, // 是否展示预警线
|
|
186
203
|
getFactorData: true, // 是否获取因子数据
|
|
187
204
|
...props.config,
|
|
188
|
-
}
|
|
189
|
-
})
|
|
205
|
+
};
|
|
206
|
+
});
|
|
190
207
|
|
|
191
208
|
watch(
|
|
192
|
-
() => [
|
|
193
|
-
props.variety, props.cycle, props.mainIndicator, subIndicator.value,
|
|
194
|
-
props.indicatorStore?.filterIndicator, props.indicatorStore?.customIndicator
|
|
195
|
-
],
|
|
209
|
+
() => [props.variety, props.cycle, props.mainIndicator, subIndicator.value, props.indicatorStore?.filterIndicator, props.indicatorStore?.customIndicator],
|
|
196
210
|
() => {
|
|
197
|
-
getMainData()
|
|
211
|
+
getMainData();
|
|
198
212
|
},
|
|
199
213
|
{ deep: true }
|
|
200
|
-
)
|
|
214
|
+
);
|
|
201
215
|
|
|
202
216
|
onMounted(() => {
|
|
203
|
-
initRequestByEnv(props.env)
|
|
204
|
-
getMainData()
|
|
205
|
-
})
|
|
217
|
+
initRequestByEnv(props.env);
|
|
218
|
+
getMainData();
|
|
219
|
+
});
|
|
206
220
|
|
|
207
221
|
onUnmounted(() => {
|
|
208
|
-
mainChartIns?.off("datazoom")
|
|
209
|
-
mainChartIns?.off("highlight")
|
|
210
|
-
mainChartIns?.off("globalout")
|
|
211
|
-
mainChartIns?.dispose()
|
|
212
|
-
resizeRo?.dispose()
|
|
213
|
-
})
|
|
222
|
+
mainChartIns?.off("datazoom");
|
|
223
|
+
mainChartIns?.off("highlight");
|
|
224
|
+
mainChartIns?.off("globalout");
|
|
225
|
+
mainChartIns?.dispose();
|
|
226
|
+
resizeRo?.dispose();
|
|
227
|
+
});
|
|
214
228
|
|
|
215
229
|
// 初始化图表
|
|
216
230
|
const initChart = () => {
|
|
217
|
-
if (mainChartIns) return
|
|
218
|
-
mainChartIns = echarts.init(klineBasicMainRef.value)
|
|
219
|
-
addEventListener()
|
|
231
|
+
if (mainChartIns) return;
|
|
232
|
+
mainChartIns = echarts.init(klineBasicMainRef.value);
|
|
233
|
+
addEventListener();
|
|
220
234
|
if (config.value.showSubChart) {
|
|
221
|
-
klineSubRef.value.connect(mainChartIns)
|
|
235
|
+
klineSubRef.value.connect(mainChartIns);
|
|
222
236
|
}
|
|
223
|
-
resizeRo = addResizeListener(klineBasicMainRef.value)
|
|
237
|
+
resizeRo = addResizeListener(klineBasicMainRef.value);
|
|
224
238
|
resizeRo.listen(() => {
|
|
225
239
|
requestAnimationFrame(() => {
|
|
226
|
-
mainChartIns.resize()
|
|
227
|
-
})
|
|
228
|
-
})
|
|
229
|
-
}
|
|
240
|
+
mainChartIns.resize();
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
};
|
|
230
244
|
// 图表事件
|
|
231
245
|
const addEventListener = () => {
|
|
232
246
|
// datazoom事件
|
|
@@ -240,9 +254,9 @@ const addEventListener = () => {
|
|
|
240
254
|
if (startValue < loadCheckCounts && isLoadHistory === false && isloadAllHistory === false) {
|
|
241
255
|
// 左侧数据小于检测条数,加载左侧数据
|
|
242
256
|
isLoadHistory = true;
|
|
243
|
-
getMoreData(
|
|
257
|
+
getMoreData("history");
|
|
244
258
|
}
|
|
245
|
-
drawLine()
|
|
259
|
+
drawLine();
|
|
246
260
|
}
|
|
247
261
|
clearTimeout(mainDataZoomTimer);
|
|
248
262
|
}, 100);
|
|
@@ -283,11 +297,9 @@ const addEventListener = () => {
|
|
|
283
297
|
|
|
284
298
|
const getMainData = async () => {
|
|
285
299
|
try {
|
|
286
|
-
if (!props.variety || !props.cycle) return
|
|
287
|
-
const {
|
|
288
|
-
|
|
289
|
-
} = props
|
|
290
|
-
const { defaultShowCounts, addCounts, showWarningLine, getFactorData } = config.value
|
|
300
|
+
if (!props.variety || !props.cycle) return;
|
|
301
|
+
const { variety, featureId, cycle, indicatorStore, mainIndicator, right, startTime, endTime } = props;
|
|
302
|
+
const { defaultShowCounts, addCounts, showWarningLine, getFactorData } = config.value;
|
|
291
303
|
const params = {
|
|
292
304
|
variety,
|
|
293
305
|
featureId,
|
|
@@ -297,53 +309,53 @@ const getMainData = async () => {
|
|
|
297
309
|
right,
|
|
298
310
|
showWarningLine,
|
|
299
311
|
getFactorData,
|
|
300
|
-
}
|
|
312
|
+
};
|
|
301
313
|
if (startTime && endTime) {
|
|
302
314
|
// 开始时间+结束时间
|
|
303
|
-
params.startTime = startTime
|
|
304
|
-
params.endTime = endTime
|
|
315
|
+
params.startTime = startTime;
|
|
316
|
+
params.endTime = endTime;
|
|
305
317
|
} else if (startTime) {
|
|
306
318
|
// 开始时间
|
|
307
|
-
params.startTime = startTime
|
|
308
|
-
params.limit = defaultShowCounts + addCounts
|
|
319
|
+
params.startTime = startTime;
|
|
320
|
+
params.limit = defaultShowCounts + addCounts;
|
|
309
321
|
} else if (endTime) {
|
|
310
322
|
// 结束时间
|
|
311
|
-
params.endTime = endTime
|
|
312
|
-
params.limit = defaultShowCounts + addCounts
|
|
323
|
+
params.endTime = endTime;
|
|
324
|
+
params.limit = defaultShowCounts + addCounts;
|
|
313
325
|
} else {
|
|
314
326
|
// 未传入时间,使用最新时间作为结束时间请求数据
|
|
315
|
-
params.endTime = dayjs().add(1, "hour").format(
|
|
316
|
-
params.limit = defaultShowCounts + addCounts
|
|
327
|
+
params.endTime = dayjs().add(1, "hour").format("YYYY-MM-DD HH:mm:ss");
|
|
328
|
+
params.limit = defaultShowCounts + addCounts;
|
|
317
329
|
}
|
|
318
|
-
const res = await getKlineBasic(params)
|
|
330
|
+
const res = await getKlineBasic(params);
|
|
319
331
|
if (!res?.body?.kline?.time?.length) {
|
|
320
332
|
isEmpty.value = true;
|
|
321
333
|
isError.value = false;
|
|
322
|
-
return
|
|
334
|
+
return;
|
|
323
335
|
} else {
|
|
324
336
|
isEmpty.value = false;
|
|
325
337
|
isError.value = false;
|
|
326
338
|
}
|
|
327
|
-
chartData.value = res?.body?.kline
|
|
328
|
-
warningLineData.value = res?.body?.warningLine || []
|
|
329
|
-
draw()
|
|
330
|
-
drawLine()
|
|
339
|
+
chartData.value = res?.body?.kline;
|
|
340
|
+
warningLineData.value = res?.body?.warningLine || [];
|
|
341
|
+
draw();
|
|
342
|
+
drawLine();
|
|
331
343
|
if (getFactorData) {
|
|
332
|
-
emit(
|
|
344
|
+
emit("getFactorData", res?.body?.factor);
|
|
333
345
|
}
|
|
334
|
-
} catch(err) {
|
|
346
|
+
} catch (err) {
|
|
335
347
|
isError.value = true;
|
|
336
348
|
isEmpty.value = false;
|
|
337
|
-
throw new Error(err)
|
|
349
|
+
throw new Error(err);
|
|
338
350
|
}
|
|
339
|
-
}
|
|
351
|
+
};
|
|
340
352
|
|
|
341
353
|
// 加载历史/未来数据
|
|
342
354
|
const getMoreData = async (type) => {
|
|
343
|
-
const { variety, cycle, indicatorStore, mainIndicator, right } = props
|
|
344
|
-
const { addCounts } = config.value
|
|
345
|
-
const { time } = chartData.value
|
|
346
|
-
if (type ===
|
|
355
|
+
const { variety, cycle, indicatorStore, mainIndicator, right } = props;
|
|
356
|
+
const { addCounts } = config.value;
|
|
357
|
+
const { time } = chartData.value;
|
|
358
|
+
if (type === "history") {
|
|
347
359
|
// 加载历史数据
|
|
348
360
|
const res = await getKline({
|
|
349
361
|
variety,
|
|
@@ -353,26 +365,26 @@ const getMoreData = async (type) => {
|
|
|
353
365
|
mainIndicatorList: indicatorStore.getIndicatorParams(mainIndicator),
|
|
354
366
|
subIndicator: subIndicator.value,
|
|
355
367
|
right,
|
|
356
|
-
})
|
|
368
|
+
});
|
|
357
369
|
// 合并数据
|
|
358
370
|
chartData.value = {
|
|
359
|
-
time: [
|
|
360
|
-
data: [
|
|
371
|
+
time: [...res.body.time, ...chartData.value.time.slice(1)],
|
|
372
|
+
data: [...res.body.data, ...chartData.value.data.slice(1)],
|
|
361
373
|
mainIndicator: chartData.value.mainIndicator.map((item, index) => {
|
|
362
374
|
return {
|
|
363
375
|
...item,
|
|
364
|
-
data: [
|
|
365
|
-
}
|
|
376
|
+
data: [...res.body.mainIndicator[index].data, ...item.data.slice(1)],
|
|
377
|
+
};
|
|
366
378
|
}),
|
|
367
379
|
subIndicator: chartData.value.subIndicator.map((item, index) => {
|
|
368
380
|
return {
|
|
369
381
|
...item,
|
|
370
|
-
data: [
|
|
371
|
-
}
|
|
382
|
+
data: [...res.body.subIndicator[index].data, ...item.data.slice(1)],
|
|
383
|
+
};
|
|
372
384
|
}),
|
|
373
|
-
}
|
|
385
|
+
};
|
|
374
386
|
// 绘制
|
|
375
|
-
draw(true)
|
|
387
|
+
draw(true);
|
|
376
388
|
// 判断是否加载完全部数据
|
|
377
389
|
if (res.body.data.length < addCounts) {
|
|
378
390
|
isloadAllHistory = true;
|
|
@@ -381,34 +393,88 @@ const getMoreData = async (type) => {
|
|
|
381
393
|
} else {
|
|
382
394
|
// 加载未来数据
|
|
383
395
|
}
|
|
384
|
-
}
|
|
396
|
+
};
|
|
385
397
|
|
|
386
398
|
const draw = (keepDataZoom = false) => {
|
|
387
|
-
initChart()
|
|
388
|
-
const { time } = chartData.value
|
|
389
|
-
const { gridRight, gridLeft, defaultShowCounts, maxShowCounts, showSubChart } = config.value
|
|
390
|
-
let startValue = time.length - 1 - defaultShowCounts
|
|
391
|
-
let endValue = time.length - 1
|
|
399
|
+
initChart();
|
|
400
|
+
const { time } = chartData.value;
|
|
401
|
+
const { gridRight, gridLeft, defaultShowCounts, maxShowCounts, showSubChart } = config.value;
|
|
402
|
+
let startValue = time.length - 1 - defaultShowCounts;
|
|
403
|
+
let endValue = time.length - 1;
|
|
392
404
|
// 保持缩放位置
|
|
393
405
|
if (keepDataZoom) {
|
|
394
|
-
const originOption = mainChartIns.getOption()
|
|
395
|
-
const originTime = originOption?.xAxis?.[0]?.data
|
|
396
|
-
const originDataZoom = originOption?.dataZoom?.[0]
|
|
397
|
-
const originStartTime = originTime[originDataZoom?.startValue]
|
|
398
|
-
const originEndTime = originTime[originDataZoom?.endValue]
|
|
399
|
-
startValue = time.findIndex((item) => item === originStartTime)
|
|
400
|
-
endValue = time.findIndex((item) => item === originEndTime)
|
|
406
|
+
const originOption = mainChartIns.getOption();
|
|
407
|
+
const originTime = originOption?.xAxis?.[0]?.data;
|
|
408
|
+
const originDataZoom = originOption?.dataZoom?.[0];
|
|
409
|
+
const originStartTime = originTime[originDataZoom?.startValue];
|
|
410
|
+
const originEndTime = originTime[originDataZoom?.endValue];
|
|
411
|
+
startValue = time.findIndex((item) => item === originStartTime);
|
|
412
|
+
endValue = time.findIndex((item) => item === originEndTime);
|
|
413
|
+
}
|
|
414
|
+
const options = getMainOptions(chartData.value, config.value, startValue, endValue);
|
|
415
|
+
mainChartIns.setOption(options, true);
|
|
416
|
+
activeIndex.value = endValue;
|
|
417
|
+
// 如果传入了刷选时间段
|
|
418
|
+
if (props.brushRange) {
|
|
419
|
+
let brushStartTime = null;
|
|
420
|
+
let brushEndTime = null;
|
|
421
|
+
switch (props.cycle) {
|
|
422
|
+
// 日
|
|
423
|
+
case "6": {
|
|
424
|
+
brushStartTime = time.find((item) => {
|
|
425
|
+
return new Date(item).getTime() >= new Date(props.brushRange[0]).getTime() || dayjs(item).format("YYYY-MM-DD") === dayjs(props.brushRange[0]).format("YYYY-MM-DD");
|
|
426
|
+
});
|
|
427
|
+
brushEndTime = time.findLast((item) => {
|
|
428
|
+
return new Date(item).getTime() <= new Date(props.brushRange[1]).getTime() || dayjs(item).format("YYYY-MM-DD") === dayjs(props.brushRange[1]).format("YYYY-MM-DD");
|
|
429
|
+
});
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
// 周
|
|
433
|
+
case "7": {
|
|
434
|
+
brushStartTime = time.find((item) => {
|
|
435
|
+
return dayjs(item).day(5).format("YYYY-MM-DD") === dayjs(props.brushRange[0]).day(5).format("YYYY-MM-DD");
|
|
436
|
+
});
|
|
437
|
+
brushEndTime = time.findLast((item) => {
|
|
438
|
+
return dayjs(item).day(5).format("YYYY-MM-DD") === dayjs(props.brushRange[1]).day(5).format("YYYY-MM-DD");
|
|
439
|
+
});
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
// 月
|
|
443
|
+
case "8": {
|
|
444
|
+
brushStartTime = time.find((item) => {
|
|
445
|
+
return dayjs(item).endOf("month").format("YYYY-MM-DD") === dayjs(props.brushRange[0]).endOf("month").format("YYYY-MM-DD");
|
|
446
|
+
});
|
|
447
|
+
brushEndTime = time.findLast((item) => {
|
|
448
|
+
return dayjs(item).endOf("month").format("YYYY-MM-DD") === dayjs(props.brushRange[1]).endOf("month").format("YYYY-MM-DD");
|
|
449
|
+
});
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
default: {
|
|
453
|
+
brushStartTime = time.find((item) => {
|
|
454
|
+
return new Date(item).getTime() >= new Date(props.brushRange[0]).getTime();
|
|
455
|
+
});
|
|
456
|
+
brushEndTime = time.findLast((item) => {
|
|
457
|
+
return new Date(item).getTime() <= new Date(props.brushRange[1]).getTime();
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
console.log(brushStartTime, brushEndTime);
|
|
462
|
+
mainChartIns.dispatchAction({
|
|
463
|
+
type: "brush",
|
|
464
|
+
areas: [
|
|
465
|
+
{
|
|
466
|
+
brushType: "lineX",
|
|
467
|
+
coordRange: [brushStartTime, brushEndTime],
|
|
468
|
+
xAxisIndex: 0,
|
|
469
|
+
},
|
|
470
|
+
],
|
|
471
|
+
});
|
|
401
472
|
}
|
|
402
|
-
const options = getMainOptions(chartData.value, config.value, startValue, endValue)
|
|
403
|
-
mainChartIns.setOption(options, true)
|
|
404
|
-
activeIndex.value = endValue
|
|
405
473
|
if (showSubChart) {
|
|
406
|
-
klineSubRef.value.draw(
|
|
407
|
-
{ startValue, endValue, maxValueSpan: maxShowCounts },
|
|
408
|
-
{ gridLeft, gridRight }
|
|
409
|
-
)
|
|
474
|
+
klineSubRef.value.draw({ startValue, endValue, maxValueSpan: maxShowCounts }, { gridLeft, gridRight });
|
|
410
475
|
}
|
|
411
|
-
|
|
476
|
+
drawBrush();
|
|
477
|
+
};
|
|
412
478
|
|
|
413
479
|
// 绘制线
|
|
414
480
|
const drawLine = () => {
|
|
@@ -420,25 +486,90 @@ const drawLine = () => {
|
|
|
420
486
|
...mainChartOption,
|
|
421
487
|
graphic: [
|
|
422
488
|
...getWarningLineOptions(mainChartIns, warningLineData.value, props, config.value, () => {
|
|
423
|
-
updateWarningLineAndDraw()
|
|
424
|
-
})
|
|
489
|
+
updateWarningLineAndDraw();
|
|
490
|
+
}),
|
|
425
491
|
],
|
|
426
492
|
},
|
|
427
493
|
true
|
|
428
494
|
);
|
|
429
|
-
|
|
495
|
+
drawBrush();
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
// 区域框选
|
|
499
|
+
const drawBrush = () => {
|
|
500
|
+
const { time } = chartData.value;
|
|
501
|
+
// 如果传入了刷选时间段
|
|
502
|
+
if (props.brushRange && time?.length) {
|
|
503
|
+
// 传入时段的始末时间
|
|
504
|
+
let startTime = dayjs(props.brushRange[0]).format("YYYY-MM-DD 00:00:00");
|
|
505
|
+
let endTime = dayjs(props.brushRange[1]).format("YYYY-MM-DD 23:59:59");
|
|
506
|
+
// 匹配到对应K线的时间段始末时间
|
|
507
|
+
let brushStartTime = null;
|
|
508
|
+
let brushEndTime = null;
|
|
509
|
+
switch (props.cycle) {
|
|
510
|
+
// 日
|
|
511
|
+
case "6": {
|
|
512
|
+
brushStartTime = time.find((item) => dayjs(item).format("YYYY-MM-DD") === dayjs(startTime).format("YYYY-MM-DD"));
|
|
513
|
+
brushEndTime = brushStartTime;
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
// 周
|
|
517
|
+
case "7": {
|
|
518
|
+
brushStartTime = time.find((item) => {
|
|
519
|
+
return dayjs(item).day(5).format("YYYY-MM-DD") === dayjs(startTime).day(5).format("YYYY-MM-DD");
|
|
520
|
+
});
|
|
521
|
+
brushEndTime = time.findLast((item) => {
|
|
522
|
+
return dayjs(item).day(5).format("YYYY-MM-DD") === dayjs(endTime).day(5).format("YYYY-MM-DD");
|
|
523
|
+
});
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
// 月
|
|
527
|
+
case "8": {
|
|
528
|
+
brushStartTime = time.find((item) => {
|
|
529
|
+
return dayjs(item).endOf("month").format("YYYY-MM-DD") === dayjs(startTime).endOf("month").format("YYYY-MM-DD");
|
|
530
|
+
});
|
|
531
|
+
brushEndTime = time.findLast((item) => {
|
|
532
|
+
return dayjs(item).endOf("month").format("YYYY-MM-DD") === dayjs(endTime).endOf("month").format("YYYY-MM-DD");
|
|
533
|
+
});
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
default: {
|
|
537
|
+
brushStartTime = time.find((item) => {
|
|
538
|
+
const condition1 = dayjs(item).format("YYYY-MM-DD") === dayjs(startTime).format("YYYY-MM-DD");
|
|
539
|
+
const condition2 = new Date(item).getTime() >= new Date(startTime).getTime();
|
|
540
|
+
return condition1 && condition2;
|
|
541
|
+
});
|
|
542
|
+
brushEndTime = time.findLast((item) => {
|
|
543
|
+
const condition1 = dayjs(item).format("YYYY-MM-DD") === dayjs(endTime).format("YYYY-MM-DD");
|
|
544
|
+
const condition2 = new Date(item).getTime() <= new Date(endTime).getTime();
|
|
545
|
+
return condition1 && condition2;
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
mainChartIns.dispatchAction({
|
|
550
|
+
type: "brush",
|
|
551
|
+
areas: [
|
|
552
|
+
{
|
|
553
|
+
brushType: "lineX",
|
|
554
|
+
coordRange: [brushStartTime, brushEndTime],
|
|
555
|
+
xAxisIndex: 0,
|
|
556
|
+
},
|
|
557
|
+
],
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
};
|
|
430
561
|
|
|
431
562
|
// 更新预警线并绘制
|
|
432
563
|
const updateWarningLineAndDraw = async () => {
|
|
433
|
-
const res = await getWarningLine({ featureId: props.featureId })
|
|
564
|
+
const res = await getWarningLine({ featureId: props.featureId });
|
|
434
565
|
warningLineData.value = res?.body || [];
|
|
435
|
-
drawLine()
|
|
436
|
-
emit(
|
|
437
|
-
}
|
|
566
|
+
drawLine();
|
|
567
|
+
emit("change", "warningLine", warningLineData.value);
|
|
568
|
+
};
|
|
438
569
|
|
|
439
570
|
const menuClick = async (item) => {
|
|
440
|
-
const { variety, varietyName, featureId, featureType } = props
|
|
441
|
-
if (item.key ===
|
|
571
|
+
const { variety, varietyName, featureId, featureType } = props;
|
|
572
|
+
if (item.key === "drawWarningLine") {
|
|
442
573
|
// 画线预警
|
|
443
574
|
// 拿到当前主图配置项
|
|
444
575
|
const mainChartOption = mainChartIns?.getOption();
|
|
@@ -510,23 +641,23 @@ const menuClick = async (item) => {
|
|
|
510
641
|
warnPrice: newWarnPrice,
|
|
511
642
|
});
|
|
512
643
|
ElMessage.success("画线预警成功!");
|
|
513
|
-
updateWarningLineAndDraw()
|
|
644
|
+
updateWarningLineAndDraw();
|
|
514
645
|
};
|
|
515
646
|
// 4.绑定echarts点击事件
|
|
516
647
|
mainChartIns?.getZr().on("mousedown", handleClick);
|
|
517
|
-
} else if (item.key ===
|
|
648
|
+
} else if (item.key === "deleteWarningLine") {
|
|
518
649
|
// 删除预警线
|
|
519
650
|
await deleteWarningLine({ id: warningItem.value.id });
|
|
520
651
|
ElMessage.success("画线预警删除成功");
|
|
521
|
-
updateWarningLineAndDraw()
|
|
522
|
-
} else if (item.key ===
|
|
652
|
+
updateWarningLineAndDraw();
|
|
653
|
+
} else if (item.key === "changeWarningLine") {
|
|
523
654
|
warningLineChangeVisible.value = true;
|
|
524
655
|
warningLineChangeValue.value = warningItem.value.warnPrice;
|
|
525
656
|
}
|
|
526
|
-
}
|
|
657
|
+
};
|
|
527
658
|
|
|
528
659
|
const changeWarningLine = async () => {
|
|
529
|
-
const { variety, varietyName, featureId, featureType } = props
|
|
660
|
+
const { variety, varietyName, featureId, featureType } = props;
|
|
530
661
|
await updateWarningLine({
|
|
531
662
|
id: warningItem.value.id,
|
|
532
663
|
featureCode: variety, //品种代码
|
|
@@ -536,21 +667,21 @@ const changeWarningLine = async () => {
|
|
|
536
667
|
warnPrice: warningLineChangeValue.value,
|
|
537
668
|
});
|
|
538
669
|
ElMessage.success("画线预警修改成功");
|
|
539
|
-
updateWarningLineAndDraw()
|
|
540
|
-
}
|
|
670
|
+
updateWarningLineAndDraw();
|
|
671
|
+
};
|
|
541
672
|
|
|
542
673
|
const closeContextMenuCallBack = () => {
|
|
543
|
-
menuData.value =[
|
|
674
|
+
menuData.value = [...defaultMenuData];
|
|
544
675
|
};
|
|
545
676
|
|
|
546
677
|
defineExpose({
|
|
547
678
|
draw: (type, data) => {
|
|
548
|
-
if (type ===
|
|
679
|
+
if (type === "warningLine") {
|
|
549
680
|
warningLineData.value = data;
|
|
550
|
-
drawLine()
|
|
681
|
+
drawLine();
|
|
551
682
|
}
|
|
552
|
-
}
|
|
553
|
-
})
|
|
683
|
+
},
|
|
684
|
+
});
|
|
554
685
|
</script>
|
|
555
686
|
|
|
556
687
|
<style lang="scss" scoped>
|
|
@@ -576,7 +707,7 @@ defineExpose({
|
|
|
576
707
|
position: absolute;
|
|
577
708
|
top: 0;
|
|
578
709
|
width: 100%;
|
|
579
|
-
height: 100%;
|
|
710
|
+
height: 100%;
|
|
580
711
|
background: #000;
|
|
581
712
|
&-content {
|
|
582
713
|
height: 100%;
|
|
@@ -597,7 +728,7 @@ defineExpose({
|
|
|
597
728
|
position: absolute;
|
|
598
729
|
top: 0;
|
|
599
730
|
width: 100%;
|
|
600
|
-
height: 100%;
|
|
731
|
+
height: 100%;
|
|
601
732
|
background: #000;
|
|
602
733
|
display: flex;
|
|
603
734
|
flex-direction: column;
|