@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
@@ -11,12 +11,14 @@ import type { BasePluginFn } from './types'
11
11
  import type {
12
12
  ComputedDatumGrid,
13
13
  ComputedDataGrid,
14
+ ContainerPosition,
14
15
  EventGrid,
15
16
  ChartParams,
16
17
  Layout,
17
18
  TransformData } from '@orbcharts/core'
18
19
  import { getD3TransitionEase } from '../utils/d3Utils'
19
20
  import { getClassName, getUniID } from '../utils/orbchartsUtils'
21
+ import { gridSelectionsObservable } from '../grid/gridObservables'
20
22
 
21
23
  export interface BaseBarsParams {
22
24
  // barType: BarType
@@ -30,32 +32,38 @@ interface BaseBarsContext {
30
32
  selection: d3.Selection<any, unknown, any, unknown>
31
33
  computedData$: Observable<ComputedDataGrid>
32
34
  visibleComputedData$: Observable<ComputedDatumGrid[][]>
35
+ existedSeriesLabels$: Observable<string[]>
33
36
  SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
34
37
  GroupDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
35
38
  fullParams$: Observable<BaseBarsParams>
36
39
  fullChartParams$: Observable<ChartParams>
37
40
  gridAxesTransform$: Observable<TransformData>
38
41
  gridGraphicTransform$: Observable<TransformData>
42
+ gridGraphicReverseScale$: Observable<[number, number][]>
39
43
  gridAxesSize$: Observable<{
40
44
  width: number;
41
45
  height: number;
42
46
  }>
43
47
  gridHighlight$: Observable<string[]>
48
+ gridContainer$: Observable<ContainerPosition[]>
49
+ isSeriesPositionSeprate$: Observable<boolean>
44
50
  event$: Subject<EventGrid>
45
51
  }
46
52
 
47
53
  interface RenderBarParams {
48
- selection: d3.Selection<SVGGElement, unknown, any, any>
49
- data: ComputedDatumGrid[][]
50
- zeroY: number
54
+ graphicGSelection: d3.Selection<SVGGElement, string, any, any>
55
+ rectClassName: string
56
+ computedData: ComputedDatumGrid[][]
57
+ zeroYArr: number[]
51
58
  groupLabels: string[]
52
59
  barScale: d3.ScalePoint<string>
53
60
  params: BaseBarsParams
54
61
  chartParams: ChartParams
55
62
  barWidth: number
56
- transformedBarRadius: [number, number]
63
+ transformedBarRadius: [number, number][]
57
64
  delayGroup: number
58
65
  transitionItem: number
66
+ isSeriesPositionSeprate: boolean
59
67
  }
60
68
 
61
69
  type ClipPathDatum = {
@@ -66,9 +74,8 @@ type ClipPathDatum = {
66
74
  height: number;
67
75
  }
68
76
 
69
- const pluginName = 'Bars'
70
- const gClassName = getClassName(pluginName, 'g')
71
- const rectClassName = getClassName(pluginName, 'rect')
77
+ // const pluginName = 'Bars'
78
+ // const rectClassName = getClassName(pluginName, 'rect')
72
79
  // group的delay在動畫中的佔比(剩餘部份的時間為圖形本身的動畫時間,因為delay時間和最後一個group的動畫時間加總為1)
73
80
  const groupDelayProportionOfDuration = 0.3
74
81
 
@@ -107,50 +114,36 @@ function calctransitionItem (barGroupAmount: number, totalDuration: number) {
107
114
  }
108
115
  return totalDuration * (1 - groupDelayProportionOfDuration) // delay後剩餘的時間
109
116
  }
117
+ // let _data: ComputedDatumGrid[][] = []
118
+
119
+ function renderRectBars ({ graphicGSelection, rectClassName, computedData, zeroYArr, groupLabels, barScale, params, chartParams, barWidth, transformedBarRadius, delayGroup, transitionItem, isSeriesPositionSeprate }: RenderBarParams) {
110
120
 
111
- function renderRectBars ({ selection, data, zeroY, groupLabels, barScale, params, chartParams, barWidth, transformedBarRadius, delayGroup, transitionItem }: RenderBarParams) {
112
-
113
121
  const barHalfWidth = barWidth! / 2
114
122
 
115
- const barGroup = selection
116
- .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${gClassName}`)
117
- .data(data, (d, i) => groupLabels[i])
118
- .join(
119
- enter => {
120
- return enter
121
- .append('g')
122
- .classed(gClassName, true)
123
- .attr('cursor', 'pointer')
124
- },
125
- update => update,
126
- exit => exit.remove()
127
- )
128
- .attr('transform', (d, i) => `translate(${d[0] ? d[0].axisX : 0}, ${0})`)
129
- .each((d, i, g) => {
130
- const bars = d3.select(g[i])
131
- .selectAll<SVGRectElement, ComputedDatumGrid>('rect')
132
- .data(d, d => d.id)
123
+ graphicGSelection
124
+ .each((seriesData, seriesIndex, g) => {
125
+ d3.select(g[seriesIndex])
126
+ .selectAll<SVGGElement, ComputedDatumGrid>(`rect.${rectClassName}`)
127
+ .data(computedData[seriesIndex] ?? [], d => d.id)
133
128
  .join(
134
129
  enter => {
130
+ // console.log('enter')
135
131
  return enter
136
132
  .append('rect')
137
133
  .classed(rectClassName, true)
134
+ .attr('cursor', 'pointer')
138
135
  .attr('height', d => 0)
139
136
  },
140
137
  update => update,
141
138
  exit => exit.remove()
142
139
  )
140
+ .attr('transform', (d, i) => `translate(${(d ? d.axisX : 0) - barHalfWidth}, ${0})`)
143
141
  .attr('fill', d => d.color)
144
- .attr('y', d => d.axisY < zeroY ? d.axisY : zeroY)
145
- .attr('x', d => barScale(d.seriesLabel)!)
142
+ .attr('y', d => d.axisY < zeroYArr[seriesIndex] ? d.axisY : zeroYArr[seriesIndex])
143
+ .attr('x', d => isSeriesPositionSeprate ? 0 : barScale(d.seriesLabel)!)
146
144
  .attr('width', barWidth!)
147
- .attr('transform', `translate(${-barHalfWidth}, 0)`)
148
- // .attr('rx', params.barRadius == true ? barHalfWidth
149
- // : params.barRadius == false ? 0
150
- // : typeof params.barRadius == 'number' ? params.barRadius
151
- // : 0)
152
- .attr('rx', transformedBarRadius[0])
153
- .attr('ry', transformedBarRadius[1])
145
+ .attr('rx', transformedBarRadius[seriesIndex][0] ?? 1)
146
+ .attr('ry', transformedBarRadius[seriesIndex][1] ?? 1)
154
147
  .transition()
155
148
  .duration(transitionItem)
156
149
  .ease(getD3TransitionEase(chartParams.transitionEase))
@@ -158,7 +151,50 @@ function renderRectBars ({ selection, data, zeroY, groupLabels, barScale, params
158
151
  .attr('height', d => Math.abs(d.axisYFromZero))
159
152
  })
160
153
 
161
- const graphicBarSelection: d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown> = barGroup.selectAll(`rect.${rectClassName}`)
154
+
155
+ // graphicGSelection
156
+ // .each((d, seriesIndex, g) => {
157
+ // d3.select(g[seriesIndex])
158
+ // .selectAll<SVGGElement, ComputedDatumGrid>(`g.${barClassName}`)
159
+ // .data(computedData[seriesIndex], d => d.seriesIndex)
160
+ // .join('g')
161
+ // .classed(barClassName, true)
162
+ // .attr('transform', (d, i) => `translate(${d ? d.axisX : 0}, ${0})`)
163
+ // .each((datum, i, g) => {
164
+ // d3.select(g[i])
165
+ // .selectAll<SVGRectElement, ComputedDatumGrid>(`rect.${rectClassName}`)
166
+ // .data([computedData[seriesIndex][i]], d => d.id)
167
+ // .join(
168
+ // enter => {
169
+ // return enter
170
+ // .append('rect')
171
+ // .classed(rectClassName, true)
172
+ // .attr('height', d => 0)
173
+ // },
174
+ // update => update,
175
+ // exit => exit.remove()
176
+ // )
177
+ // .attr('cursor', 'pointer')
178
+ // .attr('fill', d => d.color)
179
+ // .attr('y', d => d.axisY < zeroYArr[seriesIndex] ? d.axisY : zeroYArr[seriesIndex])
180
+ // .attr('x', d => isSeriesPositionSeprate ? 0 : barScale(d.seriesLabel)!)
181
+ // .attr('width', barWidth!)
182
+ // .attr('transform', `translate(${-barHalfWidth}, 0)`)
183
+ // // .attr('rx', params.barRadius == true ? barHalfWidth
184
+ // // : params.barRadius == false ? 0
185
+ // // : typeof params.barRadius == 'number' ? params.barRadius
186
+ // // : 0)
187
+ // .attr('rx', transformedBarRadius[0])
188
+ // .attr('ry', transformedBarRadius[1])
189
+ // .transition()
190
+ // .duration(transitionItem)
191
+ // .ease(getD3TransitionEase(chartParams.transitionEase))
192
+ // .delay((d, i) => d.groupIndex * delayGroup)
193
+ // .attr('height', d => Math.abs(d.axisYFromZero))
194
+ // })
195
+ // })
196
+
197
+ const graphicBarSelection: d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown> = graphicGSelection.selectAll(`rect.${rectClassName}`)
162
198
 
163
199
  return graphicBarSelection
164
200
  }
@@ -231,101 +267,194 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
231
267
  selection,
232
268
  computedData$,
233
269
  visibleComputedData$,
270
+ existedSeriesLabels$,
234
271
  SeriesDataMap$,
235
272
  GroupDataMap$,
236
273
  fullParams$,
237
274
  fullChartParams$,
238
275
  gridAxesTransform$,
239
276
  gridGraphicTransform$,
277
+ gridGraphicReverseScale$,
240
278
  gridAxesSize$,
241
279
  gridHighlight$,
280
+ gridContainer$,
281
+ isSeriesPositionSeprate$,
242
282
  event$
243
283
  }) => {
244
284
 
245
285
  const destroy$ = new Subject()
246
286
 
247
287
  const clipPathID = getUniID(pluginName, 'clipPath-box')
288
+ const rectClassName = getClassName(pluginName, 'rect')
289
+
290
+ // const seriesSelection$ = computedData$.pipe(
291
+ // takeUntil(destroy$),
292
+ // distinctUntilChanged((a, b) => {
293
+ // // 只有當series的數量改變時,才重新計算
294
+ // return a.length === b.length
295
+ // }),
296
+ // map((computedData, i) => {
297
+ // return selection
298
+ // .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${seriesClassName}`)
299
+ // .data(computedData, d => d[0] ? d[0].seriesIndex : i)
300
+ // .join(
301
+ // enter => {
302
+ // return enter
303
+ // .append('g')
304
+ // .classed(seriesClassName, true)
305
+ // .each((d, i, g) => {
306
+ // const axesSelection = d3.select(g[i])
307
+ // .selectAll<SVGGElement, ComputedDatumGrid[]>(`g.${axesClassName}`)
308
+ // .data([i])
309
+ // .join(
310
+ // enter => {
311
+ // return enter
312
+ // .append('g')
313
+ // .classed(axesClassName, true)
314
+ // .attr('clip-path', `url(#${clipPathID})`)
315
+ // .each((d, i, g) => {
316
+ // const defsSelection = d3.select(g[i])
317
+ // .selectAll<SVGDefsElement, any>('defs')
318
+ // .data([i])
319
+ // .join('defs')
320
+
321
+ // const graphicGSelection = d3.select(g[i])
322
+ // .selectAll<SVGGElement, any>('g')
323
+ // .data([i])
324
+ // .join('g')
325
+ // .classed(graphicClassName, true)
326
+ // })
327
+ // },
328
+ // update => update,
329
+ // exit => exit.remove()
330
+ // )
331
+ // })
332
+ // },
333
+ // update => update,
334
+ // exit => exit.remove()
335
+ // )
336
+ // })
337
+ // )
248
338
 
249
- const axesSelection: d3.Selection<SVGGElement, any, any, any> = selection
250
- .append('g')
251
- .attr('clip-path', `url(#${clipPathID})`)
252
- const defsSelection: d3.Selection<SVGDefsElement, ComputedDatumGrid, any, any> = axesSelection.append('defs')
253
- const graphicGSelection: d3.Selection<SVGGElement, any, any, any> = axesSelection.append('g')
254
- const barSelection$: Subject<d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown>> = new Subject()
255
-
256
- gridAxesTransform$
257
- .pipe(
258
- takeUntil(destroy$),
259
- map(d => d.value),
260
- distinctUntilChanged()
261
- ).subscribe(d => {
262
- axesSelection
263
- .style('transform', d)
264
- })
339
+ // combineLatest({
340
+ // seriesSelection: seriesSelection$,
341
+ // gridContainer: gridContainer$
342
+ // }).pipe(
343
+ // takeUntil(destroy$),
344
+ // switchMap(async d => d)
345
+ // ).subscribe(data => {
346
+ // data.seriesSelection
347
+ // .transition()
348
+ // .attr('transform', (d, i) => {
349
+ // const translate = data.gridContainer[i].translate
350
+ // const scale = data.gridContainer[i].scale
351
+ // return `translate(${translate[0]}, ${translate[1]}) scale(${scale[0]}, ${scale[1]})`
352
+ // })
353
+ // })
265
354
 
266
- gridGraphicTransform$
267
- .pipe(
268
- takeUntil(destroy$),
269
- map(d => d.value),
270
- distinctUntilChanged()
271
- ).subscribe(d => {
272
- graphicGSelection
273
- .transition()
274
- .duration(50)
275
- .style('transform', d)
276
- })
277
355
 
278
- // const visibleComputedData$ = computedData$.pipe(
356
+ // const axesSelection$ = combineLatest({
357
+ // seriesSelection: seriesSelection$,
358
+ // gridAxesTransform: gridAxesTransform$
359
+ // }).pipe(
279
360
  // takeUntil(destroy$),
361
+ // switchMap(async d => d),
280
362
  // map(data => {
281
- // const visibleComputedData = data
282
- // .map(d => {
283
- // return d.filter(_d => {
284
- // return _d.visible == true
285
- // })
286
- // })
287
- // .filter(d => d.length)
288
- // return visibleComputedData
363
+ // return data.seriesSelection
364
+ // .select<SVGGElement>(`g.${axesClassName}`)
365
+ // .style('transform', data.gridAxesTransform.value)
366
+ // })
367
+ // )
368
+ // const defsSelection$ = axesSelection$.pipe(
369
+ // takeUntil(destroy$),
370
+ // map(axesSelection => {
371
+ // return axesSelection.select<SVGDefsElement>('defs')
372
+ // })
373
+ // )
374
+ // const graphicGSelection$ = combineLatest({
375
+ // axesSelection: axesSelection$,
376
+ // gridGraphicTransform: gridGraphicTransform$
377
+ // }).pipe(
378
+ // takeUntil(destroy$),
379
+ // switchMap(async d => d),
380
+ // map(data => {
381
+ // const graphicGSelection = data.axesSelection
382
+ // .select<SVGGElement>(`g.${graphicClassName}`)
383
+ // graphicGSelection
384
+ // .transition()
385
+ // .duration(50)
386
+ // .style('transform', data.gridGraphicTransform.value)
387
+ // return graphicGSelection
289
388
  // })
290
389
  // )
291
390
 
292
- const zeroY$ = visibleComputedData$.pipe(
293
- map(d => d[0] && d[0][0]
294
- ? d[0][0].axisY - d[0][0].axisYFromZero
295
- : 0),
391
+ const {
392
+ seriesSelection$,
393
+ axesSelection$,
394
+ defsSelection$,
395
+ graphicGSelection$
396
+ } = gridSelectionsObservable({
397
+ selection,
398
+ pluginName,
399
+ clipPathID,
400
+ existedSeriesLabels$,
401
+ gridContainer$,
402
+ gridAxesTransform$,
403
+ gridGraphicTransform$
404
+ })
405
+
406
+ const zeroYArr$ = visibleComputedData$.pipe(
407
+ takeUntil(destroy$),
408
+ map(data => {
409
+ return data.map(d => {
410
+ return d[0] ? d[0].axisY - d[0].axisYFromZero : 0
411
+ })
412
+ }),
296
413
  distinctUntilChanged()
297
414
  )
298
415
 
299
- const barWidth$ = new Observable<number>(subscriber => {
300
- combineLatest({
301
- computedData: computedData$,
302
- visibleComputedData: visibleComputedData$,
303
- params: fullParams$,
304
- gridAxesSize: gridAxesSize$
305
- }).pipe(
306
- switchMap(async d => d)
307
- ).subscribe(data => {
308
- const barWidth = data.params.barWidth
309
- ? data.params.barWidth
310
- : calcBarWidth({
311
- axisWidth: data.gridAxesSize.width,
312
- groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
313
- barAmountOfGroup: data.visibleComputedData.length,
314
- barPadding: data.params.barPadding,
315
- barGroupPadding: data.params.barGroupPadding
316
- })
317
- subscriber.next(barWidth)
318
- })
416
+ const barWidth$ = combineLatest({
417
+ computedData: computedData$,
418
+ visibleComputedData: visibleComputedData$,
419
+ params: fullParams$,
420
+ gridAxesSize: gridAxesSize$,
421
+ isSeriesPositionSeprate: isSeriesPositionSeprate$
319
422
  }).pipe(
320
423
  takeUntil(destroy$),
424
+ switchMap(async d => d),
425
+ map(data => {
426
+ if (data.params.barWidth) {
427
+ return data.params.barWidth
428
+ } else if (data.isSeriesPositionSeprate) {
429
+ return calcBarWidth({
430
+ axisWidth: data.gridAxesSize.width,
431
+ groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
432
+ barAmountOfGroup: 1,
433
+ barPadding: data.params.barPadding,
434
+ barGroupPadding: data.params.barGroupPadding
435
+ })
436
+ } else {
437
+ return calcBarWidth({
438
+ axisWidth: data.gridAxesSize.width,
439
+ groupAmount: data.computedData[0] ? data.computedData[0].length : 0,
440
+ barAmountOfGroup: data.visibleComputedData.length,
441
+ barPadding: data.params.barPadding,
442
+ barGroupPadding: data.params.barGroupPadding
443
+ })
444
+ }
445
+ }),
321
446
  distinctUntilChanged()
322
447
  )
323
448
 
324
449
  // 圓角的值 [rx, ry]
325
- const transformedBarRadius$: Observable<[number, number]> = combineLatest({
326
- gridGraphicTransform: gridGraphicTransform$,
450
+ const transformedBarRadius$: Observable<[number, number][]> = combineLatest({
451
+ computedData: computedData$,
452
+ // gridGraphicTransform: gridGraphicTransform$,
327
453
  barWidth: barWidth$,
328
- params: fullParams$
454
+ params: fullParams$,
455
+ // gridContainer: gridContainer$,
456
+ // gridAxesTransform: gridAxesTransform$
457
+ gridGraphicReverseScale: gridGraphicReverseScale$
329
458
  }).pipe(
330
459
  takeUntil(destroy$),
331
460
  switchMap(async data => data),
@@ -335,24 +464,44 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
335
464
  : data.params.barRadius === false ? 0
336
465
  : typeof data.params.barRadius == 'number' ? data.params.barRadius
337
466
  : 0
338
- const transformedRx = radius == 0
339
- ? 0
340
- : radius / data.gridGraphicTransform.scale[0] // 反向外層scale的變型
341
- const transformedRy = radius == 0
342
- ? 0
343
- : radius / data.gridGraphicTransform.scale[1]
344
- return [transformedRx, transformedRy]
467
+
468
+ return data.computedData.map((series, seriesIndex) => {
469
+ const gridGraphicReverseScale = data.gridGraphicReverseScale[seriesIndex] ?? data.gridGraphicReverseScale[0]
470
+
471
+ let transformedRx = radius * gridGraphicReverseScale[0]
472
+ let transformedRy = radius * gridGraphicReverseScale[1]
473
+ // if (radius == 0) {
474
+ // transformedRx = 0
475
+ // transformedRy = 0
476
+ // } else if (data.gridAxesTransform.rotate == 0) {
477
+ // transformedRx = radius
478
+ // // 抵消外層scale的變型
479
+ // / data.gridGraphicTransform.scale[0] / data.gridContainer[0].scale[0]
480
+ // transformedRy = radius
481
+ // // 抵消外層scale的變型
482
+ // / data.gridGraphicTransform.scale[1] / data.gridContainer[0].scale[1]
483
+ // } else if (data.gridAxesTransform.rotate != 0) {
484
+ // transformedRx = radius
485
+ // // 抵消外層scale的變型,由於有90度的旋轉,所以外層 (container) x和y的scale要互換
486
+ // / data.gridGraphicTransform.scale[0] / data.gridContainer[0].scale[1]
487
+ // transformedRy = radius
488
+ // // 抵消外層scale的變型,由於有90度的旋轉,所以外層 (container) x和y的scale要互換
489
+ // / data.gridGraphicTransform.scale[1] / data.gridContainer[0].scale[0]
490
+ // }
491
+
492
+ // 如果計算出來的x圓角值大於寬度一半則進行修正
493
+ if (transformedRx > barHalfWidth) {
494
+ const rScale = barHalfWidth / transformedRx
495
+ transformedRx = transformedRx * rScale
496
+ transformedRy = transformedRy * rScale
497
+ }
498
+
499
+ return [transformedRx, transformedRy]
500
+ })
345
501
  })
346
502
  )
347
503
 
348
- // const SeriesDataMap$ = visibleComputedData$.pipe(
349
- // map(d => makeGridSeriesDataMap(d))
350
- // )
351
-
352
- // const GroupDataMap$ = visibleComputedData$.pipe(
353
- // map(d => makeGridGroupDataMap(d))
354
- // )
355
-
504
+
356
505
  const seriesLabels$ = visibleComputedData$.pipe(
357
506
  takeUntil(destroy$),
358
507
  map(data => {
@@ -379,20 +528,18 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
379
528
  })
380
529
  )
381
530
 
382
- const barScale$: Observable<d3.ScalePoint<string>> = new Observable(subscriber => {
383
- combineLatest({
384
- seriesLabels: seriesLabels$,
385
- barWidth: barWidth$,
386
- params: fullParams$,
387
- }).pipe(
388
- takeUntil(destroy$),
389
- switchMap(async d => d)
390
- ).subscribe(data => {
391
- const barScale = makeBarScale(data.barWidth, data.seriesLabels, data.params)
392
- subscriber.next(barScale)
531
+ const barScale$ = combineLatest({
532
+ seriesLabels: seriesLabels$,
533
+ barWidth: barWidth$,
534
+ params: fullParams$,
535
+ }).pipe(
536
+ takeUntil(destroy$),
537
+ switchMap(async d => d),
538
+ map(data => {
539
+ return makeBarScale(data.barWidth, data.seriesLabels, data.params)
393
540
  })
394
- })
395
-
541
+ )
542
+
396
543
  const transitionDuration$ = fullChartParams$.pipe(
397
544
  takeUntil(destroy$),
398
545
  map(d => d.transitionDuration),
@@ -429,51 +576,24 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
429
576
  distinctUntilChanged()
430
577
  )
431
578
 
432
- const barData$ = visibleComputedData$.pipe(
579
+ combineLatest({
580
+ defsSelection: defsSelection$,
581
+ gridAxesSize: gridAxesSize$,
582
+ }).pipe(
433
583
  takeUntil(destroy$),
434
- map(data => {
435
- // 取得原始陣列的維度
436
- const rows = data.length;
437
- const cols = data.reduce((prev, current) => {
438
- return Math.max(prev, current.length)
439
- }, 0)
440
-
441
- // 初始化轉換後的陣列
442
- const transposedArray = new Array(cols).fill(null).map(() => new Array(rows).fill(null))
443
-
444
- // 遍歷原始陣列,進行轉換
445
- for (let i = 0; i < rows; i++) {
446
- for (let j = 0; j < cols; j++) {
447
- transposedArray[j][i] = data[i][j]
448
- }
449
- }
450
- // console.log('transposedArray', transposedArray)
451
- return transposedArray
452
- })
453
- )
454
-
455
- gridAxesSize$.pipe(
456
- takeUntil(destroy$)
584
+ switchMap(async d => d)
457
585
  ).subscribe(data => {
458
586
  const clipPathData = [{
459
587
  id: clipPathID,
460
- width: data.width,
461
- height: data.height
588
+ width: data.gridAxesSize.width,
589
+ height: data.gridAxesSize.height
462
590
  }]
463
591
  renderClipPath({
464
- defsSelection,
592
+ defsSelection: data.defsSelection,
465
593
  clipPathData
466
594
  })
467
595
  })
468
596
 
469
- // const renderBarsFn$ = fullParams$.pipe(
470
- // takeUntil(destroy$),
471
- // map(d => d.barType === 'rect'
472
- // ? renderRectBars
473
- // : d.barType === 'triangle'
474
- // ? renderTriangleBars
475
- // : renderRectBars),
476
- // )
477
597
 
478
598
  const highlightTarget$ = fullChartParams$.pipe(
479
599
  takeUntil(destroy$),
@@ -481,11 +601,13 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
481
601
  distinctUntilChanged()
482
602
  )
483
603
 
604
+ const barSelection$ = new Subject<d3.Selection<SVGRectElement, ComputedDatumGrid, SVGGElement, unknown>>()
605
+
484
606
  combineLatest({
485
- // renderBarsFn: renderBarsFn$,
607
+ graphicGSelection: graphicGSelection$,
486
608
  computedData: computedData$,
487
- barData$: barData$,
488
- zeroY: zeroY$,
609
+ // barData$: barData$,
610
+ zeroYArr: zeroYArr$,
489
611
  groupLabels: groupLabels$,
490
612
  barScale: barScale$,
491
613
  params: fullParams$,
@@ -496,17 +618,18 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
496
618
  delayGroup: delayGroup$,
497
619
  transitionItem: transitionItem$,
498
620
  SeriesDataMap: SeriesDataMap$,
499
- GroupDataMap: GroupDataMap$
621
+ GroupDataMap: GroupDataMap$,
622
+ isSeriesPositionSeprate: isSeriesPositionSeprate$
500
623
  }).pipe(
501
624
  takeUntil(destroy$),
502
- // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
503
625
  switchMap(async (d) => d),
504
626
  ).subscribe(data => {
505
627
 
506
628
  const barSelection = renderRectBars({
507
- selection: graphicGSelection,
508
- data: data.barData$,
509
- zeroY: data.zeroY,
629
+ graphicGSelection: data.graphicGSelection,
630
+ rectClassName,
631
+ computedData: data.computedData,
632
+ zeroYArr: data.zeroYArr,
510
633
  groupLabels: data.groupLabels,
511
634
  barScale: data.barScale,
512
635
  params: data.params,
@@ -514,7 +637,8 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
514
637
  barWidth: data.barWidth,
515
638
  transformedBarRadius: data.transformedBarRadius,
516
639
  delayGroup: data.delayGroup,
517
- transitionItem: data.transitionItem
640
+ transitionItem: data.transitionItem,
641
+ isSeriesPositionSeprate: data.isSeriesPositionSeprate
518
642
  })
519
643
 
520
644
  barSelection!
@@ -598,24 +722,6 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
598
722
  barSelection$.next(barSelection!)
599
723
  })
600
724
 
601
- // combineLatest({
602
- // barSelection: barSelection$,
603
- // chartParams: fullChartParams$,
604
- // barData$: barData$,
605
- // }).pipe(
606
- // takeUntil(destroy$),
607
- // switchMap(async d => d)
608
- // ).subscribe(data => {
609
- // const ids = getGridHighlightIds(data.barData$, data.chartParams.highlightDefault)
610
- // highlight(data.barSelection, ids)
611
- // })
612
-
613
- // const datumList$ = computedData$.pipe(
614
- // takeUntil(destroy$),
615
- // map(d => d.flat())
616
- // )
617
- // const highlight$ = highlightObservable({ datumList$, fullChartParams$, event$: subject.event$ })
618
- const highlightSubscription = gridHighlight$.subscribe()
619
725
 
620
726
  combineLatest({
621
727
  barSelection: barSelection$,
@@ -632,8 +738,8 @@ export const createBaseBars: BasePluginFn<BaseBarsContext> = (pluginName: string
632
738
  })
633
739
  })
634
740
 
741
+
635
742
  return () => {
636
743
  destroy$.next(undefined)
637
- highlightSubscription.unsubscribe()
638
744
  }
639
745
  }