st-comp 0.0.45 → 0.0.47

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "st-comp",
3
3
  "public": true,
4
- "version": "0.0.45",
4
+ "version": "0.0.47",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
@@ -17,12 +17,11 @@
17
17
  "echarts": "^5.4.3",
18
18
  "element-plus": "^2.3.14",
19
19
  "pinia": "^2.1.6",
20
- "st-func": "^0.0.14",
20
+ "st-func": "^0.0.18",
21
21
  "talib.js": "^0.1.0",
22
22
  "vue-router": "^4.2.5"
23
23
  },
24
24
  "devDependencies": {
25
- "vue": "^3.3.4",
26
25
  "@vitejs/plugin-vue": "^4.2.3",
27
26
  "sass": "^1.69.3",
28
27
  "ssh2": "^1.14.0",
@@ -31,6 +30,7 @@
31
30
  "unplugin-auto-import": "^0.17.1",
32
31
  "unplugin-vue-components": "^0.25.2",
33
32
  "vite": "^4.4.5",
33
+ "vue": "^3.3.4",
34
34
  "vue-tsc": "^1.8.5"
35
35
  }
36
36
  }
@@ -10,16 +10,10 @@ import type { EChartsType } from 'echarts'
10
10
  let slideChart: EChartsType
11
11
  let resizeRo: any // dom元素监听事件
12
12
  let slideDataZoomTimer: any = null // 滑动图数据缩放定时器
13
- const defaultCOnfig = {
14
- preLoadDays: 50, // 预加载天数
15
- defaultShowDays: 50, // 默认显示天数
16
- maxShowDays: 200, // 最大展示天数
17
- }
18
13
 
19
14
  const emit = defineEmits(['change'])
20
15
  const props = defineProps({
21
16
  data: { type: Array, default: () => [] }, // 时间数据
22
- config: { type: Object, default: () => {} }, // 配置数据
23
17
  })
24
18
 
25
19
  const slideChartRef = ref<HTMLElement>() // 拖动轴
@@ -28,7 +22,6 @@ watch(
28
22
  () => props.data,
29
23
  () => {
30
24
  draw()
31
- change(props.data.length - 1 - defaultCOnfig.defaultShowDays, props.data.length - 1)
32
25
  },
33
26
  { deep: true },
34
27
  )
@@ -37,7 +30,6 @@ onMounted(() => {
37
30
  slideChart = echarts.init(slideChartRef.value)
38
31
  addEventListener()
39
32
  draw()
40
- change(props.data.length - 1 - defaultCOnfig.defaultShowDays, props.data.length - 1)
41
33
  // 绑定resize事件
42
34
  let isFirst: boolean | null = true
43
35
  resizeRo = new ResizeObserver(() => {
@@ -75,18 +67,13 @@ const addEventListener = () => {
75
67
 
76
68
  // 拖动回调
77
69
  const change = (startIndex: number, endIndex: number) => {
78
- const { preLoadDays } = defaultCOnfig
79
70
  const data: any = props.data
80
71
  if (data.length === 0) return
81
- const startTime = (data[startIndex - preLoadDays < 0 ? 0 : startIndex - preLoadDays][0] as string).split(' ')[0]
82
- const showStartTime = (data[startIndex][0] as string).split(' ')[0]
83
- const endTime = (data[endIndex + preLoadDays > data.length ? data.length - 1 : endIndex + preLoadDays][0] as string).split(' ')[0]
84
- const showEndTime = (data[endIndex][0] as string).split(' ')[0]
72
+ const startTime = (data[startIndex][0] as string).split(' ')[0]
73
+ const endTime = (data[endIndex][0] as string).split(' ')[0]
85
74
  emit('change', {
86
75
  startTime: `${startTime} 00:00:00`,
87
- showStartTime: `${showStartTime} 00:00:00`,
88
76
  endTime: `${endTime} 24:00:00`,
89
- showEndTime: `${showEndTime} 24:00:00`,
90
77
  })
91
78
  }
92
79
 
@@ -101,20 +88,6 @@ const draw = () => {
101
88
  left: '80px',
102
89
  right: '80px',
103
90
  },
104
- dataZoom: [
105
- {
106
- show: true,
107
- startValue: data.length - 1 - defaultCOnfig.defaultShowDays,
108
- endValue: data.length - 1,
109
- maxValueSpan: defaultCOnfig.maxShowDays,
110
- },
111
- {
112
- type: 'inside',
113
- startValue: data.length - 1 - defaultCOnfig.defaultShowDays,
114
- endValue: data.length - 1,
115
- maxValueSpan: defaultCOnfig.maxShowDays,
116
- }
117
- ],
118
91
  xAxis: {
119
92
  type: 'category',
120
93
  data: xAxisData,
@@ -133,15 +106,7 @@ const draw = () => {
133
106
  }
134
107
 
135
108
  defineExpose({
136
- reset: () => {
137
- slideChart.dispatchAction({
138
- type: 'dataZoom',
139
- startValue: props.data.length - 1 - defaultCOnfig.defaultShowDays,
140
- endValue: props.data.length - 1,
141
- })
142
- change(props.data.length - 1 - defaultCOnfig.defaultShowDays, props.data.length - 1)
143
- }, // 重置
144
- resetSlide: (startTime, endTime) => {
109
+ resetSlide: (startTime: string, endTime: string, maxValueSpan: number) => {
145
110
  let slideStartIndex = -1
146
111
  let slideEndIndex = -1
147
112
  props.data.forEach((item: any, index: number) => {
@@ -155,12 +120,23 @@ defineExpose({
155
120
  } else if (slideEndIndex === -1 && new Date(item[0]) > new Date(endTime)) {
156
121
  slideEndIndex = index - 1
157
122
  }
158
-
159
123
  })
160
- slideChart.dispatchAction({
161
- type: 'dataZoom',
162
- startValue: slideStartIndex,
163
- endValue: slideEndIndex
124
+ slideEndIndex = slideEndIndex === -1 ? props.data.length - 1 : slideEndIndex
125
+ slideChart.setOption({
126
+ dataZoom: [
127
+ {
128
+ show: true,
129
+ startValue: slideStartIndex,
130
+ endValue: slideEndIndex,
131
+ maxValueSpan,
132
+ },
133
+ {
134
+ type: 'inside',
135
+ startValue: slideStartIndex,
136
+ endValue: slideEndIndex,
137
+ maxValueSpan,
138
+ }
139
+ ],
164
140
  })
165
141
  }, // 重置
166
142
  })
@@ -23,7 +23,7 @@
23
23
  </template>
24
24
 
25
25
  <script setup lang="ts">
26
- import { ref, onMounted, onUnmounted, watch, computed } from "vue"
26
+ import { ref, onMounted, onUnmounted, nextTick, computed } from "vue"
27
27
  import * as echarts from 'echarts'
28
28
  import type { EChartsType } from 'echarts'
29
29
  import Tips from '../Tips/index.vue'
@@ -39,6 +39,7 @@ const props = defineProps({
39
39
  activeIndex: { type: Number, require: true },
40
40
  modelValue: { type: String, required: true }, // 副图指标
41
41
  subIndicatorList: { type: Array, required: true }, // 副图指标列表
42
+ config: { type: Object, require: true }, // 配置
42
43
  })
43
44
 
44
45
  const subChartRef = ref<HTMLElement>() // 拖动轴
@@ -54,7 +55,7 @@ const subIndicator = computed({
54
55
  const subIndicatorTips = computed(() => {
55
56
  const { drawData, activeIndex } = props
56
57
  const subIndicatorInfo = props.subIndicatorList.find((item: any) => item.value === subIndicator.value)
57
- if (drawData.originData[activeIndex]) {
58
+ if (drawData.originData && drawData.originData[activeIndex]) {
58
59
  return subIndicatorInfo.config.map((item: any) => {
59
60
  let value = '-'
60
61
  if (item.source === 'origin') {
@@ -118,180 +119,168 @@ defineExpose({
118
119
  echarts.connect([chart, subChart])
119
120
  },// 联动
120
121
  draw: (config) => {
121
- const { showStartTime, showEndTime, drawData, subIndicator, subIndicatorList, maxShowDays } = config
122
- const { xAxisData, subIndicatorData, candlestickData, originData } = drawData
123
- const subIndicatorInfo = subIndicatorList.find((item: any) => item.value === subIndicator)
124
- let startValue = -1
125
- let endValue = -1
126
- let dayPerTime: any = {}
127
- xAxisData.forEach((time: any, index: number) => {
128
- dayPerTime[time.split(' ')[0]] = dayPerTime[time.split(' ')[0]] || 0
129
- dayPerTime[time.split(' ')[0]] += 1
130
- if (new Date(time) >= new Date(showStartTime) && startValue === -1) {
131
- startValue = index
132
- }
133
- if (new Date(time) <= new Date(showEndTime)) {
134
- endValue = index
135
- }
136
- })
137
- const maxShowCount = Math.max(...Object.values(dayPerTime)) * maxShowDays
138
- const series: any[] = []
139
- // 主图
140
- if (subIndicatorInfo.series === 'bar') {
141
- let data = []
142
- if (subIndicatorInfo.source === 'origin') {
143
- data = originData.map((i: any) => i[subIndicatorInfo.dataIndex])
144
- } else {
145
- data = subIndicatorData?.find((i: any) => i.key === subIndicatorInfo.dataIndex)?.data || []
146
- }
147
-
148
- series.push({
149
- name: 'subMain',
150
- xAxisIndex: 0,
151
- yAxisIndex: 1,
152
- type: 'bar',
153
- silent: true,
154
- symbol: 'none',
155
- data: data.map((item: any, index: number) => {
156
- if (subIndicatorInfo.color === 'kline') {
157
- return {
158
- value: item,
159
- itemStyle: getSubBarStyle(candlestickData, index),
160
- }
161
- } else if (subIndicatorInfo.color === 'value') {
162
- return {
163
- value: item,
164
- itemStyle: {
165
- color: item >= 0 ? '#FF0000' : '#00FFFF',
166
- },
167
- }
168
- } else {
169
- return {
170
- value: item,
171
- itemStyle: {
172
- color: subIndicatorInfo.color,
173
- },
174
- }
175
- }
176
- }),
177
- })
178
- }
179
-
180
- // 处理副图指标线数据
181
- subIndicatorData.forEach((item: any) => {
182
- if (item.series === 'line') {
122
+ nextTick(() => {
123
+ const { startValue, endValue, maxValueSpan } = config
124
+ const { xAxisData, subIndicatorData, candlestickData, originData } = (props.drawData as any)
125
+ const subIndicatorInfo: any = props.subIndicatorList.find((item: any) => item.value === subIndicator.value)
126
+ const series: any[] = []
127
+ // 主图
128
+ if (subIndicatorInfo.series === 'bar') {
183
129
  let data = []
184
- if (item.source === 'origin') {
185
- data = originData.map((i: any) => i[item.dataIndex])
186
- } else if (item.source === 'calculation') {
187
- data = item.data
130
+ if (subIndicatorInfo.source === 'origin') {
131
+ data = originData.map((i: any) => i[subIndicatorInfo.dataIndex])
132
+ } else {
133
+ data = subIndicatorData?.find((i: any) => i.key === subIndicatorInfo.dataIndex)?.data || []
188
134
  }
135
+
189
136
  series.push({
137
+ name: 'subMain',
190
138
  xAxisIndex: 0,
191
- yAxisIndex: item.yAxis === 'right' ? 2 : 1,
192
- name: item.key,
193
- type: 'line',
139
+ yAxisIndex: 1,
140
+ type: 'bar',
194
141
  silent: true,
195
142
  symbol: 'none',
196
- data,
197
- lineStyle: {
198
- width: 1,
199
- },
200
- itemStyle: {
201
- color: item.color,
202
- },
143
+ data: data.map((item: any, index: number) => {
144
+ if (subIndicatorInfo.color === 'kline') {
145
+ return {
146
+ value: item,
147
+ itemStyle: getSubBarStyle(candlestickData, index),
148
+ }
149
+ } else if (subIndicatorInfo.color === 'value') {
150
+ return {
151
+ value: item,
152
+ itemStyle: {
153
+ color: item >= 0 ? '#FF0000' : '#00FFFF',
154
+ },
155
+ }
156
+ } else {
157
+ return {
158
+ value: item,
159
+ itemStyle: {
160
+ color: subIndicatorInfo.color,
161
+ },
162
+ }
163
+ }
164
+ }),
203
165
  })
204
166
  }
205
- })
206
167
 
207
- subChart.setOption({
208
- animation: false,
209
- grid: {
210
- left: '60px',
211
- top: '10px',
212
- right: '20px',
213
- bottom: '20px',
214
- },
215
- dataZoom: [
216
- {
217
- type: 'inside',
218
- startValue,
219
- endValue,
220
- maxValueSpan: maxShowCount,
168
+ // 处理副图指标线数据
169
+ subIndicatorData.forEach((item: any) => {
170
+ if (item.series === 'line') {
171
+ let data = []
172
+ if (item.source === 'origin') {
173
+ data = originData.map((i: any) => i[item.dataIndex])
174
+ } else if (item.source === 'calculation') {
175
+ data = item.data
176
+ }
177
+ series.push({
178
+ xAxisIndex: 0,
179
+ yAxisIndex: item.yAxis === 'right' ? 2 : 1,
180
+ name: item.key,
181
+ type: 'line',
182
+ silent: true,
183
+ symbol: 'none',
184
+ data,
185
+ lineStyle: {
186
+ width: 1,
187
+ },
188
+ itemStyle: {
189
+ color: item.color,
190
+ },
191
+ })
221
192
  }
222
- ],
223
- tooltip: {
224
- trigger: 'axis',
225
- appendToBody: true,
226
- confine: true,
227
- axisPointer: {
228
- type: 'cross',
229
- label: {
230
- rich: {},
231
- formatter: (data: any) => {
232
- const { axisDimension, value } = data
233
- if(axisDimension === 'x') {
234
- return value
235
- } else if(data.axisIndex === 1) {
236
- return String(round(value))
193
+ })
194
+
195
+ subChart.setOption({
196
+ animation: false,
197
+ grid: {
198
+ left: `${props.config.gridLeft}px`,
199
+ top: '10px',
200
+ right: `${props.config.gridRight}px`,
201
+ bottom: '20px',
202
+ },
203
+ dataZoom: [
204
+ {
205
+ type: 'inside',
206
+ startValue,
207
+ endValue,
208
+ maxValueSpan,
209
+ }
210
+ ],
211
+ tooltip: {
212
+ trigger: 'axis',
213
+ appendToBody: true,
214
+ confine: true,
215
+ axisPointer: {
216
+ type: 'cross',
217
+ label: {
218
+ rich: {},
219
+ formatter: (data: any) => {
220
+ const { axisDimension, value } = data
221
+ if(axisDimension === 'x') {
222
+ return value
223
+ } else if(data.axisIndex === 1) {
224
+ return String(round(value))
225
+ }
237
226
  }
238
- }
227
+ },
239
228
  },
229
+ formatter: () => ''
240
230
  },
241
- formatter: () => ''
242
- },
243
- xAxis: {
244
- type: "category",
245
- data: xAxisData,
246
- axisLine: {
247
- show: true,
248
- },
249
- splitLine: {
250
- show: false,
251
- },
252
- axisLabel: {
253
- show: true,
254
- formatter: (data: string) => data,
255
- },
256
- },
257
- yAxis: [
258
- {
259
- position: 'right',
260
- },
261
- {
262
- position: 'left',
263
- min: subIndicatorInfo.leftYAxisRange === 'cover' ? (value: any) => value.min : null,
264
- max: subIndicatorInfo.leftYAxisRange === 'cover' ? (value: any) => value.max : null,
265
- splitNumber: 1,
231
+ xAxis: {
232
+ type: "category",
233
+ data: xAxisData,
266
234
  axisLine: {
267
235
  show: true,
268
236
  },
269
237
  splitLine: {
238
+ show: false,
239
+ },
240
+ axisLabel: {
270
241
  show: true,
271
- lineStyle: {
272
- type: 'dotted',
273
- color: '#333',
274
- },
242
+ formatter: (data: string) => data,
275
243
  },
276
244
  },
277
- {
278
- position: 'right',
279
- min: subIndicatorInfo.rightYAxisRange === 'cover' ? (value: any) => value.min : null,
280
- max: subIndicatorInfo.rightYAxisRange === 'cover' ? (value: any) => value.max : null,
281
- splitNumber: 1,
282
- axisLine: {
283
- show: false,
245
+ yAxis: [
246
+ {
247
+ position: 'right',
284
248
  },
285
- splitLine: {
286
- show: false,
249
+ {
250
+ position: 'left',
251
+ min: subIndicatorInfo.leftYAxisRange === 'cover' ? (value: any) => value.min : null,
252
+ max: subIndicatorInfo.leftYAxisRange === 'cover' ? (value: any) => value.max : null,
253
+ splitNumber: 1,
254
+ axisLine: {
255
+ show: true,
256
+ },
257
+ splitLine: {
258
+ show: true,
259
+ lineStyle: {
260
+ type: 'dotted',
261
+ color: '#333',
262
+ },
263
+ },
287
264
  },
288
- axisLabel: {
289
- show: false,
290
- }
291
- },
292
- ],
293
- series,
294
- }, true)
265
+ {
266
+ position: 'right',
267
+ min: subIndicatorInfo.rightYAxisRange === 'cover' ? (value: any) => value.min : null,
268
+ max: subIndicatorInfo.rightYAxisRange === 'cover' ? (value: any) => value.max : null,
269
+ splitNumber: 1,
270
+ axisLine: {
271
+ show: false,
272
+ },
273
+ splitLine: {
274
+ show: false,
275
+ },
276
+ axisLabel: {
277
+ show: false,
278
+ }
279
+ },
280
+ ],
281
+ series,
282
+ }, true)
283
+ })
295
284
  }, // 重置
296
285
  })
297
286
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="kline-mainTips">
2
+ <div class="kline-tips">
3
3
  <Tips :data="mainTips" />
4
4
  <Tips :data="mainIndicatorTips" />
5
5
  </div>
@@ -24,10 +24,10 @@
24
24
  })
25
25
 
26
26
  const mainTips = computed(() => {
27
- const { drawData, activeIndex } = props
27
+ const { drawData, activeIndex } = (props as any)
28
+ if (drawData.candlestickData && drawData.candlestickData[activeIndex]) {
28
29
  const itemData = drawData.candlestickData[activeIndex]
29
- if (itemData) {
30
- const diff = round(multiply(divide(subtract(itemData[2], itemData[4]), itemData[4]), 100))
30
+ const diff = round(multiply(divide(subtract(itemData[1], itemData[4]), itemData[4]), 100))
31
31
  let diffColor
32
32
  if (diff > 0) {
33
33
  diffColor = 'red'
@@ -37,8 +37,8 @@
37
37
  return [
38
38
  { label: '开', value: round(itemData[0]) },
39
39
  { label: '高', value: round(itemData[3]) },
40
- { label: '低', value: round(itemData[1]) },
41
- { label: '收', value: round(itemData[2]) },
40
+ { label: '低', value: round(itemData[2]) },
41
+ { label: '收', value: round(itemData[1]) },
42
42
  { label: '涨跌', value: `${diff}%`, color: diffColor },
43
43
  ]
44
44
  }
@@ -47,14 +47,14 @@
47
47
 
48
48
  const mainIndicatorTips = computed(() => {
49
49
  const { drawData, activeIndex } = props
50
- return drawData.mainIndicatorData.map(item => {
50
+ return drawData?.mainIndicatorData?.map(item => {
51
51
  return { label: item.key, value: round(item.data[activeIndex]), color: item.color }
52
- })
52
+ }) || []
53
53
  })
54
54
  </script>
55
55
 
56
56
  <style lang="scss" scoped>
57
- .kline-mainTips {
57
+ .kline-tips {
58
58
  padding-left: 3px;
59
59
  width: 100%;
60
60
  }