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

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