@orbcharts/plugins-basic 3.0.0-alpha.34 → 3.0.0-alpha.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/dist/orbcharts-plugins-basic.es.js +10198 -9511
  2. package/dist/orbcharts-plugins-basic.umd.js +10 -10
  3. package/dist/src/base/BaseBarStack.d.ts +5 -1
  4. package/dist/src/base/BaseBars.d.ts +5 -1
  5. package/dist/src/base/BaseBarsTriangle.d.ts +5 -1
  6. package/dist/src/base/BaseDots.d.ts +4 -1
  7. package/dist/src/base/BaseGroupAxis.d.ts +35 -0
  8. package/dist/src/base/BaseLines.d.ts +3 -1
  9. package/dist/src/base/BaseValueAxis.d.ts +36 -0
  10. package/dist/src/grid/defaults.d.ts +3 -3
  11. package/dist/src/grid/gridObservables.d.ts +18 -4
  12. package/dist/src/grid/index.d.ts +1 -1
  13. package/dist/src/grid/plugins/GroupAux.d.ts +3 -0
  14. package/dist/src/grid/plugins/GroupAxis.d.ts +1 -3
  15. package/dist/src/grid/plugins/ValueAxis.d.ts +1 -3
  16. package/dist/src/grid/plugins/ValueStackAxis.d.ts +1 -3
  17. package/dist/src/grid/types.d.ts +1 -1
  18. package/dist/src/multiGrid/defaults.d.ts +9 -2
  19. package/dist/src/multiGrid/index.d.ts +8 -1
  20. package/dist/src/multiGrid/multiGridObservables.d.ts +12 -0
  21. package/dist/src/multiGrid/plugins/MultiBarStack.d.ts +1 -0
  22. package/dist/src/multiGrid/plugins/MultiBars.d.ts +1 -0
  23. package/dist/src/multiGrid/plugins/MultiBarsTriangle.d.ts +1 -0
  24. package/dist/src/multiGrid/plugins/MultiDots.d.ts +1 -0
  25. package/dist/src/multiGrid/plugins/MultiGroupAxis.d.ts +1 -0
  26. package/dist/src/multiGrid/plugins/MultiLines.d.ts +1 -0
  27. package/dist/src/multiGrid/plugins/MultiValueAxis.d.ts +1 -0
  28. package/dist/src/multiGrid/plugins/OverlappingValueAxes.d.ts +1 -0
  29. package/dist/src/multiGrid/types.d.ts +31 -0
  30. package/package.json +2 -2
  31. package/src/base/BaseBarStack.ts +375 -198
  32. package/src/base/BaseBars.ts +297 -191
  33. package/src/base/BaseBarsTriangle.ts +344 -229
  34. package/src/base/BaseDots.ts +285 -117
  35. package/src/base/BaseGroupAxis.ts +497 -0
  36. package/src/base/BaseLines.ts +180 -50
  37. package/src/base/BaseValueAxis.ts +475 -0
  38. package/src/grid/defaults.ts +3 -3
  39. package/src/grid/gridObservables.ts +147 -14
  40. package/src/grid/index.ts +1 -1
  41. package/src/grid/plugins/BarStack.ts +4 -0
  42. package/src/grid/plugins/Bars.ts +4 -0
  43. package/src/grid/plugins/BarsTriangle.ts +4 -0
  44. package/src/grid/plugins/Dots.ts +3 -0
  45. package/src/grid/plugins/{GroupArea.ts → GroupAux.ts} +24 -24
  46. package/src/grid/plugins/GroupAxis.ts +16 -348
  47. package/src/grid/plugins/Lines.ts +2 -0
  48. package/src/grid/plugins/ScalingArea.ts +9 -6
  49. package/src/grid/plugins/ValueAxis.ts +13 -337
  50. package/src/grid/plugins/ValueStackAxis.ts +35 -336
  51. package/src/grid/types.ts +1 -1
  52. package/src/index.ts +1 -0
  53. package/src/multiGrid/defaults.ts +120 -14
  54. package/src/multiGrid/index.ts +9 -2
  55. package/src/multiGrid/multiGridObservables.ts +279 -0
  56. package/src/multiGrid/plugins/MultiBarStack.ts +60 -0
  57. package/src/multiGrid/plugins/MultiBars.ts +59 -0
  58. package/src/multiGrid/plugins/MultiBarsTriangle.ts +58 -0
  59. package/src/multiGrid/plugins/MultiDots.ts +58 -0
  60. package/src/multiGrid/plugins/MultiGridLegend.ts +2 -7
  61. package/src/multiGrid/plugins/MultiGroupAxis.ts +53 -0
  62. package/src/multiGrid/plugins/MultiLines.ts +58 -0
  63. package/src/multiGrid/plugins/MultiValueAxis.ts +53 -0
  64. package/src/multiGrid/plugins/OverlappingValueAxes.ts +165 -0
  65. package/src/multiGrid/types.ts +39 -0
  66. package/tsconfig.dev.json +17 -0
  67. package/tsconfig.prod.json +14 -0
  68. package/vite.config.js +5 -0
  69. package/dist/src/grid/plugins/GroupArea.d.ts +0 -3
  70. package/dist/src/multiGrid/plugins/BarsAndLines.d.ts +0 -1
  71. package/dist/src/multiGrid/plugins/FirstGroupScaleAxis.d.ts +0 -0
  72. package/dist/src/multiGrid/plugins/TwoValueScaleAxes.d.ts +0 -0
  73. package/src/multiGrid/plugins/BarStackAndLines.ts +0 -0
  74. package/src/multiGrid/plugins/BarsAndLines.ts +0 -126
  75. package/src/multiGrid/plugins/BarsTriangleAndLines.ts +0 -0
  76. package/src/multiGrid/plugins/FirstGroupScaleAxis.ts +0 -0
  77. package/src/multiGrid/plugins/TwoValueScaleAxes.ts +0 -0
  78. /package/dist/src/{multiGrid/plugins/BarStackAndLines.d.ts → base/BaseGroupArea.d.ts} +0 -0
  79. /package/{dist/src/multiGrid/plugins/BarsTriangleAndLines.d.ts → src/base/BaseGroupArea.ts} +0 -0
@@ -1,356 +1,32 @@
1
- import * as d3 from 'd3'
2
1
  import {
3
- combineLatest,
4
- switchMap,
5
- distinctUntilChanged,
6
- first,
7
- map,
8
- takeUntil,
9
- Observable,
10
2
  Subject } from 'rxjs'
11
3
  import {
12
4
  defineGridPlugin } from '@orbcharts/core'
13
- import { createAxisLinearScale } from '@orbcharts/core'
14
- import type {
15
- DataFormatterGrid,
16
- ChartParams,
17
- TransformData } from '@orbcharts/core'
18
- import type { ValueAxisParams } from '../types'
19
5
  import { DEFAULT_VALUE_AXIS_PARAMS } from '../defaults'
20
- import { parseTickFormatValue } from '../../utils/d3Utils'
21
- import { getColor, getMinAndMaxValue, getClassName, getUniID } from '../../utils/orbchartsUtils'
22
6
 
23
- interface TextAlign {
24
- textAnchor: "start" | "middle" | "end"
25
- dominantBaseline: "middle" | "auto" | "hanging"
26
- }
7
+ import { createBaseValueAxis } from '../../base/BaseValueAxis'
27
8
 
28
9
  const pluginName = 'ValueAxis'
29
- const gClassName = getClassName(pluginName, 'g')
30
- const textClassName = getClassName(pluginName, 'text')
31
- const defaultTickSize = 6
32
-
33
- function renderLinearAxis ({ selection, fullParams, tickTextAlign, axisLabelAlign, gridAxesSize, fullDataFormatter, fullChartParams, valueScale, contentTransform, minAndMax }: {
34
- selection: d3.Selection<SVGGElement, any, any, any>,
35
- fullParams: ValueAxisParams
36
- tickTextAlign: TextAlign
37
- axisLabelAlign: TextAlign
38
- gridAxesSize: { width: number, height: number }
39
- fullDataFormatter: DataFormatterGrid,
40
- fullChartParams: ChartParams
41
- valueScale: d3.ScaleLinear<number, number>
42
- contentTransform: string,
43
- minAndMax: [number, number]
44
- }) {
45
-
46
- const yAxisSelection = selection
47
- .selectAll<SVGGElement, ValueAxisParams>(`g.${gClassName}`)
48
- .data([fullParams])
49
- .join('g')
50
- .classed(gClassName, true)
51
-
52
- const axisLabelSelection = selection
53
- .selectAll<SVGGElement, ValueAxisParams>(`g.${textClassName}`)
54
- .data([fullParams])
55
- .join('g')
56
- .classed(textClassName, true)
57
- .each((d, i, g) => {
58
- const text = d3.select(g[i])
59
- .selectAll<SVGTextElement, ValueAxisParams>(`text`)
60
- .data([d])
61
- .join(
62
- enter => {
63
- return enter
64
- .append('text')
65
- .style('font-weight', 'bold')
66
- },
67
- update => update,
68
- exit => exit.remove()
69
- )
70
- .attr('text-anchor', axisLabelAlign.textAnchor)
71
- .attr('dominant-baseline', axisLabelAlign.dominantBaseline)
72
- .style('font-size', `${fullChartParams.styles.textSize}px`)
73
- .style('fill', getColor(fullParams.labelColorType, fullChartParams))
74
- .style('transform', contentTransform)
75
- .text(d => fullDataFormatter.valueAxis.label)
76
- })
77
- .attr('transform', d => `translate(${- d.tickPadding + fullParams.labelOffset[0]}, ${gridAxesSize.height + d.tickPadding + fullParams.labelOffset[1]})`)
78
-
79
- const valueLength = minAndMax[1] - minAndMax[0]
80
-
81
- // 設定Y軸刻度
82
- const yAxis = d3.axisLeft(valueScale)
83
- .scale(valueScale)
84
- .ticks(valueLength > fullParams.ticks
85
- ? fullParams.ticks
86
- : ((minAndMax[0] === 0 && minAndMax[1] === 0)
87
- ? 1
88
- : Math.ceil(valueLength))) // 刻度分段數量
89
- .tickFormat(d => parseTickFormatValue(d, fullParams.tickFormat))
90
- .tickSize(fullParams.tickFullLine == true
91
- ? -gridAxesSize.width
92
- : defaultTickSize)
93
- .tickPadding(fullParams.tickPadding)
94
-
95
- const yAxisEl = yAxisSelection
96
- .transition()
97
- .duration(100)
98
- .call(yAxis)
99
-
100
- yAxisEl.selectAll('line')
101
- .style('fill', 'none')
102
- .style('stroke', fullParams.tickLineVisible == true ? getColor(fullParams.tickColorType, fullChartParams) : 'none')
103
- .style('stroke-dasharray', fullParams.tickFullLineDasharray)
104
- .attr('pointer-events', 'none')
105
-
106
- yAxisEl.selectAll('path')
107
- .style('fill', 'none')
108
- // .style('stroke', this.fullParams.axisLineColor!)
109
- .style('stroke', fullParams.axisLineVisible == true ? getColor(fullParams.axisLineColorType, fullChartParams) : 'none')
110
- .style('shape-rendering', 'crispEdges')
111
-
112
- // const yText = yAxisEl.selectAll('text')
113
- const yText = yAxisSelection.selectAll('text')
114
- .style('font-family', 'sans-serif')
115
- .style('font-size', `${fullChartParams.styles.textSize}px`)
116
- .style('color', getColor(fullParams.tickTextColorType, fullChartParams))
117
- .attr('text-anchor', tickTextAlign.textAnchor)
118
- .attr('dominant-baseline', tickTextAlign.dominantBaseline)
119
- .attr('transform-origin', `-${fullParams.tickPadding + defaultTickSize} 0`)
120
- yText.style('transform', contentTransform)
121
-
122
- return yAxisSelection
123
- }
124
-
125
10
 
126
11
  export const ValueAxis = defineGridPlugin(pluginName, DEFAULT_VALUE_AXIS_PARAMS)(({ selection, name, observer, subject }) => {
127
12
 
128
13
  const destroy$ = new Subject()
129
14
 
130
- // const axisGUpdate = selection
131
- // .selectAll('g')
132
- // .data()
133
-
134
- const axisSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
135
- // let graphicSelection: d3.Selection<SVGGElement, any, any, any> | undefined
136
- // let pathSelection: d3.Selection<SVGPathElement, ComputedDatumGrid[], any, any> | undefined
137
- // .style('transform', 'translate(0px, 0px) scale(1)')
138
-
139
- observer.gridAxesTransform$
140
- .pipe(
141
- takeUntil(destroy$),
142
- map(d => d.value),
143
- distinctUntilChanged()
144
- ).subscribe(d => {
145
- axisSelection
146
- .style('transform', d)
147
- .attr('opacity', 0)
148
- .transition()
149
- .attr('opacity', 1)
150
- })
151
-
152
- // const gridAxesSize$ = gridAxisSizeObservable({
153
- // fullDataFormatter$,
154
- // layout$
155
- // })
156
-
157
- // const contentTransform$: Observable<string> = new Observable(subscriber => {
158
- // combineLatest({
159
- // fullParams: fullParams$,
160
- // layout: layout$
161
- // }).pipe(
162
- // takeUntil(destroy$),
163
- // // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
164
- // switchMap(async (d) => d),
165
- // ).subscribe(data => {
166
-
167
- // const transformData = Object.assign({}, data.layout.content.axesTransformData)
168
-
169
- // const value = getAxesTransformValue({
170
- // translate: [0, 0],
171
- // scale: [transformData.scale[0] * -1, transformData.scale[1] * -1],
172
- // rotate: transformData.rotate * -1 + data.fullParams.tickTextRotate,
173
- // rotateX: transformData.rotateX * -1,
174
- // rotateY: transformData.rotateY * -1
175
- // })
176
-
177
- // subscriber.next(value)
178
- // })
179
- // })
180
- // const oppositeTransform$: Observable<TransformData> = observer.gridAxesTransform$.pipe(
181
- // takeUntil(destroy$),
182
- // map(d => {
183
- // const translate: [number, number] = [d.translate[0] * -1, d.translate[1] * -1]
184
- // const scale: [number, number] = [d.scale[0] * -1, d.scale[1] * -1]
185
- // const rotate = d.rotate * -1
186
- // const rotateX = d.rotateX * -1
187
- // const rotateY = d.rotateY * -1
188
- // return {
189
- // translate,
190
- // scale,
191
- // rotate,
192
- // rotateX,
193
- // rotateY,
194
- // value: ''
195
- // }
196
- // }),
197
- // )
198
- const contentTransform$ = combineLatest({
199
- fullParams: observer.fullParams$,
200
- gridAxesOppositeTransform: observer.gridAxesOppositeTransform$
201
- }).pipe(
202
- takeUntil(destroy$),
203
- switchMap(async data => {
204
- const rotate = data.gridAxesOppositeTransform.rotate + data.fullParams.tickTextRotate
205
- return `translate(${data.gridAxesOppositeTransform.translate[0]}px, ${data.gridAxesOppositeTransform.translate[1]}px) rotate(${rotate}deg) rotateX(${data.gridAxesOppositeTransform.rotateX}deg) rotateY(${data.gridAxesOppositeTransform.rotateY}deg)`
206
- }),
207
- distinctUntilChanged()
208
- )
209
-
210
- const minAndMax$: Observable<[number, number]> = new Observable(subscriber => {
211
- combineLatest({
212
- fullDataFormatter: observer.fullDataFormatter$,
213
- gridAxesSize: observer.gridAxesSize$,
214
- computedData: observer.computedData$
215
- }).pipe(
216
- takeUntil(destroy$),
217
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
218
- switchMap(async (d) => d),
219
- ).subscribe(data => {
220
- const groupMin = 0
221
- const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
222
- const groupScaleDomainMin = data.fullDataFormatter.groupAxis.scaleDomain[0] === 'auto'
223
- ? groupMin - data.fullDataFormatter.groupAxis.scalePadding
224
- : data.fullDataFormatter.groupAxis.scaleDomain[0] as number - data.fullDataFormatter.groupAxis.scalePadding
225
- const groupScaleDomainMax = data.fullDataFormatter.groupAxis.scaleDomain[1] === 'auto'
226
- ? groupMax + data.fullDataFormatter.groupAxis.scalePadding
227
- : data.fullDataFormatter.groupAxis.scaleDomain[1] as number + data.fullDataFormatter.groupAxis.scalePadding
228
-
229
- const filteredData = data.computedData.map((d, i) => {
230
- return d.filter((_d, _i) => {
231
- return _i >= groupScaleDomainMin && _i <= groupScaleDomainMax
232
- })
233
- })
234
-
235
- const filteredMinAndMax = getMinAndMaxValue(filteredData.flat())
236
-
237
- subscriber.next(filteredMinAndMax)
238
- })
239
- })
240
-
241
- const valueScale$: Observable<d3.ScaleLinear<number, number>> = new Observable(subscriber => {
242
- combineLatest({
243
- fullDataFormatter: observer.fullDataFormatter$,
244
- gridAxesSize: observer.gridAxesSize$,
245
- minAndMax: minAndMax$
246
- }).pipe(
247
- takeUntil(destroy$),
248
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
249
- switchMap(async (d) => d),
250
- ).subscribe(data => {
251
-
252
- const valueScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
253
- maxValue: data.minAndMax[1],
254
- minValue: data.minAndMax[0],
255
- axisWidth: data.gridAxesSize.height,
256
- scaleDomain: data.fullDataFormatter.valueAxis.scaleDomain,
257
- scaleRange: data.fullDataFormatter.valueAxis.scaleRange
258
- })
259
-
260
- subscriber.next(valueScale)
261
- })
262
- })
263
-
264
- const tickTextAlign$: Observable<TextAlign> = observer.fullDataFormatter$.pipe(
265
- takeUntil(destroy$),
266
- map(d => {
267
- let textAnchor: 'start' | 'middle' | 'end' = 'start'
268
- let dominantBaseline: 'auto' | 'middle' | 'hanging' = 'hanging'
269
-
270
- if (d.valueAxis.position === 'left') {
271
- textAnchor = 'end'
272
- dominantBaseline = 'middle'
273
- } else if (d.valueAxis.position === 'right') {
274
- textAnchor = 'start'
275
- dominantBaseline = 'middle'
276
- } else if (d.valueAxis.position === 'bottom') {
277
- textAnchor = 'middle'
278
- dominantBaseline = 'hanging'
279
- } else if (d.valueAxis.position === 'top') {
280
- textAnchor = 'middle'
281
- dominantBaseline = 'auto'
282
- }
283
- return {
284
- textAnchor,
285
- dominantBaseline
286
- }
287
- })
288
- )
289
-
290
- const axisLabelAlign$: Observable<TextAlign> = observer.fullDataFormatter$.pipe(
291
- takeUntil(destroy$),
292
- map(d => {
293
- let textAnchor: 'start' | 'middle' | 'end' = 'start'
294
- let dominantBaseline: 'auto' | 'middle' | 'hanging' = 'hanging'
295
-
296
- if (d.groupAxis.position === 'bottom') {
297
- dominantBaseline = 'auto'
298
- } else if (d.groupAxis.position === 'top') {
299
- dominantBaseline = 'hanging'
300
- } else if (d.groupAxis.position === 'left') {
301
- textAnchor = 'start'
302
- } else if (d.groupAxis.position === 'right') {
303
- textAnchor = 'end'
304
- }
305
- if (d.valueAxis.position === 'left') {
306
- textAnchor = 'end'
307
- } else if (d.valueAxis.position === 'right') {
308
- textAnchor = 'start'
309
- } else if (d.valueAxis.position === 'bottom') {
310
- dominantBaseline = 'hanging'
311
- } else if (d.valueAxis.position === 'top') {
312
- dominantBaseline = 'auto'
313
- }
314
- return {
315
- textAnchor,
316
- dominantBaseline
317
- }
318
- })
319
- )
320
-
321
-
322
- combineLatest({
323
- fullParams: observer.fullParams$,
324
- tickTextAlign: tickTextAlign$,
325
- axisLabelAlign: axisLabelAlign$,
326
- computedData: observer.computedData$,
327
- gridAxesSize: observer.gridAxesSize$,
328
- fullDataFormatter: observer.fullDataFormatter$,
329
- fullChartParams: observer.fullChartParams$,
330
- valueScale: valueScale$,
331
- contentTransform: contentTransform$,
332
- minAndMax: minAndMax$
333
- }).pipe(
334
- takeUntil(destroy$),
335
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
336
- switchMap(async (d) => d),
337
- ).subscribe(data => {
338
-
339
- renderLinearAxis({
340
- selection: axisSelection,
341
- fullParams: data.fullParams,
342
- tickTextAlign: data.tickTextAlign,
343
- axisLabelAlign: data.axisLabelAlign,
344
- gridAxesSize: data.gridAxesSize,
345
- fullDataFormatter: data.fullDataFormatter,
346
- fullChartParams: data.fullChartParams,
347
- valueScale: data.valueScale,
348
- contentTransform: data.contentTransform,
349
- minAndMax: data.minAndMax
350
- })
15
+ const unsubscribeBaseValueAxis = createBaseValueAxis(pluginName, {
16
+ selection,
17
+ computedData$: observer.computedData$,
18
+ fullParams$: observer.fullParams$,
19
+ fullDataFormatter$: observer.fullDataFormatter$,
20
+ fullChartParams$: observer.fullChartParams$,
21
+ gridAxesTransform$: observer.gridAxesTransform$,
22
+ gridAxesReverseTransform$: observer.gridAxesReverseTransform$,
23
+ gridAxesSize$: observer.gridAxesSize$,
24
+ gridContainer$: observer.gridContainer$,
25
+ isSeriesPositionSeprate$: observer.isSeriesPositionSeprate$,
351
26
  })
352
27
 
353
28
  return () => {
354
29
  destroy$.next(undefined)
30
+ unsubscribeBaseValueAxis()
355
31
  }
356
32
  })