@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.
- package/dist/orbcharts-plugins-basic.es.js +5699 -5476
- 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/base/BaseLegend.ts +1 -0
- package/src/grid/plugins/GroupAxis.ts +1 -0
- package/src/multiGrid/plugins/MultiGroupAxis.ts +1 -0
- package/src/multiGrid/plugins/OverlappingValueAxes.ts +3 -0
- package/src/multiGrid/plugins/OverlappingValueStackAxes.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({
|
package/src/base/BaseLegend.ts
CHANGED
@@ -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 () => {
|
@@ -47,6 +47,7 @@ export const OverlappingValueAxes = defineMultiGridPlugin(pluginName, DEFAULT_OV
|
|
47
47
|
takeUntil(destroy$),
|
48
48
|
switchMap(async (d) => d),
|
49
49
|
map(data => {
|
50
|
+
console.log('data', data)
|
50
51
|
if (!data.fullDataFormatter.gridList[data.secondGridIndex]) {
|
51
52
|
data.fullDataFormatter.gridList[data.secondGridIndex] = Object.assign({}, data.fullDataFormatter.gridList[data.firstGridIndex])
|
52
53
|
}
|
@@ -62,6 +63,7 @@ export const OverlappingValueAxes = defineMultiGridPlugin(pluginName, DEFAULT_OV
|
|
62
63
|
} else if (position === 'right') {
|
63
64
|
reversePosition = 'left'
|
64
65
|
}
|
66
|
+
// console.log('reversePosition', reversePosition)
|
65
67
|
return <DataFormatterGrid>{
|
66
68
|
type: 'grid',
|
67
69
|
visibleFilter: data.fullDataFormatter.visibleFilter as any,
|
@@ -116,6 +118,7 @@ export const OverlappingValueAxes = defineMultiGridPlugin(pluginName, DEFAULT_OV
|
|
116
118
|
})
|
117
119
|
return {
|
118
120
|
...observables,
|
121
|
+
dataFormatter$: secondGridDataFormatter$,
|
119
122
|
gridAxesTransform$,
|
120
123
|
gridAxesReverseTransform$,
|
121
124
|
gridContainerPosition$,
|
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') {
|