st-comp 0.0.245 → 0.0.246
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 +574 -606
- package/es/style.css +1 -1
- package/lib/bundle.js +1 -1
- package/lib/bundle.umd.cjs +147 -147
- package/lib/{index-ab2ee69a.js → index-2a325d42.js} +10720 -10752
- package/lib/{python-ca75e11c.js → python-eb65d93b.js} +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/packages/KlineBasic/index.vue +518 -497
- package/src/pages/KlineBasic/api.js +7 -4
- package/src/pages/KlineBasic/index.vue +346 -56
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const
|
|
3
|
+
// 测试环境
|
|
4
|
+
// const token = "dc4eb64816effa53ccee0de7a02e777b";
|
|
5
|
+
// export const host = "http://192.168.12.38:5173";
|
|
6
|
+
|
|
7
|
+
// 线上环境
|
|
8
|
+
const token = "10831ed6ce9ff2652a732f63c5d79c5c";
|
|
9
|
+
export const host = "//investapi.hzyotoy.com";
|
|
5
10
|
|
|
6
11
|
// 获取指标线配置
|
|
7
12
|
export const getIndicator = async () => {
|
|
@@ -21,7 +26,6 @@ export const getConfig = async () => {
|
|
|
21
26
|
});
|
|
22
27
|
return res.data;
|
|
23
28
|
}
|
|
24
|
-
|
|
25
29
|
// 设置配置
|
|
26
30
|
export const setConfig = async (data) => {
|
|
27
31
|
const res = await axios({
|
|
@@ -32,7 +36,6 @@ export const setConfig = async (data) => {
|
|
|
32
36
|
});
|
|
33
37
|
return res.data;
|
|
34
38
|
}
|
|
35
|
-
|
|
36
39
|
// 获取周期列表
|
|
37
40
|
export const getCycleList = async () => {
|
|
38
41
|
const res = await axios({
|
|
@@ -1,76 +1,366 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div style="width: 100%;height: 100%;">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<el-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
<div style="width: 100%;height: 100%; display: flex; flex-direction: column;">
|
|
3
|
+
<!-- 工具栏 -->
|
|
4
|
+
<div style="height: 42px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 0 12px; flex-shrink: 0;">
|
|
5
|
+
<el-radio-group v-model="displayMode" size="small" @change="handleModeChange">
|
|
6
|
+
<el-radio-button value="single">单周期</el-radio-button>
|
|
7
|
+
<el-radio-button value="multi">多周期</el-radio-button>
|
|
8
|
+
</el-radio-group>
|
|
9
|
+
|
|
10
|
+
<el-divider direction="vertical" />
|
|
11
|
+
|
|
12
|
+
<!-- 单周期模式下的配置 -->
|
|
13
|
+
<template v-if="displayMode === 'single'">
|
|
14
|
+
<el-input
|
|
15
|
+
v-model="singleConfig.variety"
|
|
16
|
+
placeholder="品种代码"
|
|
17
|
+
size="small"
|
|
18
|
+
style="width: 120px;"
|
|
14
19
|
/>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
:label="item.label"
|
|
21
|
-
:value="item.value"
|
|
20
|
+
<el-input
|
|
21
|
+
v-model="singleConfig.varietyName"
|
|
22
|
+
placeholder="品种名称"
|
|
23
|
+
size="small"
|
|
24
|
+
style="width: 120px;"
|
|
22
25
|
/>
|
|
23
|
-
|
|
26
|
+
<el-input
|
|
27
|
+
v-model="singleConfig.featureId"
|
|
28
|
+
placeholder="合约ID"
|
|
29
|
+
size="small"
|
|
30
|
+
style="width: 120px;"
|
|
31
|
+
/>
|
|
32
|
+
<el-input
|
|
33
|
+
v-model="singleConfig.featureType"
|
|
34
|
+
placeholder="合约类型"
|
|
35
|
+
size="small"
|
|
36
|
+
style="width: 120px;"
|
|
37
|
+
/>
|
|
38
|
+
<el-select
|
|
39
|
+
v-model="singleConfig.cycle"
|
|
40
|
+
placeholder="周期"
|
|
41
|
+
size="small"
|
|
42
|
+
style="width: 120px;"
|
|
43
|
+
>
|
|
44
|
+
<el-option
|
|
45
|
+
v-for="item in cycleOptions"
|
|
46
|
+
:key="item.value"
|
|
47
|
+
:label="item.label"
|
|
48
|
+
:value="item.value"
|
|
49
|
+
/>
|
|
50
|
+
</el-select>
|
|
51
|
+
<el-select
|
|
52
|
+
v-model="singleConfig.mainIndicator"
|
|
53
|
+
placeholder="主图指标"
|
|
54
|
+
size="small"
|
|
55
|
+
style="width: 120px;"
|
|
56
|
+
>
|
|
57
|
+
<el-option
|
|
58
|
+
v-for="(item, index) in indicatorStore.mainIndicatorList"
|
|
59
|
+
:key="index"
|
|
60
|
+
:label="item.label"
|
|
61
|
+
:value="item.value"
|
|
62
|
+
/>
|
|
63
|
+
</el-select>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<!-- 多周期模式下的配置(共用基础信息) -->
|
|
67
|
+
<template v-if="displayMode === 'multi'">
|
|
68
|
+
<el-input
|
|
69
|
+
v-model="multiBaseConfig.variety"
|
|
70
|
+
placeholder="品种代码"
|
|
71
|
+
size="small"
|
|
72
|
+
style="width: 120px;"
|
|
73
|
+
@change="refreshMultiCharts"
|
|
74
|
+
/>
|
|
75
|
+
<el-input
|
|
76
|
+
v-model="multiBaseConfig.varietyName"
|
|
77
|
+
placeholder="品种名称"
|
|
78
|
+
size="small"
|
|
79
|
+
style="width: 120px;"
|
|
80
|
+
@change="refreshMultiCharts"
|
|
81
|
+
/>
|
|
82
|
+
<el-input
|
|
83
|
+
v-model="multiBaseConfig.featureId"
|
|
84
|
+
placeholder="合约ID"
|
|
85
|
+
size="small"
|
|
86
|
+
style="width: 120px;"
|
|
87
|
+
@change="refreshMultiCharts"
|
|
88
|
+
/>
|
|
89
|
+
<el-input
|
|
90
|
+
v-model="multiBaseConfig.featureType"
|
|
91
|
+
placeholder="合约类型"
|
|
92
|
+
size="small"
|
|
93
|
+
style="width: 120px;"
|
|
94
|
+
@change="refreshMultiCharts"
|
|
95
|
+
/>
|
|
96
|
+
<el-select
|
|
97
|
+
v-model="multiBaseConfig.mainIndicator"
|
|
98
|
+
placeholder="主图指标"
|
|
99
|
+
size="small"
|
|
100
|
+
style="width: 120px;"
|
|
101
|
+
@change="refreshMultiCharts"
|
|
102
|
+
>
|
|
103
|
+
<el-option
|
|
104
|
+
v-for="(item, index) in indicatorStore.mainIndicatorList"
|
|
105
|
+
:key="index"
|
|
106
|
+
:label="item.label"
|
|
107
|
+
:value="item.value"
|
|
108
|
+
/>
|
|
109
|
+
</el-select>
|
|
110
|
+
</template>
|
|
24
111
|
</div>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
:
|
|
31
|
-
:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
112
|
+
|
|
113
|
+
<!-- 图表展示区域 -->
|
|
114
|
+
<div
|
|
115
|
+
class="charts-container"
|
|
116
|
+
:style="{
|
|
117
|
+
height: 'calc(100% - 42px)',
|
|
118
|
+
overflow: 'auto'
|
|
119
|
+
}"
|
|
120
|
+
>
|
|
121
|
+
<!-- 单周期模式:单个图表 -->
|
|
122
|
+
<div
|
|
123
|
+
v-if="displayMode === 'single' && show"
|
|
124
|
+
class="single-chart"
|
|
125
|
+
>
|
|
126
|
+
<st-klineBasic
|
|
127
|
+
:key="singleChartKey"
|
|
128
|
+
:variety="singleConfig.variety"
|
|
129
|
+
:varietyName="singleConfig.varietyName"
|
|
130
|
+
:featureId="singleConfig.featureId"
|
|
131
|
+
:featureType="singleConfig.featureType"
|
|
132
|
+
:cycle="singleConfig.cycle"
|
|
133
|
+
:mainIndicator="singleConfig.mainIndicator"
|
|
134
|
+
:indicatorStore="indicatorStore"
|
|
135
|
+
:env="{ VITE_BASE_URL: host }"
|
|
136
|
+
:brushRange="['2025-06-03 00:00:00', '2025-06-05 23:59:59']"
|
|
137
|
+
/>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<!-- 多周期模式:6个图表网格布局 -->
|
|
141
|
+
<div
|
|
142
|
+
v-if="displayMode === 'multi' && show"
|
|
143
|
+
class="multi-charts-grid"
|
|
144
|
+
>
|
|
145
|
+
<div
|
|
146
|
+
v-for="(chart, index) in multiCharts"
|
|
147
|
+
:key="`${chart.cycle}-${multiBaseConfig.variety}`"
|
|
148
|
+
class="multi-chart-item"
|
|
149
|
+
>
|
|
150
|
+
<div class="multi-chart-header">
|
|
151
|
+
<span class="multi-chart-title">{{ chart.cycleLabel }}</span>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="multi-chart-content">
|
|
154
|
+
<st-klineBasic
|
|
155
|
+
:ref="(el) => setChartRef(el, chart.cycle)"
|
|
156
|
+
:variety="multiBaseConfig.variety"
|
|
157
|
+
:varietyName="multiBaseConfig.varietyName"
|
|
158
|
+
:featureId="multiBaseConfig.featureId"
|
|
159
|
+
:featureType="multiBaseConfig.featureType"
|
|
160
|
+
:cycle="chart.cycle"
|
|
161
|
+
:mainIndicator="multiBaseConfig.mainIndicator"
|
|
162
|
+
:indicatorStore="indicatorStore"
|
|
163
|
+
:env="{ VITE_BASE_URL: host }"
|
|
164
|
+
:brushRange="['2025-06-03 00:00:00', '2025-06-05 23:59:59']"
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
38
169
|
</div>
|
|
39
170
|
</div>
|
|
40
171
|
</template>
|
|
41
172
|
|
|
42
173
|
<script setup>
|
|
43
|
-
import { ref, onMounted } from 'vue';
|
|
174
|
+
import { ref, reactive, computed, onMounted, watch } from 'vue';
|
|
44
175
|
import useIndicatorStore from './indicator';
|
|
45
|
-
import { getCycleList } from './api';
|
|
46
|
-
|
|
47
|
-
const freqOptions = ['1m', '5m', '15m', '30m', '60m', '1d', '1w', '1mon']
|
|
176
|
+
import { getCycleList, host } from './api';
|
|
48
177
|
|
|
49
178
|
const indicatorStore = useIndicatorStore();
|
|
50
179
|
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
180
|
+
// 显示模式
|
|
181
|
+
const displayMode = ref('single'); // single: 单周期, multi: 多周期
|
|
182
|
+
const show = ref(false);
|
|
183
|
+
|
|
184
|
+
// 周期映射
|
|
185
|
+
const cycleMap = {
|
|
186
|
+
'15m': { value: '1', label: '15分钟' },
|
|
187
|
+
'30m': { value: '2', label: '30分钟' },
|
|
188
|
+
'60m': { value: '3', label: '60分钟' },
|
|
189
|
+
'1d': { value: '6', label: '日线' },
|
|
190
|
+
'1w': { value: '7', label: '周线' },
|
|
191
|
+
'1mon': { value: '8', label: '月线' }
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// 多周期展示的周期列表
|
|
195
|
+
const multiCycleList = [
|
|
196
|
+
{ cycle: '1', cycleLabel: '15分钟' }, // 15m
|
|
197
|
+
{ cycle: '2', cycleLabel: '30分钟' }, // 30m
|
|
198
|
+
{ cycle: '3', cycleLabel: '60分钟' }, // 60m
|
|
199
|
+
{ cycle: '6', cycleLabel: '日线' }, // 1d
|
|
200
|
+
{ cycle: '7', cycleLabel: '周线' }, // 1w
|
|
201
|
+
{ cycle: '8', cycleLabel: '月线' } // 1mon
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
// 周期选项
|
|
56
205
|
const cycleOptions = ref([]);
|
|
57
|
-
const cycle = ref('');
|
|
58
|
-
const mainIndicator = ref('DKX_EMA')
|
|
59
|
-
const config = ref({
|
|
60
|
-
defaultShowCounts: 500, // 默认展示条数
|
|
61
|
-
maxShowCounts: 5000, // 单页最大展示条数
|
|
62
|
-
showSubChart: true, // 是否展示副图
|
|
63
|
-
})
|
|
64
206
|
|
|
207
|
+
// 单周期配置
|
|
208
|
+
const singleConfig = reactive({
|
|
209
|
+
variety: '000001',
|
|
210
|
+
varietyName: '平安银行',
|
|
211
|
+
featureId: 88,
|
|
212
|
+
featureType: '3',
|
|
213
|
+
cycle: '',
|
|
214
|
+
mainIndicator: 'DKX_EMA'
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// 多周期基础配置(共用)
|
|
218
|
+
const multiBaseConfig = reactive({
|
|
219
|
+
variety: '000001',
|
|
220
|
+
varietyName: '平安银行',
|
|
221
|
+
featureId: 88,
|
|
222
|
+
featureType: '3',
|
|
223
|
+
mainIndicator: 'DKX_EMA'
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// 多周期图表数据
|
|
227
|
+
const multiCharts = ref(multiCycleList);
|
|
228
|
+
|
|
229
|
+
// 存储图表实例引用(用于需要时手动刷新)
|
|
230
|
+
const chartRefs = ref({});
|
|
231
|
+
|
|
232
|
+
// 单图表刷新key
|
|
233
|
+
const singleChartKey = ref(0);
|
|
234
|
+
|
|
235
|
+
// 设置图表引用
|
|
236
|
+
const setChartRef = (el, cycle) => {
|
|
237
|
+
if (el) {
|
|
238
|
+
chartRefs.value[cycle] = el;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// 刷新多周期图表
|
|
243
|
+
const refreshMultiCharts = () => {
|
|
244
|
+
// 通过重新生成key来强制刷新
|
|
245
|
+
multiCharts.value = [...multiCycleList];
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// 模式切换处理
|
|
249
|
+
const handleModeChange = () => {
|
|
250
|
+
// 切换模式时不需要额外操作,Vue会自动重新渲染
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// 监听单周期配置变化,刷新图表
|
|
254
|
+
watch(
|
|
255
|
+
() => [singleConfig.variety, singleConfig.cycle, singleConfig.mainIndicator],
|
|
256
|
+
() => {
|
|
257
|
+
if (displayMode.value === 'single') {
|
|
258
|
+
singleChartKey.value++;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// 监听多周期基础配置变化,刷新所有图表
|
|
264
|
+
watch(
|
|
265
|
+
() => [multiBaseConfig.variety, multiBaseConfig.mainIndicator],
|
|
266
|
+
() => {
|
|
267
|
+
if (displayMode.value === 'multi') {
|
|
268
|
+
refreshMultiCharts();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
// 初始化
|
|
65
274
|
onMounted(async () => {
|
|
66
|
-
await indicatorStore.init()
|
|
67
|
-
const res = await getCycleList()
|
|
68
|
-
cycleOptions.value = res?.body?.[1002].map(item => ({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
})
|
|
275
|
+
await indicatorStore.init();
|
|
276
|
+
const res = await getCycleList();
|
|
277
|
+
cycleOptions.value = res?.body?.[1002].map(item => ({
|
|
278
|
+
label: item.dictName,
|
|
279
|
+
value: item.dictCode
|
|
280
|
+
}));
|
|
281
|
+
|
|
282
|
+
// 设置默认周期(取第二个选项,通常是日线)
|
|
283
|
+
if (cycleOptions.value.length > 1) {
|
|
284
|
+
singleConfig.cycle = cycleOptions.value[1].value;
|
|
285
|
+
} else if (cycleOptions.value.length > 0) {
|
|
286
|
+
singleConfig.cycle = cycleOptions.value[0].value;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
show.value = true;
|
|
290
|
+
});
|
|
72
291
|
</script>
|
|
73
292
|
|
|
74
293
|
<style lang="scss" scoped>
|
|
294
|
+
.charts-container {
|
|
295
|
+
flex: 1;
|
|
296
|
+
overflow: auto;
|
|
297
|
+
padding: 12px;
|
|
298
|
+
background: #f5f5f5;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 单周期模式
|
|
302
|
+
.single-chart {
|
|
303
|
+
width: 100%;
|
|
304
|
+
height: 100%;
|
|
305
|
+
min-height: 600px;
|
|
306
|
+
background: #000;
|
|
307
|
+
border-radius: 4px;
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// 多周期模式 - 网格布局
|
|
312
|
+
.multi-charts-grid {
|
|
313
|
+
display: grid;
|
|
314
|
+
grid-template-columns: repeat(3, 1fr);
|
|
315
|
+
gap: 12px;
|
|
316
|
+
width: 100%;
|
|
317
|
+
}
|
|
75
318
|
|
|
76
|
-
|
|
319
|
+
// 多周期模式 - 6宫格布局
|
|
320
|
+
.multi-charts-grid {
|
|
321
|
+
display: grid;
|
|
322
|
+
grid-template-columns: repeat(3, 1fr); // 3列
|
|
323
|
+
grid-template-rows: repeat(2, 1fr); // 2行,每行占满剩余空间
|
|
324
|
+
gap: 12px;
|
|
325
|
+
width: 100%;
|
|
326
|
+
height: 100%; // 占满父容器高度
|
|
327
|
+
min-height: 0; // 确保grid可以正确收缩
|
|
328
|
+
|
|
329
|
+
.multi-chart-item {
|
|
330
|
+
background: #000;
|
|
331
|
+
border-radius: 4px;
|
|
332
|
+
overflow: hidden;
|
|
333
|
+
display: flex;
|
|
334
|
+
flex-direction: column;
|
|
335
|
+
min-height: 0; // 确保flex子项可以正确收缩
|
|
336
|
+
height: 100%; // 占满grid单元格高度
|
|
337
|
+
|
|
338
|
+
.multi-chart-header {
|
|
339
|
+
height: 32px;
|
|
340
|
+
padding: 0 12px;
|
|
341
|
+
background: #1a1a1a;
|
|
342
|
+
display: flex;
|
|
343
|
+
align-items: center;
|
|
344
|
+
border-bottom: 1px solid #333;
|
|
345
|
+
flex-shrink: 0; // 头部固定高度,不收缩
|
|
346
|
+
|
|
347
|
+
.multi-chart-title {
|
|
348
|
+
font-size: 14px;
|
|
349
|
+
font-weight: 500;
|
|
350
|
+
color: #fff;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.multi-chart-content {
|
|
355
|
+
flex: 1; // 占满剩余空间
|
|
356
|
+
min-height: 0; // 确保内容区域可以正确收缩
|
|
357
|
+
position: relative;
|
|
358
|
+
|
|
359
|
+
// 确保K线组件占满容器
|
|
360
|
+
:deep(.klineBasic) {
|
|
361
|
+
height: 100%;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
</style>
|