@orbcharts/plugins-basic 3.0.0-alpha.63 → 3.0.0-alpha.65

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.
@@ -27,24 +27,38 @@ import { seriesCenterSelectionObservable } from '../seriesObservables'
27
27
  interface RenderDatum {
28
28
  pieDatum: PieDatum
29
29
  arcIndex: number
30
- arcLabel: string
30
+ arcLabels: string[]
31
+ lineStartX: number
32
+ lineStartY: number
33
+ lineStartMouseoverX: number
34
+ lineStartMouseoverY: number
31
35
  x: number
32
36
  y: number
33
37
  mouseoverX: number
34
38
  mouseoverY: number
39
+ textWidth: number, // 文字寬度
40
+ collisionShiftX: number // 避免碰撞的位移
41
+ collisionShiftY: number
42
+ quadrant: number // 第幾象限
35
43
  }
36
44
 
37
45
  const pluginName = 'RoseLabels'
46
+ const labelGClassName = getClassName(pluginName, 'label-g')
47
+ const lineGClassName = getClassName(pluginName, 'line-g')
38
48
  const textClassName = getClassName(pluginName, 'text')
39
49
 
40
- function makeRenderData ({ pieData, centroid, arcScaleType, maxValue, axisWidth, outerRadius }: {
50
+ const pieOuterCentroid = 2
51
+
52
+ function makeRenderData ({ pieData, labelCentroid, arcScaleType, maxValue, axisWidth, outerRadius, lineStartCentroid, fullParams }: {
41
53
  pieData: PieDatum[]
42
54
  // arc: d3.Arc<any, d3.DefaultArcObject>
43
- centroid: number
55
+ labelCentroid: number
44
56
  arcScaleType: 'area' | 'radius'
45
57
  maxValue: number
46
58
  axisWidth: number
47
59
  outerRadius: number
60
+ lineStartCentroid: number
61
+ fullParams: RoseLabelsParams
48
62
  }): RenderDatum[] {
49
63
 
50
64
  const outerRadiusWidth = (axisWidth / 2) * outerRadius
@@ -71,118 +85,286 @@ function makeRenderData ({ pieData, centroid, arcScaleType, maxValue, axisWidth,
71
85
 
72
86
  const [_x, _y] = arc!.centroid(d as any)
73
87
  const [_mouseoverX, _mouseoverY] = [_x, _y]
88
+ const arcLabel = fullParams.labelFn(d.data)
74
89
  return {
75
90
  pieDatum: d,
76
91
  arcIndex: i,
77
- arcLabel: d.data.label,
78
- x: _x * centroid!,
79
- y: _y * centroid!,
80
- mouseoverX: _mouseoverX * centroid!,
81
- mouseoverY: _mouseoverY * centroid!
92
+ arcLabels: arcLabel.split('\n'),
93
+ lineStartX: _x * lineStartCentroid,
94
+ lineStartY: _y * lineStartCentroid,
95
+ lineStartMouseoverX: _mouseoverX * lineStartCentroid,
96
+ lineStartMouseoverY: _mouseoverY * lineStartCentroid,
97
+ x: _x * labelCentroid!,
98
+ y: _y * labelCentroid!,
99
+ mouseoverX: _mouseoverX * labelCentroid!,
100
+ mouseoverY: _mouseoverY * labelCentroid!,
101
+ textWidth: 0, // 後面再做計算
102
+ collisionShiftX: 0, // 後面再做計算
103
+ collisionShiftY: 0, // 後面再做計算
104
+ quadrant: _x >= 0 && _y <= 0
105
+ ? 1
106
+ : _x < 0 && _y <= 0
107
+ ? 2
108
+ : _x < 0 && _y > 0
109
+ ? 3
110
+ : 4
82
111
  }
83
112
  })
84
113
  .filter(d => d.pieDatum.data.visible)
85
114
  }
86
115
 
87
116
  // 繪製圓餅圖
88
- function renderLabel (selection: d3.Selection<SVGGElement, undefined, any, any>, data: RenderDatum[], pluginParams: RoseLabelsParams, fullChartParams: ChartParams) {
117
+ function renderLabel ({ labelGSelection, data, fullParams, fullChartParams, textSizePx }: {
118
+ labelGSelection: d3.Selection<SVGGElement, undefined, any, any>
119
+ data: RenderDatum[]
120
+ fullParams: RoseLabelsParams
121
+ fullChartParams: ChartParams
122
+ textSizePx: number
123
+ }) {
89
124
  // console.log(data)
90
125
  // let update = this.gSelection.selectAll('g').data(pieData)
91
- let update: d3.Selection<SVGPathElement, RenderDatum, any, any> = selection
92
- .selectAll<SVGPathElement, RenderDatum>('text')
126
+ const textSelection = labelGSelection
127
+ .selectAll<SVGTextElement, RenderDatum>('text')
93
128
  .data(data, d => d.pieDatum.id)
94
- let enter = update.enter()
95
- .append<SVGPathElement>('text')
129
+ .join('text')
96
130
  .classed(textClassName, true)
97
- let exit = update.exit()
98
-
99
- enter
100
- .append('text')
101
-
102
- const labelSelection = update.merge(enter)
103
- labelSelection
104
131
  .attr('font-weight', 'bold')
105
- .attr('text-anchor', 'middle')
106
- .style('dominant-baseline', 'middle')
132
+ .attr('text-anchor', d => d.quadrant == 1 || d.quadrant == 4 ? 'start' : 'end')
133
+ .style('dominant-baseline', d => d.quadrant == 1 || d.quadrant == 2 ? 'auto' : 'hanging')
107
134
  // .style('pointer-events', 'none')
108
135
  .style('cursor', d => fullChartParams.highlightTarget && fullChartParams.highlightTarget != 'none'
109
136
  ? 'pointer'
110
137
  : 'none')
111
138
  // .text((d, i) => d.arcLabel)
112
- .text(d => pluginParams.labelFn(d.pieDatum.data))
139
+ // .text(d => fullParams.labelFn(d.pieDatum.data))
113
140
  .attr('font-size', fullChartParams.styles.textSize)
114
- .attr('fill', (d, i) => getDatumColor({ datum: d.pieDatum.data, colorType: pluginParams.labelColorType, fullChartParams }))
141
+ .attr('fill', (d, i) => getDatumColor({ datum: d.pieDatum.data, colorType: fullParams.labelColorType, fullChartParams }))
142
+ .each((d, i, n) => {
143
+ const textNode = d3.select<SVGTextElement, RenderDatum>(n[i])
144
+ .selectAll('tspan')
145
+ .data(d.arcLabels)
146
+ .join('tspan')
147
+ .attr('x', 0)
148
+ .attr('y', (_d, _i) => d.quadrant == 1 || d.quadrant == 2
149
+ ? - (d.arcLabels.length - 1 - _i) * textSizePx
150
+ : _i * textSizePx)
151
+ .text(d => d)
152
+ })
153
+ textSelection
115
154
  .transition()
116
155
  .attr('transform', (d) => {
117
156
  return 'translate(' + d.x + ',' + d.y + ')'
118
157
  })
119
158
  // .on('end', () => initHighlight({ labelSelection, data, fullChartParams }))
120
- exit.remove()
121
159
 
122
160
  // 如無新增資料則不用等動畫
123
161
  // if (enter.size() == 0) {
124
162
  // this.initHighlight()
125
163
  // }
126
164
 
127
- return labelSelection
165
+ return textSelection
128
166
  }
129
167
 
130
- // function initHighlight ({ labelSelection, data, fullChartParams }: {
131
- // labelSelection: (d3.Selection<SVGPathElement, RenderDatum, any, any>)
132
- // data: RenderDatum[]
133
- // fullChartParams: ChartParams
134
- // }) {
135
- // removeHighlight({ labelSelection })
136
- // // if (fullParams.highlightSeriesId || fullParams.highlightDatumId) {
137
- // highlight({
138
- // labelSelection,
139
- // data,
140
- // id: fullChartParams.highlightDefault,
141
- // label: fullChartParams.highlightDefault,
142
- // fullChartParams
143
- // })
144
- // // }
145
- // }
146
-
147
- function highlight ({ labelSelection, ids, fullChartParams }: {
148
- labelSelection: (d3.Selection<SVGPathElement, RenderDatum, any, any>)
168
+ // 獲取每個文字元素的邊界框並檢查是否重疊
169
+ function resolveCollisions(textSelection: d3.Selection<SVGTextElement, RenderDatum, any, any>, data: RenderDatum[], textSizePx: number) {
170
+ const textArray = textSelection.nodes();
171
+ const padding = textSizePx // 調整文字間的間距
172
+
173
+ // 存儲每個標籤的當前位置
174
+ const positions = textArray.map((textNode, i) => {
175
+ const bbox = textNode.getBBox();
176
+ // const arcCentroid = arc.centroid(data[i]);
177
+ const arcCentroid = [data[i].x, data[i].y];
178
+ return {
179
+ node: textNode,
180
+ x: arcCentroid[0],
181
+ y: arcCentroid[1],
182
+ width: bbox.width,
183
+ height: bbox.height
184
+ }
185
+ })
186
+
187
+ // 順時針碰撞檢測(只處理 2、4 象限,將較後面的文字碰撞時往外偏移)
188
+ for (let i = 0; i < positions.length; i++) {
189
+ const a = positions[i]
190
+
191
+ for (let j = i + 1; j < positions.length; j++) {
192
+ const b = positions[j]
193
+
194
+ // 記錄文字寬度
195
+ data[i].textWidth = a.width
196
+
197
+ const ax = a.x + data[i].collisionShiftX
198
+ const ay = a.y + data[i].collisionShiftY
199
+ const bx = b.x + data[j].collisionShiftX
200
+ const by = b.y + data[j].collisionShiftY
201
+
202
+ // 檢查是否重疊
203
+ if (!(ax + a.width / 2 < bx - b.width / 2 ||
204
+ ax - a.width / 2 > bx + b.width / 2 ||
205
+ ay + a.height / 2 < by - b.height / 2 ||
206
+ ay - a.height / 2 > by + b.height / 2)) {
207
+
208
+ if (data[j].quadrant == 2) {
209
+ const moveDown = (by > ay)
210
+ ? -padding * 2
211
+ : -padding
212
+ data[j].collisionShiftY += moveDown // 由後一個累加高度
213
+ } else if (data[j].quadrant == 4) {
214
+ const moveDown = (by > ay)
215
+ ? padding
216
+ : padding * 2
217
+ data[j].collisionShiftY += moveDown // 由後一個累加高度
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ // 逆時針碰撞檢測(只處理 1、3 象限,將較前面的文字碰撞時往外偏移)
224
+ for (let i = positions.length - 1; i >= 0; i--) {
225
+ const a = positions[i]
226
+
227
+ for (let j = i - 1; j >= 0; j--) {
228
+ const b = positions[j]
229
+
230
+ // 記錄文字寬度
231
+ data[i].textWidth = a.width
232
+
233
+ const ax = a.x + data[i].collisionShiftX
234
+ const ay = a.y + data[i].collisionShiftY
235
+ const bx = b.x + data[j].collisionShiftX
236
+ const by = b.y + data[j].collisionShiftY
237
+
238
+ // 檢查是否重疊
239
+ if (!(ax + a.width / 2 < bx - b.width / 2 ||
240
+ ax - a.width / 2 > bx + b.width / 2 ||
241
+ ay + a.height / 2 < by - b.height / 2 ||
242
+ ay - a.height / 2 > by + b.height / 2)) {
243
+
244
+ if (data[j].quadrant == 1) {
245
+ const moveDown = (by > ay)
246
+ ? -padding * 2
247
+ : -padding
248
+ data[j].collisionShiftY += moveDown // 由前一個累加高度
249
+ } else if (data[j].quadrant == 3) {
250
+ const moveDown = (by > ay)
251
+ ? padding
252
+ : padding * 2
253
+ data[j].collisionShiftY += moveDown // 由前一個累加高度
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ // 全部算完再來 render
260
+ textSelection
261
+ .data(data)
262
+ .transition()
263
+ .attr('transform', (d) => {
264
+ return `translate(${d.x + d.collisionShiftX},${d.y + d.collisionShiftY})`
265
+ })
266
+ }
267
+
268
+ function renderLine ({ lineGSelection, data, fullParams, fullChartParams }: {
269
+ lineGSelection: d3.Selection<SVGGElement, undefined, any, any>
270
+ data: RenderDatum[]
271
+ fullParams: RoseLabelsParams
272
+ fullChartParams: ChartParams
273
+ }) {
274
+
275
+ // 只顯示在有偏移的標籤
276
+ const filteredData = data.filter(d => d.collisionShiftX || d.collisionShiftY)
277
+
278
+ // 添加標籤的連接線
279
+ const lines = lineGSelection.selectAll<SVGPolylineElement, RenderDatum>("polyline")
280
+ .data(filteredData, d => d.pieDatum.id)
281
+ .join("polyline")
282
+ .attr("stroke", d => getDatumColor({ datum: d.pieDatum.data, colorType: fullParams.labelColorType, fullChartParams }))
283
+ .attr("stroke-width", 1)
284
+ .attr("fill", "none")
285
+ .attr("points", (d) => {
286
+ return [[d.lineStartX, d.lineStartY], [d.lineStartX, d.lineStartY]] as any // 畫出從弧線中心到延伸點的線
287
+ })
288
+ lines
289
+ .transition()
290
+ .attr("points", (d) => {
291
+ // const pos = arc.centroid(d) // 起點:弧線的中心點
292
+ // const outerPos = [pos[0] * 2.5, pos[1] * 2.5] // 外部延伸的點(乘以倍率來延長線段)
293
+
294
+ let lineEndX = d.x + d.collisionShiftX
295
+ let lineEndY = d.y + d.collisionShiftY
296
+ // if (d.lineStartX >= Math.abs(d.lineStartY)) {
297
+ // lineEndX -= d.textWidth / 2
298
+ // } else if (d.lineStartX <= - Math.abs(d.lineStartY)) {
299
+ // lineEndX += d.textWidth / 2
300
+ // }
301
+
302
+ return [[lineEndX, lineEndY], [d.lineStartX, d.lineStartY]] as any // 畫出從弧線中心到延伸點的線
303
+ })
304
+
305
+ return lines
306
+ }
307
+
308
+ function highlight ({ textSelection, lineSelection, ids, fullChartParams }: {
309
+ textSelection: d3.Selection<SVGTextElement, RenderDatum, any, any>
310
+ lineSelection: d3.Selection<SVGPolylineElement, RenderDatum, any, any>
149
311
  ids: string[]
150
312
  fullChartParams: ChartParams
151
313
  }) {
152
- labelSelection.interrupt('highlight')
314
+ textSelection.interrupt('highlight')
315
+ lineSelection.interrupt('highlight')
153
316
 
154
317
  if (!ids.length) {
155
- labelSelection
156
- .transition()
318
+ textSelection
319
+ .transition('highlight')
157
320
  .duration(200)
158
321
  .attr('transform', (d) => {
159
- return 'translate(' + d.x + ',' + d.y + ')'
322
+ return `translate(${d.x + d.collisionShiftX},${d.y + d.collisionShiftY})`
160
323
  })
161
324
  .style('opacity', 1)
325
+ lineSelection
326
+ .transition('highlight')
327
+ .duration(200)
328
+ .style('opacity', 1)
162
329
  return
163
330
  }
164
331
 
165
- labelSelection.each((d, i, n) => {
166
- const segment = d3.select<SVGPathElement, RenderDatum>(n[i])
332
+ textSelection.each((d, i, n) => {
333
+ const segment = d3.select<SVGTextElement, RenderDatum>(n[i])
167
334
 
168
335
  if (ids.includes(d.pieDatum.data.id)) {
169
336
  segment
170
337
  .style('opacity', 1)
171
- .transition()
338
+ .transition('highlight')
172
339
  .duration(200)
173
340
  .attr('transform', (d) => {
174
- return 'translate(' + d.mouseoverX + ',' + d.mouseoverY + ')'
341
+ return `translate(${d.mouseoverX + d.collisionShiftX},${d.mouseoverY + d.collisionShiftY})`
175
342
  })
176
343
  } else {
177
344
  segment
178
345
  .style('opacity', fullChartParams.styles.unhighlightedOpacity)
179
- .transition()
346
+ .transition('highlight')
180
347
  .duration(200)
181
348
  .attr('transform', (d) => {
182
- return 'translate(' + d.x + ',' + d.y + ')'
349
+ return `translate(${d.x + d.collisionShiftX},${d.y + d.collisionShiftY})`
183
350
  })
184
351
  }
185
352
  })
353
+ lineSelection.each((d, i, n) => {
354
+ const segment = d3.select<SVGPolylineElement, RenderDatum>(n[i])
355
+
356
+ if (ids.includes(d.pieDatum.data.id)) {
357
+ segment
358
+ .style('opacity', 1)
359
+ .transition('highlight')
360
+ .duration(200)
361
+ } else {
362
+ segment
363
+ .style('opacity', fullChartParams.styles.unhighlightedOpacity)
364
+ .transition('highlight')
365
+ .duration(200)
366
+ }
367
+ })
186
368
  }
187
369
 
188
370
 
@@ -194,13 +376,22 @@ function createEachPieLabel (pluginName: string, context: {
194
376
  // SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
195
377
  fullParams$: Observable<RoseLabelsParams>
196
378
  fullChartParams$: Observable<ChartParams>
379
+ textSizePx$: Observable<number>
197
380
  seriesHighlight$: Observable<ComputedDatumSeries[]>
198
381
  seriesContainerPosition$: Observable<SeriesContainerPosition>
199
382
  event$: Subject<EventSeries>
200
383
  }) {
201
384
  const destroy$ = new Subject()
202
385
 
203
- let labelSelection$: Subject<d3.Selection<SVGPathElement, RenderDatum, any, any>> = new Subject()
386
+ context.containerSelection.selectAll('g').remove()
387
+
388
+ const lineGSelection: d3.Selection<SVGGElement, any, any, unknown> = context.containerSelection.append('g')
389
+ lineGSelection.classed(lineGClassName, true)
390
+ const labelGSelection: d3.Selection<SVGGElement, any, any, unknown> = context.containerSelection.append('g')
391
+ labelGSelection.classed(labelGClassName, true)
392
+
393
+ const textSelection$: Subject<d3.Selection<SVGTextElement, RenderDatum, any, any>> = new Subject()
394
+ const lineSelection$: Subject<d3.Selection<SVGPolylineElement, RenderDatum, any, any>> = new Subject()
204
395
  let renderData: RenderDatum[] = []
205
396
 
206
397
  const shorterSideWith$ = context.seriesContainerPosition$.pipe(
@@ -214,6 +405,16 @@ function createEachPieLabel (pluginName: string, context: {
214
405
  distinctUntilChanged()
215
406
  )
216
407
 
408
+ const lineStartCentroid$ = context.fullParams$.pipe(
409
+ takeUntil(destroy$),
410
+ map(d => {
411
+ return d.labelCentroid >= pieOuterCentroid
412
+ ? pieOuterCentroid // 當 label在 pie的外側時,線條從 pie的邊緣開始
413
+ : d.labelCentroid // 當 label在 pie的內側時,線條從 label未偏移前的位置開始
414
+
415
+ })
416
+ )
417
+
217
418
  combineLatest({
218
419
  // layout: context.seriesContainerPosition$,
219
420
  shorterSideWith: shorterSideWith$,
@@ -221,36 +422,13 @@ function createEachPieLabel (pluginName: string, context: {
221
422
  maxValue: maxValue$,
222
423
  fullParams: context.fullParams$,
223
424
  fullChartParams: context.fullChartParams$,
425
+ textSizePx: context.textSizePx$,
426
+ lineStartCentroid: lineStartCentroid$
224
427
  }).pipe(
225
428
  takeUntil(destroy$),
226
429
  switchMap(async (d) => d),
227
430
  ).subscribe(data => {
228
431
 
229
- // const shorterSideWith = data.layout.width < data.layout.height ? data.layout.width : data.layout.height
230
-
231
- // // 弧產生器 (d3.arc())
232
- // const arc = makeD3Arc({
233
- // axisWidth: shorterSideWith,
234
- // innerRadius: 0,
235
- // outerRadius: data.fullParams.outerRadius,
236
- // padAngle: 0,
237
- // cornerRadius: 0
238
- // })
239
-
240
- // const arcMouseover = makeD3Arc({
241
- // axisWidth: shorterSideWith,
242
- // innerRadius: 0,
243
- // outerRadius: data.fullParams.outerRadiusWhileHighlight, // 外半徑變化
244
- // padAngle: 0,
245
- // cornerRadius: 0
246
- // })
247
-
248
- // const pieData = makePieData({
249
- // data: data.containerVisibleComputedLayoutData,
250
- // startAngle: data.fullParams.startAngle,
251
- // endAngle: data.fullParams.endAngle
252
- // })
253
-
254
432
  const eachAngle = Math.PI * 2 / data.containerVisibleComputedLayoutData.length
255
433
 
256
434
  const pieData = data.containerVisibleComputedLayoutData.map((d, i) => {
@@ -268,21 +446,44 @@ function createEachPieLabel (pluginName: string, context: {
268
446
 
269
447
  renderData = makeRenderData({
270
448
  pieData,
271
- centroid: data.fullParams.labelCentroid,
449
+ labelCentroid: data.fullParams.labelCentroid,
272
450
  arcScaleType: data.fullParams.arcScaleType,
273
451
  maxValue: data.maxValue,
274
452
  axisWidth: data.shorterSideWith,
275
- outerRadius: data.fullParams.outerRadius
453
+ outerRadius: data.fullParams.outerRadius,
454
+ lineStartCentroid: data.lineStartCentroid,
455
+ fullParams: data.fullParams
276
456
  })
277
457
 
278
- const labelSelection = renderLabel(context.containerSelection, renderData, data.fullParams, data.fullChartParams)
458
+ // 先移除線條,等偏移後再重新繪製
459
+ lineGSelection.selectAll('polyline').remove()
279
460
 
280
- labelSelection$.next(labelSelection)
461
+ const textSelection = renderLabel({
462
+ labelGSelection,
463
+ data: renderData,
464
+ fullParams: data.fullParams,
465
+ fullChartParams: data.fullChartParams,
466
+ textSizePx: data.textSizePx
467
+ })
468
+
469
+ // 等 label 本身的 transition 結束後再進行碰撞檢測
470
+ setTimeout(() => {
471
+ // 偏移 label
472
+ resolveCollisions(textSelection, renderData, data.textSizePx)
473
+
474
+ const lineSelection = renderLine({ lineGSelection, data: renderData, fullParams: data.fullParams, fullChartParams: data.fullChartParams })
281
475
 
476
+ lineSelection$.next(lineSelection)
477
+
478
+ }, 1000)
479
+
480
+ textSelection$.next(textSelection)
481
+
282
482
  })
283
483
 
284
484
  combineLatest({
285
- labelSelection: labelSelection$,
485
+ textSelection: textSelection$,
486
+ lineSelection: lineSelection$,
286
487
  highlight: context.seriesHighlight$.pipe(
287
488
  map(data => data.map(d => d.id))
288
489
  ),
@@ -292,7 +493,8 @@ function createEachPieLabel (pluginName: string, context: {
292
493
  switchMap(async d => d)
293
494
  ).subscribe(data => {
294
495
  highlight({
295
- labelSelection: data.labelSelection,
496
+ textSelection: data.textSelection,
497
+ lineSelection: data.lineSelection,
296
498
  ids: data.highlight,
297
499
  fullChartParams: data.fullChartParams,
298
500
  })
@@ -348,6 +550,7 @@ export const RoseLabels = defineSeriesPlugin(pluginName, DEFAULT_ROSE_LABELS_PAR
348
550
  // SeriesDataMap$: observer.SeriesDataMap$,
349
551
  fullParams$: observer.fullParams$,
350
552
  fullChartParams$: observer.fullChartParams$,
553
+ textSizePx$: observer.textSizePx$,
351
554
  seriesHighlight$: observer.seriesHighlight$,
352
555
  seriesContainerPosition$: containerPosition$,
353
556
  event$: subject.event$,
@@ -20,14 +20,16 @@ export interface BubblesParams {
20
20
 
21
21
  export interface PieParams {
22
22
  // padding: Padding
23
- outerRadius: number;
24
- innerRadius: number;
25
- outerRadiusWhileHighlight: number;
23
+ outerRadius: number
24
+ innerRadius: number
25
+ outerRadiusWhileHighlight: number
26
26
  // label?: LabelStyle
27
27
  // enterDuration: number
28
28
  startAngle: number
29
29
  endAngle: number
30
30
  padAngle: number
31
+ strokeColorType: ColorType
32
+ strokeWidth: number
31
33
  // padRadius: number
32
34
  cornerRadius: number
33
35
  }
@@ -55,10 +57,12 @@ export interface PieLabelsParams {
55
57
 
56
58
  export interface RoseParams {
57
59
  outerRadius: number
58
- // padAngle: number
60
+ padAngle: number
61
+ strokeColorType: ColorType
62
+ strokeWidth: number
59
63
  cornerRadius: number
60
64
  arcScaleType: ArcScaleType
61
- mouseoverAngleIncrease: number
65
+ angleIncreaseWhileHighlight: number
62
66
  }
63
67
 
64
68
  export interface RoseLabelsParams {