@orbcharts/plugins-basic 3.0.9 → 3.0.11

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.
@@ -151,6 +151,93 @@ function renderPie ({ selection, data, arc, pathClassName, fullParams, fullChart
151
151
  return pathSelection
152
152
  }
153
153
 
154
+ // function renderGauge ({ selection, data, arc, pathClassName, fullParams, fullChartParams, axisWidth }: {
155
+ // selection: d3.Selection<SVGGElement, unknown, any, unknown>
156
+ // data: PieDatum[]
157
+ // arc: d3.Arc<any, d3.DefaultArcObject>
158
+ // pathClassName: string
159
+ // fullParams: PieParams
160
+ // fullChartParams: ChartParams
161
+ // axisWidth: number
162
+ // }) {
163
+ // const gaugeClassName = getClassName('Gauge', 'tick')
164
+ // const gaugeLabelClassName = getClassName('Gauge', 'label')
165
+
166
+ // // 計算總角度範圍
167
+ // const totalAngle = fullParams.endAngle - fullParams.startAngle
168
+ // const totalTicks = 20 // 總刻度數量
169
+ // const tickInterval = totalAngle / totalTicks
170
+
171
+ // // 計算刻度資料
172
+ // const tickData = Array.from({ length: totalTicks + 1 }, (_, i) => {
173
+ // const angle = fullParams.startAngle + (i * tickInterval)
174
+ // const isLongTick = i % 5 === 0 // 每5格一個長線
175
+ // return {
176
+ // angle,
177
+ // isLongTick,
178
+ // value: Math.round((i / totalTicks) * 100) // 0-100的數值
179
+ // }
180
+ // })
181
+
182
+ // // 計算實際像素半徑
183
+ // const arcScale = d3.scaleLinear()
184
+ // .domain([0, 1])
185
+ // .range([0, axisWidth / 2])
186
+
187
+ // const outerRadius = arcScale(fullParams.outerRadius)
188
+ // const innerRadius = arcScale(fullParams.innerRadius)
189
+ // const longTickLength = (outerRadius - innerRadius) * 0.3
190
+ // const shortTickLength = (outerRadius - innerRadius) * 0.15
191
+
192
+ // // 繪製刻度線
193
+ // const tickSelection = selection
194
+ // .selectAll(`line.${gaugeClassName}`)
195
+ // .data(tickData)
196
+ // .join('line')
197
+ // .classed(gaugeClassName, true)
198
+ // .attr('x1', d => {
199
+ // const radius = outerRadius
200
+ // return Math.cos(d.angle - Math.PI / 2) * radius
201
+ // })
202
+ // .attr('y1', d => {
203
+ // const radius = outerRadius
204
+ // return Math.sin(d.angle - Math.PI / 2) * radius
205
+ // })
206
+ // .attr('x2', d => {
207
+ // const radius = outerRadius - (d.isLongTick ? longTickLength : shortTickLength)
208
+ // return Math.cos(d.angle - Math.PI / 2) * radius
209
+ // })
210
+ // .attr('y2', d => {
211
+ // const radius = outerRadius - (d.isLongTick ? longTickLength : shortTickLength)
212
+ // return Math.sin(d.angle - Math.PI / 2) * radius
213
+ // })
214
+ // .attr('stroke', fullChartParams.colors[fullChartParams.colorScheme].primary)
215
+ // .attr('stroke-width', d => d.isLongTick ? 2 : 1)
216
+ // .attr('stroke-linecap', 'round')
217
+
218
+ // // 繪製數字標籤(只在長線上)
219
+ // const labelSelection = selection
220
+ // .selectAll(`text.${gaugeLabelClassName}`)
221
+ // .data(tickData.filter(d => d.isLongTick))
222
+ // .join('text')
223
+ // .classed(gaugeLabelClassName, true)
224
+ // .attr('x', d => {
225
+ // const radius = outerRadius + 15 // 稍微往外一點
226
+ // return Math.cos(d.angle - Math.PI / 2) * radius
227
+ // })
228
+ // .attr('y', d => {
229
+ // const radius = outerRadius + 15
230
+ // return Math.sin(d.angle - Math.PI / 2) * radius
231
+ // })
232
+ // .attr('text-anchor', 'middle')
233
+ // .attr('dominant-baseline', 'middle')
234
+ // .attr('fill', fullChartParams.colors[fullChartParams.colorScheme].primary)
235
+ // .attr('font-size', '12px')
236
+ // .text(d => d.value)
237
+
238
+ // return { tickSelection, labelSelection }
239
+ // }
240
+
154
241
  function highlight ({ pathSelection, ids, fullChartParams, arc, arcHighlight }: {
155
242
  pathSelection: d3.Selection<SVGPathElement, PieDatum, any, any>
156
243
  ids: string[]
@@ -314,6 +401,14 @@ function createEachPie (pluginName: string, context: {
314
401
  distinctUntilChanged()
315
402
  )
316
403
 
404
+ // highlight的對象(不做成observable是因為要避免觸發監聽)
405
+ let seriesHighlight: ComputedDatumSeries[] = []
406
+ context.seriesHighlight$
407
+ .pipe(
408
+ takeUntil(destroy$)
409
+ )
410
+ .subscribe(d => seriesHighlight = d)
411
+
317
412
  const pathSelection$ = new Observable<d3.Selection<SVGPathElement, PieDatum, any, any>>(subscriber => {
318
413
  combineLatest({
319
414
  pieData: pieData$,
@@ -359,6 +454,16 @@ function createEachPie (pluginName: string, context: {
359
454
  fullParams: data.fullParams,
360
455
  fullChartParams: data.fullChartParams,
361
456
  })
457
+
458
+ // renderGauge({
459
+ // selection: context.containerSelection,
460
+ // data: tweenData,
461
+ // arc: data.arc,
462
+ // pathClassName,
463
+ // fullParams: data.fullParams,
464
+ // fullChartParams: data.fullChartParams,
465
+ // axisWidth: 500
466
+ // })
362
467
 
363
468
  // @Q@ 想盡量減清效能負擔所以取消掉
364
469
  // context.event$.next({
@@ -422,13 +527,12 @@ function createEachPie (pluginName: string, context: {
422
527
  eventName: 'transitionEnd',
423
528
  event: undefined,
424
529
  highlightTarget: data.highlightTarget,
425
- datum: null,
530
+ data: data.computedData,
426
531
  series: [],
427
532
  seriesIndex: -1,
428
533
  seriesLabel: '',
429
- data: data.computedData
534
+ datum: null
430
535
  })
431
-
432
536
 
433
537
  })
434
538
 
@@ -87,11 +87,14 @@ function renderText (
87
87
  function createTextData ({ eventData, renderFn, textAttrs, textStyles }: {
88
88
  eventData: EventSeries,
89
89
  // t: number,
90
- renderFn: (d: EventSeries) => string[] | string
90
+ renderFn: (d: EventSeries) => string[] | string | null
91
91
  textAttrs: Array<{ [key:string]: string | number }>
92
92
  textStyles: Array<{ [key:string]: string | number }>
93
- }): TextDatum[] {
94
- const callbackText = renderFn(eventData)
93
+ }): TextDatum[] | null {
94
+ const callbackText: string[] | string | null = renderFn(eventData)
95
+ if (callbackText === null) {
96
+ return null
97
+ }
95
98
  const textArr = Array.isArray(callbackText) ? callbackText : [callbackText]
96
99
  return textArr.map((d, i) => {
97
100
  return {
@@ -142,6 +145,14 @@ function createEachPieEventTexts (pluginName: string, context: {
142
145
  map(d => d.highlightTarget),
143
146
  distinctUntilChanged()
144
147
  )
148
+
149
+ // highlight的對象(不做成observable是因為要避免觸發監聽)
150
+ let seriesHighlight: ComputedDatumSeries[] = []
151
+ context.seriesHighlight$
152
+ .pipe(
153
+ takeUntil(destroy$)
154
+ )
155
+ .subscribe(d => seriesHighlight = d)
145
156
 
146
157
  combineLatest({
147
158
  computedData: context.computedData$,
@@ -151,8 +162,11 @@ function createEachPieEventTexts (pluginName: string, context: {
151
162
  }).pipe(
152
163
  takeUntil(destroy$),
153
164
  switchMap(async (d) => d),
165
+ // first()
154
166
  ).subscribe(data => {
155
167
 
168
+ // console.log('PieEventTexts data', data)
169
+
156
170
  context.containerSelection
157
171
  .transition('move')
158
172
  .duration(data.fullChartParams.transitionDuration!)
@@ -168,10 +182,10 @@ function createEachPieEventTexts (pluginName: string, context: {
168
182
  tween: t,
169
183
  highlightTarget: data.highlightTarget,
170
184
  data: data.computedData,
171
- series: [],
172
- seriesIndex: -1,
173
- seriesLabel: '',
174
- datum: null
185
+ series: seriesHighlight,
186
+ seriesIndex: seriesHighlight[0] ? seriesHighlight[0].seriesIndex : -1,
187
+ seriesLabel: seriesHighlight[0] ? seriesHighlight[0].seriesLabel : '',
188
+ datum: seriesHighlight[0] || null
175
189
  },
176
190
  // eventName: 'transitionMove',
177
191
  // t,
@@ -179,7 +193,9 @@ function createEachPieEventTexts (pluginName: string, context: {
179
193
  textAttrs: data.fullParams.textAttrs!,
180
194
  textStyles: data.fullParams.textStyles!
181
195
  })
182
- centerTextSelection = renderText(context.containerSelection, renderData)
196
+ if (renderData != null) {
197
+ centerTextSelection = renderText(context.containerSelection, renderData)
198
+ }
183
199
  }
184
200
  })
185
201
  .on('end', (event, datum) => {
@@ -192,10 +208,10 @@ function createEachPieEventTexts (pluginName: string, context: {
192
208
  tween: 1,
193
209
  highlightTarget: data.highlightTarget,
194
210
  data: data.computedData,
195
- series: [],
196
- seriesIndex: -1,
197
- seriesLabel: '',
198
- datum: null
211
+ series: seriesHighlight,
212
+ seriesIndex: seriesHighlight[0] ? seriesHighlight[0].seriesIndex : -1,
213
+ seriesLabel: seriesHighlight[0] ? seriesHighlight[0].seriesLabel : '',
214
+ datum: seriesHighlight[0] || null
199
215
  },
200
216
  // eventName: 'transitionMove',
201
217
  // t: 1,
@@ -203,8 +219,11 @@ function createEachPieEventTexts (pluginName: string, context: {
203
219
  textAttrs: data.fullParams.textAttrs!,
204
220
  textStyles: data.fullParams.textStyles!
205
221
  })
206
- centerTextSelection = renderText(context.containerSelection, renderData)
222
+ if (renderData != null) {
223
+ centerTextSelection = renderText(context.containerSelection, renderData)
224
+ }
207
225
 
226
+ // 監聽 highlight
208
227
  if (storeEventSubscription) {
209
228
  storeEventSubscription.unsubscribe()
210
229
  }
@@ -217,7 +236,9 @@ function createEachPieEventTexts (pluginName: string, context: {
217
236
  textAttrs: data.fullParams.textAttrs!,
218
237
  textStyles: data.fullParams.textStyles!
219
238
  })
220
- centerTextSelection = renderText(context.containerSelection, renderData)
239
+ if (renderData != null) {
240
+ centerTextSelection = renderText(context.containerSelection, renderData)
241
+ }
221
242
  })
222
243
  })
223
244
  })