@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.
- package/dist/orbcharts-plugins-basic.es.js +5695 -5474
- package/dist/orbcharts-plugins-basic.umd.js +16 -10
- package/dist/src/base/BaseGroupAxis.d.ts +1 -0
- package/dist/src/noneData/index.d.ts +0 -1
- package/dist/src/noneData/types.d.ts +1 -1
- package/dist/src/series/types.d.ts +6 -1
- package/package.json +2 -2
- package/src/base/BaseGroupAxis.ts +35 -20
- package/src/grid/plugins/GroupAxis.ts +1 -0
- package/src/multiGrid/plugins/MultiGroupAxis.ts +1 -0
- package/src/noneData/index.ts +1 -1
- package/src/noneData/plugins/Tooltip.ts +26 -9
- package/src/noneData/types.ts +1 -1
- package/src/series/defaults.ts +15 -10
- package/src/series/plugins/Pie.ts +12 -4
- package/src/series/plugins/PieLabels.ts +357 -63
- package/src/series/plugins/Rose.ts +17 -8
- package/src/series/plugins/RoseLabels.ts +290 -87
- package/src/series/types.ts +9 -5
@@ -31,6 +31,7 @@ interface BaseGroupAxisContext {
|
|
31
31
|
}>;
|
32
32
|
gridContainerPosition$: Observable<GridContainerPosition[]>;
|
33
33
|
isSeriesSeprate$: Observable<boolean>;
|
34
|
+
textSizePx$: Observable<number>;
|
34
35
|
}
|
35
36
|
export declare const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext>;
|
36
37
|
export {};
|
@@ -19,6 +19,6 @@ export type TooltipParams = {
|
|
19
19
|
textColorType: ColorType;
|
20
20
|
offset: [number, number];
|
21
21
|
padding: number;
|
22
|
-
textRenderFn: <T extends ChartType>(eventData: EventTypeMap<T>) => string[];
|
22
|
+
textRenderFn: <T extends ChartType>(eventData: EventTypeMap<T>) => string[] | string | null;
|
23
23
|
svgRenderFn: (<T extends ChartType>(eventData: EventTypeMap<T>) => string) | null;
|
24
24
|
};
|
@@ -21,6 +21,8 @@ export interface PieParams {
|
|
21
21
|
startAngle: number;
|
22
22
|
endAngle: number;
|
23
23
|
padAngle: number;
|
24
|
+
strokeColorType: ColorType;
|
25
|
+
strokeWidth: number;
|
24
26
|
cornerRadius: number;
|
25
27
|
}
|
26
28
|
export interface PieEventTextsParams {
|
@@ -43,9 +45,12 @@ export interface PieLabelsParams {
|
|
43
45
|
}
|
44
46
|
export interface RoseParams {
|
45
47
|
outerRadius: number;
|
48
|
+
padAngle: number;
|
49
|
+
strokeColorType: ColorType;
|
50
|
+
strokeWidth: number;
|
46
51
|
cornerRadius: number;
|
47
52
|
arcScaleType: ArcScaleType;
|
48
|
-
|
53
|
+
angleIncreaseWhileHighlight: number;
|
49
54
|
}
|
50
55
|
export interface RoseLabelsParams {
|
51
56
|
outerRadius: number;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@orbcharts/plugins-basic",
|
3
|
-
"version": "3.0.0-alpha.
|
3
|
+
"version": "3.0.0-alpha.65",
|
4
4
|
"description": "plugins for OrbCharts",
|
5
5
|
"author": "Blue Planet Inc.",
|
6
6
|
"license": "Apache-2.0",
|
@@ -35,7 +35,7 @@
|
|
35
35
|
"vite-plugin-dts": "^3.7.3"
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
|
-
"@orbcharts/core": "^3.0.0-alpha.
|
38
|
+
"@orbcharts/core": "^3.0.0-alpha.59",
|
39
39
|
"d3": "^7.8.5",
|
40
40
|
"rxjs": "^7.8.1"
|
41
41
|
}
|
@@ -55,6 +55,7 @@ interface BaseGroupAxisContext {
|
|
55
55
|
}>
|
56
56
|
gridContainerPosition$: Observable<GridContainerPosition[]>
|
57
57
|
isSeriesSeprate$: Observable<boolean>
|
58
|
+
textSizePx$: Observable<number>
|
58
59
|
}
|
59
60
|
|
60
61
|
interface TextAlign {
|
@@ -147,7 +148,7 @@ function renderAxisLabel ({ selection, groupingLabelClassName, fullParams, axisL
|
|
147
148
|
|
148
149
|
}
|
149
150
|
|
150
|
-
function renderAxis ({ selection, xAxisClassName, fullParams, tickTextAlign, gridAxesSize, fullDataFormatter, chartParams, groupScale, groupScaleDomain, groupLabels, textReverseTransformWithRotate }: {
|
151
|
+
function renderAxis ({ selection, xAxisClassName, fullParams, tickTextAlign, gridAxesSize, fullDataFormatter, chartParams, groupScale, groupScaleDomain, groupLabels, textReverseTransformWithRotate, textSizePx }: {
|
151
152
|
selection: d3.Selection<SVGGElement, any, any, any>,
|
152
153
|
xAxisClassName: string
|
153
154
|
fullParams: BaseGroupAxisParams
|
@@ -159,6 +160,7 @@ function renderAxis ({ selection, xAxisClassName, fullParams, tickTextAlign, gri
|
|
159
160
|
groupScaleDomain: number[]
|
160
161
|
groupLabels: string[]
|
161
162
|
textReverseTransformWithRotate: string
|
163
|
+
textSizePx: number
|
162
164
|
}) {
|
163
165
|
|
164
166
|
const xAxisSelection = selection
|
@@ -209,9 +211,34 @@ function renderAxis ({ selection, xAxisClassName, fullParams, tickTextAlign, gri
|
|
209
211
|
const xAxisEl = xAxisSelection
|
210
212
|
.transition()
|
211
213
|
.duration(100)
|
212
|
-
.call(xAxis)
|
213
|
-
|
214
|
-
|
214
|
+
.call(xAxis)
|
215
|
+
.on('end', (self, t) => {
|
216
|
+
// 先等transition結束再處理文字,否則會被原本的文字覆蓋
|
217
|
+
xAxisEl
|
218
|
+
.selectAll('.tick text')
|
219
|
+
.each((d, groupIndex, n) => {
|
220
|
+
// -- 將原本單行文字改為多行文字 --
|
221
|
+
const groupLabel = groupLabels[groupIndex] ?? '' // 非整數index不顯示
|
222
|
+
const groupLabelTspans = groupLabel.split('\n')
|
223
|
+
const textSelection = d3.select(n[groupIndex])
|
224
|
+
.text(null) // 先清空原本的 text
|
225
|
+
|
226
|
+
const textX = Number(textSelection.attr('x'))
|
227
|
+
let textY = Number(textSelection.attr('y'))
|
228
|
+
if (fullDataFormatter.grid.groupAxis.position === 'top') {
|
229
|
+
// 當文字在上方時,要往上偏移第一行的高度
|
230
|
+
textY -= (groupLabelTspans.length - 1) * textSizePx
|
231
|
+
}
|
232
|
+
|
233
|
+
textSelection
|
234
|
+
.selectAll('tspan')
|
235
|
+
.data(groupLabelTspans)
|
236
|
+
.join('tspan')
|
237
|
+
.attr('x', textX)
|
238
|
+
.attr('y', (_d, _i) => textY + _i * textSizePx)
|
239
|
+
.text(d => d)
|
240
|
+
})
|
241
|
+
})
|
215
242
|
|
216
243
|
xAxisEl.selectAll('line')
|
217
244
|
.style('fill', 'none')
|
@@ -224,22 +251,7 @@ function renderAxis ({ selection, xAxisClassName, fullParams, tickTextAlign, gri
|
|
224
251
|
.style('stroke', fullParams.axisLineVisible == true ? getColor(fullParams.axisLineColorType, chartParams) : 'none')
|
225
252
|
.style('shape-rendering', 'crispEdges')
|
226
253
|
|
227
|
-
|
228
|
-
// xAxisSelection.each((d, i, g) => {
|
229
|
-
// d3.select(g[i])
|
230
|
-
// .selectAll('text')
|
231
|
-
// .data([d])
|
232
|
-
// .join('text')
|
233
|
-
// .style('font-family', 'sans-serif')
|
234
|
-
// .style('font-size', `${chartParams.styles.textSize}px`)
|
235
|
-
// // .style('font-weight', 'bold')
|
236
|
-
// .style('color', getColor(params.tickTextColorType, chartParams))
|
237
|
-
// .attr('text-anchor', tickTextAlign.textAnchor)
|
238
|
-
// .attr('dominant-baseline', tickTextAlign.dominantBaseline)
|
239
|
-
// .attr('transform-origin', `0 -${params.tickPadding + defaultTickSize}`)
|
240
|
-
// .style('transform', textReverseTransform)
|
241
|
-
// })
|
242
|
-
const xText = xAxisSelection.selectAll('text')
|
254
|
+
const xText = xAxisSelection.selectAll<SVGTextElement, BaseGroupAxisParams>('text')
|
243
255
|
// .style('font-family', 'sans-serif')
|
244
256
|
.attr('font-size', chartParams.styles.textSize)
|
245
257
|
// .style('font-weight', 'bold')
|
@@ -269,6 +281,7 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
269
281
|
gridAxesSize$,
|
270
282
|
gridContainerPosition$,
|
271
283
|
isSeriesSeprate$,
|
284
|
+
textSizePx$,
|
272
285
|
}) => {
|
273
286
|
|
274
287
|
const destroy$ = new Subject()
|
@@ -600,6 +613,7 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
600
613
|
groupLabels: groupLabels$,
|
601
614
|
textReverseTransform: textReverseTransform$,
|
602
615
|
textReverseTransformWithRotate: textReverseTransformWithRotate$,
|
616
|
+
textSizePx: textSizePx$
|
603
617
|
// tickTextFormatter: tickTextFormatter$
|
604
618
|
}).pipe(
|
605
619
|
takeUntil(destroy$),
|
@@ -618,6 +632,7 @@ export const createBaseGroupAxis: BasePluginFn<BaseGroupAxisContext> = ((pluginN
|
|
618
632
|
groupScaleDomain: data.groupScaleDomain,
|
619
633
|
groupLabels: data.groupLabels,
|
620
634
|
textReverseTransformWithRotate: data.textReverseTransformWithRotate,
|
635
|
+
textSizePx: data.textSizePx
|
621
636
|
})
|
622
637
|
|
623
638
|
renderAxisLabel({
|
@@ -27,6 +27,7 @@ export const GroupAxis = defineGridPlugin(pluginName, DEFAULT_GROUP_AXIS_PARAMS)
|
|
27
27
|
gridAxesSize$: observer.gridAxesSize$,
|
28
28
|
gridContainerPosition$: observer.gridContainerPosition$,
|
29
29
|
isSeriesSeprate$: observer.isSeriesSeprate$,
|
30
|
+
textSizePx$: observer.textSizePx$,
|
30
31
|
})
|
31
32
|
|
32
33
|
return () => {
|
package/src/noneData/index.ts
CHANGED
@@ -34,15 +34,32 @@ const pluginName = 'Tooltip'
|
|
34
34
|
const gClassName = getClassName(pluginName, 'g')
|
35
35
|
const boxClassName = getClassName(pluginName, 'box')
|
36
36
|
|
37
|
-
function textToSvg (
|
37
|
+
function textToSvg (_textArr: string[] | string | null | undefined, textStyle: TooltipStyle) {
|
38
38
|
const lineHeight = textStyle.textSizePx * 1.5
|
39
|
-
|
39
|
+
|
40
|
+
const textArr = _textArr == null
|
41
|
+
? []
|
42
|
+
: Array.isArray(_textArr)
|
43
|
+
? _textArr
|
44
|
+
: typeof _textArr === 'string'
|
45
|
+
? _textArr.split('\n')
|
46
|
+
: [_textArr]
|
47
|
+
|
48
|
+
const tspan = textArr
|
40
49
|
.filter(d => d != '')
|
41
50
|
.map((text, i) => {
|
42
51
|
const top = i * lineHeight
|
43
|
-
return `<
|
52
|
+
return `<tspan x="0" y="${top}">${text}</tspan>`
|
44
53
|
})
|
45
|
-
.join()
|
54
|
+
.join('')
|
55
|
+
|
56
|
+
if (tspan) {
|
57
|
+
return `<text font-size="${textStyle.textSize}" fill="${textStyle.textColor}" x="0" y="0" style="dominant-baseline:text-before-edge">
|
58
|
+
${tspan}
|
59
|
+
</text>`
|
60
|
+
} else {
|
61
|
+
return ''
|
62
|
+
}
|
46
63
|
}
|
47
64
|
|
48
65
|
function renderTooltip ({ rootSelection, pluginName, rootWidth, rootHeight, svgString, tooltipStyle, event }: {
|
@@ -234,14 +251,14 @@ export const Tooltip: PluginConstructor<any, string, any> = defineNoneDataPlugin
|
|
234
251
|
}).pipe(
|
235
252
|
takeUntil(destroy$),
|
236
253
|
switchMap(async d => d),
|
237
|
-
map(
|
238
|
-
if (
|
239
|
-
return
|
254
|
+
map(data => {
|
255
|
+
if (data.fullParams.svgRenderFn) {
|
256
|
+
return data.fullParams.svgRenderFn
|
240
257
|
}
|
241
258
|
// 將textRenderFn回傳的資料使用<text>包裝起來
|
242
259
|
return (eventData: EventTypeMap<any>) => {
|
243
|
-
const textArr =
|
244
|
-
return textToSvg(textArr,
|
260
|
+
const textArr = data.fullParams.textRenderFn(eventData as any)
|
261
|
+
return textToSvg(textArr, data.tooltipStyle)
|
245
262
|
}
|
246
263
|
})
|
247
264
|
)
|
package/src/noneData/types.ts
CHANGED
@@ -20,7 +20,7 @@ export type TooltipParams = {
|
|
20
20
|
textColorType: ColorType
|
21
21
|
offset: [number, number]
|
22
22
|
padding: number
|
23
|
-
textRenderFn: <T extends ChartType> (eventData: EventTypeMap<T>) => string[]
|
23
|
+
textRenderFn: <T extends ChartType> (eventData: EventTypeMap<T>) => string[] | string | null
|
24
24
|
svgRenderFn: (<T extends ChartType> (eventData: EventTypeMap<T>) => string) | null
|
25
25
|
}
|
26
26
|
|
package/src/series/defaults.ts
CHANGED
@@ -31,14 +31,16 @@ export const DEFAULT_PIE_PARAMS: PieParams = {
|
|
31
31
|
// bottom: 50,
|
32
32
|
// left: 70
|
33
33
|
// },
|
34
|
-
outerRadius: 0.
|
34
|
+
outerRadius: 0.85,
|
35
35
|
innerRadius: 0,
|
36
|
-
outerRadiusWhileHighlight:
|
36
|
+
outerRadiusWhileHighlight: 0.9,
|
37
37
|
// label?: LabelStyle
|
38
38
|
// enterDuration: 800,
|
39
39
|
startAngle: 0,
|
40
40
|
endAngle: Math.PI * 2,
|
41
|
-
padAngle: 0
|
41
|
+
padAngle: 0,
|
42
|
+
strokeColorType: 'background',
|
43
|
+
strokeWidth: 1,
|
42
44
|
// padRadius: 100,
|
43
45
|
cornerRadius: 0,
|
44
46
|
// highlightTarget: 'datum',
|
@@ -99,13 +101,13 @@ DEFAULT_PIE_EVENT_TEXTS_PARAMS.eventFn.toString = () => `(eventData: EventSeries
|
|
99
101
|
export const DEFAULT_PIE_LABELS_PARAMS: PieLabelsParams = {
|
100
102
|
// solidColor: undefined,
|
101
103
|
// colors: DEFAULT_COLORS,
|
102
|
-
outerRadius: 0.
|
103
|
-
outerRadiusWhileHighlight:
|
104
|
+
outerRadius: 0.85,
|
105
|
+
outerRadiusWhileHighlight: 0.9,
|
104
106
|
// innerRadius: 0,
|
105
107
|
// enterDuration: 800,
|
106
108
|
startAngle: 0,
|
107
109
|
endAngle: Math.PI * 2,
|
108
|
-
labelCentroid: 2.
|
110
|
+
labelCentroid: 2.1,
|
109
111
|
// fontSize: 12,
|
110
112
|
labelColorType: 'primary',
|
111
113
|
labelFn: d => String(d.label),
|
@@ -113,15 +115,18 @@ export const DEFAULT_PIE_LABELS_PARAMS: PieLabelsParams = {
|
|
113
115
|
DEFAULT_PIE_LABELS_PARAMS.labelFn.toString = () => `d => String(d.label)`
|
114
116
|
|
115
117
|
export const DEFAULT_ROSE_PARAMS: RoseParams = {
|
116
|
-
outerRadius: 0.
|
118
|
+
outerRadius: 0.85,
|
119
|
+
padAngle: 0,
|
120
|
+
strokeColorType: 'background',
|
121
|
+
strokeWidth: 0,
|
117
122
|
cornerRadius: 0,
|
118
123
|
arcScaleType: 'area',
|
119
|
-
|
124
|
+
angleIncreaseWhileHighlight: 0.05
|
120
125
|
}
|
121
126
|
|
122
127
|
export const DEFAULT_ROSE_LABELS_PARAMS: RoseLabelsParams = {
|
123
|
-
outerRadius: 0.
|
124
|
-
labelCentroid: 2.
|
128
|
+
outerRadius: 0.85,
|
129
|
+
labelCentroid: 2.1,
|
125
130
|
labelFn: d => String(d.label),
|
126
131
|
labelColorType: 'primary',
|
127
132
|
arcScaleType: 'area'
|
@@ -22,7 +22,7 @@ import {
|
|
22
22
|
import { DEFAULT_PIE_PARAMS } from '../defaults'
|
23
23
|
import { makePieData } from '../seriesUtils'
|
24
24
|
import { getD3TransitionEase, makeD3Arc } from '../../utils/d3Utils'
|
25
|
-
import { getClassName } from '../../utils/orbchartsUtils'
|
25
|
+
import { getDatumColor, getClassName } from '../../utils/orbchartsUtils'
|
26
26
|
import { seriesCenterSelectionObservable } from '../seriesObservables'
|
27
27
|
|
28
28
|
|
@@ -87,11 +87,13 @@ function makePieRenderData (data: PieDatum[], startAngle: number, endAngle: numb
|
|
87
87
|
})
|
88
88
|
}
|
89
89
|
|
90
|
-
function renderPie ({ selection, data, arc, pathClassName }: {
|
90
|
+
function renderPie ({ selection, data, arc, pathClassName, fullParams, fullChartParams }: {
|
91
91
|
selection: d3.Selection<SVGGElement, unknown, any, unknown>
|
92
92
|
data: PieDatum[]
|
93
93
|
arc: d3.Arc<any, d3.DefaultArcObject>
|
94
94
|
pathClassName: string
|
95
|
+
fullParams: PieParams
|
96
|
+
fullChartParams: ChartParams
|
95
97
|
}): d3.Selection<SVGPathElement, PieDatum, any, any> {
|
96
98
|
// console.log('data', data)
|
97
99
|
const pathSelection: d3.Selection<SVGPathElement, PieDatum, any, any> = selection
|
@@ -101,6 +103,8 @@ function renderPie ({ selection, data, arc, pathClassName }: {
|
|
101
103
|
.classed(pathClassName, true)
|
102
104
|
.style('cursor', 'pointer')
|
103
105
|
.attr('fill', (d, i) => d.data.color)
|
106
|
+
.attr('stroke', (d, i) => getDatumColor({ datum: d.data, colorType: fullParams.strokeColorType, fullChartParams }))
|
107
|
+
.attr('stroke-width', fullParams.strokeWidth)
|
104
108
|
.attr('d', (d, i) => {
|
105
109
|
return arc!(d as any)
|
106
110
|
})
|
@@ -312,7 +316,9 @@ function createEachPie (pluginName: string, context: {
|
|
312
316
|
selection: context.containerSelection,
|
313
317
|
data: tweenData,
|
314
318
|
arc: data.arc,
|
315
|
-
pathClassName
|
319
|
+
pathClassName,
|
320
|
+
fullParams: data.fullParams,
|
321
|
+
fullChartParams: data.fullChartParams,
|
316
322
|
})
|
317
323
|
|
318
324
|
// @Q@ 想盡量減清效能負擔所以取消掉
|
@@ -345,7 +351,9 @@ function createEachPie (pluginName: string, context: {
|
|
345
351
|
selection: context.containerSelection,
|
346
352
|
data: tweenData,
|
347
353
|
arc: data.arc,
|
348
|
-
pathClassName
|
354
|
+
pathClassName,
|
355
|
+
fullParams: data.fullParams,
|
356
|
+
fullChartParams: data.fullChartParams,
|
349
357
|
})
|
350
358
|
|
351
359
|
// if (data.fullParams.highlightTarget && data.fullParams.highlightTarget != 'none') {
|