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

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.
Files changed (80) hide show
  1. package/dist/orbcharts-plugins-basic.es.js +10246 -9523
  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 +33 -0
  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/Dots.d.ts +1 -3
  14. package/dist/src/grid/plugins/GroupAux.d.ts +3 -0
  15. package/dist/src/grid/plugins/GroupAxis.d.ts +1 -3
  16. package/dist/src/grid/plugins/ValueAxis.d.ts +1 -3
  17. package/dist/src/grid/plugins/ValueStackAxis.d.ts +1 -3
  18. package/dist/src/grid/types.d.ts +1 -1
  19. package/dist/src/multiGrid/defaults.d.ts +9 -2
  20. package/dist/src/multiGrid/index.d.ts +8 -1
  21. package/dist/src/multiGrid/multiGridObservables.d.ts +12 -0
  22. package/dist/src/multiGrid/plugins/MultiBarStack.d.ts +1 -0
  23. package/dist/src/multiGrid/plugins/MultiBars.d.ts +1 -0
  24. package/dist/src/multiGrid/plugins/MultiBarsTriangle.d.ts +1 -0
  25. package/dist/src/multiGrid/plugins/MultiDots.d.ts +1 -0
  26. package/dist/src/multiGrid/plugins/MultiGroupAxis.d.ts +1 -0
  27. package/dist/src/multiGrid/plugins/MultiLines.d.ts +1 -0
  28. package/dist/src/multiGrid/plugins/MultiValueAxis.d.ts +1 -0
  29. package/dist/src/multiGrid/plugins/OverlappingValueAxes.d.ts +1 -0
  30. package/dist/src/multiGrid/types.d.ts +31 -0
  31. package/package.json +2 -2
  32. package/src/base/BaseBarStack.ts +375 -198
  33. package/src/base/BaseBars.ts +297 -191
  34. package/src/base/BaseBarsTriangle.ts +344 -229
  35. package/src/base/BaseDots.ts +634 -0
  36. package/src/base/BaseGroupAxis.ts +497 -0
  37. package/src/base/BaseLines.ts +180 -50
  38. package/src/base/BaseValueAxis.ts +475 -0
  39. package/src/grid/defaults.ts +3 -3
  40. package/src/grid/gridObservables.ts +147 -14
  41. package/src/grid/index.ts +1 -1
  42. package/src/grid/plugins/BarStack.ts +4 -0
  43. package/src/grid/plugins/Bars.ts +4 -0
  44. package/src/grid/plugins/BarsTriangle.ts +4 -0
  45. package/src/grid/plugins/Dots.ts +19 -410
  46. package/src/grid/plugins/{GroupArea.ts → GroupAux.ts} +24 -24
  47. package/src/grid/plugins/GroupAxis.ts +16 -348
  48. package/src/grid/plugins/Lines.ts +2 -0
  49. package/src/grid/plugins/ScalingArea.ts +9 -6
  50. package/src/grid/plugins/ValueAxis.ts +13 -337
  51. package/src/grid/plugins/ValueStackAxis.ts +35 -336
  52. package/src/grid/types.ts +1 -1
  53. package/src/index.ts +1 -0
  54. package/src/multiGrid/defaults.ts +120 -14
  55. package/src/multiGrid/index.ts +9 -2
  56. package/src/multiGrid/multiGridObservables.ts +279 -0
  57. package/src/multiGrid/plugins/MultiBarStack.ts +60 -0
  58. package/src/multiGrid/plugins/MultiBars.ts +59 -0
  59. package/src/multiGrid/plugins/MultiBarsTriangle.ts +58 -0
  60. package/src/multiGrid/plugins/MultiDots.ts +58 -0
  61. package/src/multiGrid/plugins/MultiGridLegend.ts +9 -10
  62. package/src/multiGrid/plugins/MultiGroupAxis.ts +53 -0
  63. package/src/multiGrid/plugins/MultiLines.ts +58 -0
  64. package/src/multiGrid/plugins/MultiValueAxis.ts +53 -0
  65. package/src/multiGrid/plugins/OverlappingValueAxes.ts +165 -0
  66. package/src/multiGrid/types.ts +39 -0
  67. package/tsconfig.dev.json +17 -0
  68. package/tsconfig.prod.json +14 -0
  69. package/vite.config.js +5 -0
  70. package/dist/src/grid/plugins/GroupArea.d.ts +0 -3
  71. package/dist/src/multiGrid/plugins/BarsAndLines.d.ts +0 -1
  72. package/dist/src/multiGrid/plugins/FirstGroupScaleAxis.d.ts +0 -0
  73. package/dist/src/multiGrid/plugins/TwoValueScaleAxes.d.ts +0 -0
  74. package/src/multiGrid/plugins/BarStackAndLines.ts +0 -0
  75. package/src/multiGrid/plugins/BarsAndLines.ts +0 -126
  76. package/src/multiGrid/plugins/BarsTriangleAndLines.ts +0 -0
  77. package/src/multiGrid/plugins/FirstGroupScaleAxis.ts +0 -0
  78. package/src/multiGrid/plugins/TwoValueScaleAxes.ts +0 -0
  79. /package/dist/src/{multiGrid/plugins/BarStackAndLines.d.ts → base/BaseGroupArea.d.ts} +0 -0
  80. /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
  })