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

Sign up to get free protection for your applications and to get access to all the features.
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
  }