@orbcharts/plugins-basic 3.0.0-alpha.24
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/LICENSE +201 -0
- package/package.json +41 -0
- package/src/grid/defaults.ts +95 -0
- package/src/grid/gridObservables.ts +114 -0
- package/src/grid/index.ts +12 -0
- package/src/grid/plugins/BarStack.ts +661 -0
- package/src/grid/plugins/Bars.ts +604 -0
- package/src/grid/plugins/BarsTriangle.ts +594 -0
- package/src/grid/plugins/Dots.ts +427 -0
- package/src/grid/plugins/GroupArea.ts +636 -0
- package/src/grid/plugins/GroupAxis.ts +363 -0
- package/src/grid/plugins/Lines.ts +528 -0
- package/src/grid/plugins/Ranking.ts +0 -0
- package/src/grid/plugins/RankingAxis.ts +0 -0
- package/src/grid/plugins/ScalingArea.ts +168 -0
- package/src/grid/plugins/ValueAxis.ts +356 -0
- package/src/grid/plugins/ValueStackAxis.ts +372 -0
- package/src/grid/types.ts +102 -0
- package/src/index.ts +7 -0
- package/src/multiGrid/index.ts +0 -0
- package/src/multiGrid/plugins/Diverging.ts +0 -0
- package/src/multiGrid/plugins/DivergingAxes.ts +0 -0
- package/src/multiGrid/plugins/TwoScaleAxes.ts +0 -0
- package/src/multiGrid/plugins/TwoScales.ts +0 -0
- package/src/multiValue/index.ts +0 -0
- package/src/multiValue/plugins/Scatter.ts +0 -0
- package/src/multiValue/plugins/ScatterAxes.ts +0 -0
- package/src/noneData/defaults.ts +47 -0
- package/src/noneData/index.ts +4 -0
- package/src/noneData/plugins/Container.ts +11 -0
- package/src/noneData/plugins/Tooltip.ts +305 -0
- package/src/noneData/types.ts +26 -0
- package/src/relationship/index.ts +0 -0
- package/src/relationship/plugins/Relationship.ts +0 -0
- package/src/series/defaults.ts +82 -0
- package/src/series/index.ts +6 -0
- package/src/series/plugins/Bubbles.ts +553 -0
- package/src/series/plugins/Pie.ts +603 -0
- package/src/series/plugins/PieEventTexts.ts +194 -0
- package/src/series/plugins/PieLabels.ts +289 -0
- package/src/series/plugins/Waffle.ts +0 -0
- package/src/series/seriesUtils.ts +51 -0
- package/src/series/types.ts +53 -0
- package/src/tree/index.ts +0 -0
- package/src/tree/plugins/TreeMap.ts +0 -0
- package/src/utils/commonUtils.ts +22 -0
- package/src/utils/d3Graphics.ts +125 -0
- package/src/utils/d3Utils.ts +73 -0
- package/src/utils/observables.ts +14 -0
- package/src/utils/orbchartsUtils.ts +70 -0
- package/tsconfig.json +14 -0
- package/vite.config.js +45 -0
@@ -0,0 +1,372 @@
|
|
1
|
+
import * as d3 from 'd3'
|
2
|
+
import {
|
3
|
+
combineLatest,
|
4
|
+
switchMap,
|
5
|
+
distinctUntilChanged,
|
6
|
+
first,
|
7
|
+
map,
|
8
|
+
takeUntil,
|
9
|
+
Observable,
|
10
|
+
Subject } from 'rxjs'
|
11
|
+
import {
|
12
|
+
defineGridPlugin } from '@orbcharts/core'
|
13
|
+
import { createAxisLinearScale } from '@orbcharts/core'
|
14
|
+
import type {
|
15
|
+
DataFormatterGrid,
|
16
|
+
ChartParams,
|
17
|
+
TransformData } from '@orbcharts/core'
|
18
|
+
import type { ValueStackAxisParams } from '../types'
|
19
|
+
import { DEFAULT_VALUE_STACK_AXIS_PLUGIN_PARAMS } from '../defaults'
|
20
|
+
import { getMinAndMax } from '../../utils/commonUtils'
|
21
|
+
import { parseTickFormatValue } from '../../utils/d3Utils'
|
22
|
+
import { getColor, getClassName } from '../../utils/orbchartsUtils'
|
23
|
+
|
24
|
+
interface TextAlign {
|
25
|
+
textAnchor: "start" | "middle" | "end"
|
26
|
+
dominantBaseline: "middle" | "auto" | "hanging"
|
27
|
+
}
|
28
|
+
|
29
|
+
const pluginName = 'ValueStackAxis'
|
30
|
+
const gClassName = getClassName(pluginName, 'g')
|
31
|
+
const textClassName = getClassName(pluginName, 'text')
|
32
|
+
const defaultTickSize = 6
|
33
|
+
|
34
|
+
function renderLinearAxis ({ selection, fullParams, tickTextAlign, axisLabelAlign, gridAxesSize, fullDataFormatter, fullChartParams, valueScale, contentTransform, minAndMax }: {
|
35
|
+
selection: d3.Selection<SVGGElement, any, any, any>,
|
36
|
+
fullParams: ValueStackAxisParams
|
37
|
+
tickTextAlign: TextAlign
|
38
|
+
axisLabelAlign: TextAlign
|
39
|
+
gridAxesSize: { width: number, height: number }
|
40
|
+
fullDataFormatter: DataFormatterGrid,
|
41
|
+
fullChartParams: ChartParams
|
42
|
+
valueScale: d3.ScaleLinear<number, number>
|
43
|
+
contentTransform: string,
|
44
|
+
minAndMax: [number, number]
|
45
|
+
}) {
|
46
|
+
|
47
|
+
const yAxisSelection = selection
|
48
|
+
.selectAll<SVGGElement, ValueStackAxisParams>(`g.${gClassName}`)
|
49
|
+
.data([fullParams])
|
50
|
+
.join('g')
|
51
|
+
.classed(gClassName, true)
|
52
|
+
|
53
|
+
const axisLabelSelection = selection
|
54
|
+
.selectAll<SVGGElement, ValueStackAxisParams>(`g.${textClassName}`)
|
55
|
+
.data([fullParams])
|
56
|
+
.join('g')
|
57
|
+
.classed(textClassName, true)
|
58
|
+
.each((d, i, g) => {
|
59
|
+
const text = d3.select(g[i])
|
60
|
+
.selectAll<SVGTextElement, ValueStackAxisParams>(`text`)
|
61
|
+
.data([d])
|
62
|
+
.join(
|
63
|
+
enter => {
|
64
|
+
return enter
|
65
|
+
.append('text')
|
66
|
+
.style('font-weight', 'bold')
|
67
|
+
},
|
68
|
+
update => update,
|
69
|
+
exit => exit.remove()
|
70
|
+
)
|
71
|
+
.attr('text-anchor', axisLabelAlign.textAnchor)
|
72
|
+
.attr('dominant-baseline', axisLabelAlign.dominantBaseline)
|
73
|
+
.style('font-size', `${fullChartParams.styles.textSize}px`)
|
74
|
+
.style('fill', getColor(fullParams.labelColorType, fullChartParams))
|
75
|
+
.style('transform', contentTransform)
|
76
|
+
.text(d => fullDataFormatter.valueAxis.label)
|
77
|
+
})
|
78
|
+
.attr('transform', d => `translate(${- d.tickPadding + fullParams.labelOffset[0]}, ${gridAxesSize.height + d.tickPadding + fullParams.labelOffset[1]})`)
|
79
|
+
|
80
|
+
|
81
|
+
const valueLength = minAndMax[1] - minAndMax[0]
|
82
|
+
|
83
|
+
// 設定Y軸刻度
|
84
|
+
const yAxis = d3.axisLeft(valueScale)
|
85
|
+
.scale(valueScale)
|
86
|
+
.ticks(valueLength > fullParams.ticks
|
87
|
+
? fullParams.ticks
|
88
|
+
: ((minAndMax[0] === 0 && minAndMax[1] === 0)
|
89
|
+
? 1
|
90
|
+
: Math.ceil(valueLength))) // 刻度分段數量
|
91
|
+
.tickFormat(d => parseTickFormatValue(d, fullParams.tickFormat))
|
92
|
+
.tickSize(fullParams.tickFullLine == true
|
93
|
+
? -gridAxesSize.width
|
94
|
+
: defaultTickSize)
|
95
|
+
.tickPadding(fullParams.tickPadding)
|
96
|
+
|
97
|
+
const yAxisEl = yAxisSelection
|
98
|
+
.transition()
|
99
|
+
.duration(100)
|
100
|
+
.call(yAxis)
|
101
|
+
|
102
|
+
yAxisEl.selectAll('line')
|
103
|
+
.style('fill', 'none')
|
104
|
+
.style('stroke', fullParams.tickLineVisible == true ? getColor(fullParams.tickColorType, fullChartParams) : 'none')
|
105
|
+
.style('stroke-dasharray', fullParams.tickFullLineDasharray)
|
106
|
+
.attr('pointer-events', 'none')
|
107
|
+
|
108
|
+
yAxisEl.selectAll('path')
|
109
|
+
.style('fill', 'none')
|
110
|
+
// .style('stroke', this.fullParams.axisLineColor!)
|
111
|
+
.style('stroke', fullParams.axisLineVisible == true ? getColor(fullParams.axisLineColorType, fullChartParams) : 'none')
|
112
|
+
.style('shape-rendering', 'crispEdges')
|
113
|
+
|
114
|
+
// const yText = yAxisEl.selectAll('text')
|
115
|
+
const yText = yAxisSelection.selectAll('text')
|
116
|
+
.style('font-family', 'sans-serif')
|
117
|
+
.style('font-size', `${fullChartParams.styles.textSize}px`)
|
118
|
+
.style('color', getColor(fullParams.tickTextColorType, fullChartParams))
|
119
|
+
.attr('text-anchor', tickTextAlign.textAnchor)
|
120
|
+
.attr('dominant-baseline', tickTextAlign.dominantBaseline)
|
121
|
+
.attr('transform-origin', `-${fullParams.tickPadding + defaultTickSize} 0`)
|
122
|
+
yText.style('transform', contentTransform)
|
123
|
+
|
124
|
+
return yAxisSelection
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
export const ValueStackAxis = defineGridPlugin(pluginName, DEFAULT_VALUE_STACK_AXIS_PLUGIN_PARAMS)(({ selection, name, observer, subject }) => {
|
129
|
+
|
130
|
+
const destroy$ = new Subject()
|
131
|
+
|
132
|
+
// const axisGUpdate = selection
|
133
|
+
// .selectAll('g')
|
134
|
+
// .data()
|
135
|
+
|
136
|
+
const axisSelection: d3.Selection<SVGGElement, any, any, any> = selection.append('g')
|
137
|
+
// let graphicSelection: d3.Selection<SVGGElement, any, any, any> | undefined
|
138
|
+
// let pathSelection: d3.Selection<SVGPathElement, ComputedDatumGrid[], any, any> | undefined
|
139
|
+
// .style('transform', 'translate(0px, 0px) scale(1)')
|
140
|
+
|
141
|
+
observer.gridAxesTransform$
|
142
|
+
.pipe(
|
143
|
+
takeUntil(destroy$),
|
144
|
+
map(d => d.value),
|
145
|
+
distinctUntilChanged()
|
146
|
+
).subscribe(d => {
|
147
|
+
axisSelection
|
148
|
+
.style('transform', d)
|
149
|
+
.attr('opacity', 0)
|
150
|
+
.transition()
|
151
|
+
.attr('opacity', 1)
|
152
|
+
})
|
153
|
+
|
154
|
+
// const gridAxesSize$ = gridAxisSizeObservable({
|
155
|
+
// fullDataFormatter$,
|
156
|
+
// computedLayout$
|
157
|
+
// })
|
158
|
+
|
159
|
+
// const contentTransform$: Observable<string> = new Observable(subscriber => {
|
160
|
+
// combineLatest({
|
161
|
+
// fullParams: fullParams$,
|
162
|
+
// computedLayout: computedLayout$
|
163
|
+
// }).pipe(
|
164
|
+
// takeUntil(destroy$),
|
165
|
+
// // 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
166
|
+
// switchMap(async (d) => d),
|
167
|
+
// ).subscribe(data => {
|
168
|
+
|
169
|
+
// const transformData = Object.assign({}, data.computedLayout.content.axesTransformData)
|
170
|
+
|
171
|
+
// const value = getAxesTransformValue({
|
172
|
+
// translate: [0, 0],
|
173
|
+
// scale: [transformData.scale[0] * -1, transformData.scale[1] * -1],
|
174
|
+
// rotate: transformData.rotate * -1 + data.fullParams.tickTextRotate,
|
175
|
+
// rotateX: transformData.rotateX * -1,
|
176
|
+
// rotateY: transformData.rotateY * -1
|
177
|
+
// })
|
178
|
+
|
179
|
+
// subscriber.next(value)
|
180
|
+
// })
|
181
|
+
// })
|
182
|
+
// const oppositeTransform$: Observable<TransformData> = observer.gridAxesTransform$.pipe(
|
183
|
+
// takeUntil(destroy$),
|
184
|
+
// map(d => {
|
185
|
+
// const translate: [number, number] = [d.translate[0] * -1, d.translate[1] * -1]
|
186
|
+
// const scale: [number, number] = [d.scale[0] * -1, d.scale[1] * -1]
|
187
|
+
// const rotate = d.rotate * -1
|
188
|
+
// const rotateX = d.rotateX * -1
|
189
|
+
// const rotateY = d.rotateY * -1
|
190
|
+
// return {
|
191
|
+
// translate,
|
192
|
+
// scale,
|
193
|
+
// rotate,
|
194
|
+
// rotateX,
|
195
|
+
// rotateY,
|
196
|
+
// value: ''
|
197
|
+
// }
|
198
|
+
// }),
|
199
|
+
// )
|
200
|
+
const contentTransform$ = combineLatest({
|
201
|
+
fullParams: observer.fullParams$,
|
202
|
+
gridAxesOppositeTransform: observer.gridAxesOppositeTransform$
|
203
|
+
}).pipe(
|
204
|
+
takeUntil(destroy$),
|
205
|
+
switchMap(async data => {
|
206
|
+
const rotate = data.gridAxesOppositeTransform.rotate + data.fullParams.tickTextRotate
|
207
|
+
return `translate(${data.gridAxesOppositeTransform.translate[0]}px, ${data.gridAxesOppositeTransform.translate[1]}px) rotate(${rotate}deg) rotateX(${data.gridAxesOppositeTransform.rotateX}deg) rotateY(${data.gridAxesOppositeTransform.rotateY}deg)`
|
208
|
+
}),
|
209
|
+
distinctUntilChanged()
|
210
|
+
)
|
211
|
+
|
212
|
+
const minAndMax$: Observable<[number, number]> = new Observable(subscriber => {
|
213
|
+
combineLatest({
|
214
|
+
fullDataFormatter: observer.fullDataFormatter$,
|
215
|
+
gridAxesSize: observer.gridAxesSize$,
|
216
|
+
computedData: observer.computedData$,
|
217
|
+
}).pipe(
|
218
|
+
takeUntil(destroy$),
|
219
|
+
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
220
|
+
switchMap(async (d) => d),
|
221
|
+
).subscribe(data => {
|
222
|
+
const groupMin = 0
|
223
|
+
const groupMax = data.computedData[0] ? data.computedData[0].length - 1 : 0
|
224
|
+
const groupScaleDomainMin = data.fullDataFormatter.groupAxis.scaleDomain[0] === 'auto'
|
225
|
+
? groupMin - data.fullDataFormatter.groupAxis.scalePadding
|
226
|
+
: data.fullDataFormatter.groupAxis.scaleDomain[0] as number - data.fullDataFormatter.groupAxis.scalePadding
|
227
|
+
const groupScaleDomainMax = data.fullDataFormatter.groupAxis.scaleDomain[1] === 'auto'
|
228
|
+
? groupMax + data.fullDataFormatter.groupAxis.scalePadding
|
229
|
+
: data.fullDataFormatter.groupAxis.scaleDomain[1] as number + data.fullDataFormatter.groupAxis.scalePadding
|
230
|
+
|
231
|
+
const filteredData = data.computedData.map((d, i) => {
|
232
|
+
return d.filter((_d, _i) => {
|
233
|
+
return _i >= groupScaleDomainMin && _i <= groupScaleDomainMax
|
234
|
+
})
|
235
|
+
})
|
236
|
+
|
237
|
+
// 將同一group的value加總起來
|
238
|
+
const filteredStackedData = new Array(filteredData[0] ? filteredData[0].length : 0)
|
239
|
+
.fill(null)
|
240
|
+
.map((_, i) => {
|
241
|
+
return filteredData.reduce((prev, current) => {
|
242
|
+
if (current && current[i]) {
|
243
|
+
const currentValue = current[i].value == null || current[i].visible == false
|
244
|
+
? 0
|
245
|
+
: current[i].value!
|
246
|
+
return prev + currentValue
|
247
|
+
}
|
248
|
+
return prev
|
249
|
+
}, 0)
|
250
|
+
})
|
251
|
+
|
252
|
+
const filteredMinAndMax = getMinAndMax(filteredStackedData)
|
253
|
+
|
254
|
+
subscriber.next(filteredMinAndMax)
|
255
|
+
})
|
256
|
+
})
|
257
|
+
|
258
|
+
const valueScale$: Observable<d3.ScaleLinear<number, number>> = new Observable(subscriber => {
|
259
|
+
combineLatest({
|
260
|
+
fullDataFormatter: observer.fullDataFormatter$,
|
261
|
+
gridAxesSize: observer.gridAxesSize$,
|
262
|
+
minAndMax: minAndMax$
|
263
|
+
}).pipe(
|
264
|
+
takeUntil(destroy$),
|
265
|
+
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
266
|
+
switchMap(async (d) => d),
|
267
|
+
).subscribe(data => {
|
268
|
+
|
269
|
+
const valueScale: d3.ScaleLinear<number, number> = createAxisLinearScale({
|
270
|
+
maxValue: data.minAndMax[1],
|
271
|
+
minValue: data.minAndMax[0],
|
272
|
+
axisWidth: data.gridAxesSize.height,
|
273
|
+
scaleDomain: data.fullDataFormatter.valueAxis.scaleDomain,
|
274
|
+
scaleRange: data.fullDataFormatter.valueAxis.scaleRange
|
275
|
+
})
|
276
|
+
|
277
|
+
subscriber.next(valueScale)
|
278
|
+
})
|
279
|
+
})
|
280
|
+
|
281
|
+
const tickTextAlign$: Observable<TextAlign> = observer.fullDataFormatter$.pipe(
|
282
|
+
takeUntil(destroy$),
|
283
|
+
map(d => {
|
284
|
+
let textAnchor: 'start' | 'middle' | 'end' = 'start'
|
285
|
+
let dominantBaseline: 'auto' | 'middle' | 'hanging' = 'hanging'
|
286
|
+
|
287
|
+
if (d.valueAxis.position === 'left') {
|
288
|
+
textAnchor = 'end'
|
289
|
+
dominantBaseline = 'middle'
|
290
|
+
} else if (d.valueAxis.position === 'right') {
|
291
|
+
textAnchor = 'start'
|
292
|
+
dominantBaseline = 'middle'
|
293
|
+
} else if (d.valueAxis.position === 'bottom') {
|
294
|
+
textAnchor = 'middle'
|
295
|
+
dominantBaseline = 'hanging'
|
296
|
+
} else if (d.valueAxis.position === 'top') {
|
297
|
+
textAnchor = 'middle'
|
298
|
+
dominantBaseline = 'auto'
|
299
|
+
}
|
300
|
+
return {
|
301
|
+
textAnchor,
|
302
|
+
dominantBaseline
|
303
|
+
}
|
304
|
+
})
|
305
|
+
)
|
306
|
+
|
307
|
+
const axisLabelAlign$: Observable<TextAlign> = observer.fullDataFormatter$.pipe(
|
308
|
+
takeUntil(destroy$),
|
309
|
+
map(d => {
|
310
|
+
let textAnchor: 'start' | 'middle' | 'end' = 'start'
|
311
|
+
let dominantBaseline: 'auto' | 'middle' | 'hanging' = 'hanging'
|
312
|
+
|
313
|
+
if (d.groupAxis.position === 'bottom') {
|
314
|
+
dominantBaseline = 'auto'
|
315
|
+
} else if (d.groupAxis.position === 'top') {
|
316
|
+
dominantBaseline = 'hanging'
|
317
|
+
} else if (d.groupAxis.position === 'left') {
|
318
|
+
textAnchor = 'start'
|
319
|
+
} else if (d.groupAxis.position === 'right') {
|
320
|
+
textAnchor = 'end'
|
321
|
+
}
|
322
|
+
if (d.valueAxis.position === 'left') {
|
323
|
+
textAnchor = 'end'
|
324
|
+
} else if (d.valueAxis.position === 'right') {
|
325
|
+
textAnchor = 'start'
|
326
|
+
} else if (d.valueAxis.position === 'bottom') {
|
327
|
+
dominantBaseline = 'hanging'
|
328
|
+
} else if (d.valueAxis.position === 'top') {
|
329
|
+
dominantBaseline = 'auto'
|
330
|
+
}
|
331
|
+
return {
|
332
|
+
textAnchor,
|
333
|
+
dominantBaseline
|
334
|
+
}
|
335
|
+
})
|
336
|
+
)
|
337
|
+
|
338
|
+
combineLatest({
|
339
|
+
fullParams: observer.fullParams$,
|
340
|
+
tickTextAlign: tickTextAlign$,
|
341
|
+
axisLabelAlign: axisLabelAlign$,
|
342
|
+
computedData: observer.computedData$,
|
343
|
+
gridAxesSize: observer.gridAxesSize$,
|
344
|
+
fullDataFormatter: observer.fullDataFormatter$,
|
345
|
+
fullChartParams: observer.fullChartParams$,
|
346
|
+
valueScale: valueScale$,
|
347
|
+
contentTransform: contentTransform$,
|
348
|
+
minAndMax: minAndMax$
|
349
|
+
}).pipe(
|
350
|
+
takeUntil(destroy$),
|
351
|
+
// 轉換後會退訂前一個未完成的訂閱事件,因此可以取到「同時間」最後一次的訂閱事件
|
352
|
+
switchMap(async (d) => d),
|
353
|
+
).subscribe(data => {
|
354
|
+
|
355
|
+
renderLinearAxis({
|
356
|
+
selection: axisSelection,
|
357
|
+
fullParams: data.fullParams,
|
358
|
+
tickTextAlign: data.tickTextAlign,
|
359
|
+
axisLabelAlign: data.axisLabelAlign,
|
360
|
+
gridAxesSize: data.gridAxesSize,
|
361
|
+
fullDataFormatter: data.fullDataFormatter,
|
362
|
+
fullChartParams: data.fullChartParams,
|
363
|
+
valueScale: data.valueScale,
|
364
|
+
contentTransform: data.contentTransform,
|
365
|
+
minAndMax: data.minAndMax
|
366
|
+
})
|
367
|
+
})
|
368
|
+
|
369
|
+
return () => {
|
370
|
+
destroy$.next(undefined)
|
371
|
+
}
|
372
|
+
})
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import type { ColorType } from '@orbcharts/core'
|
2
|
+
|
3
|
+
// export type LineType = 'line' | 'area' | 'gradientArea'
|
4
|
+
// export type BarType = 'rect' | 'triangle'
|
5
|
+
|
6
|
+
export interface LinesPluginParams {
|
7
|
+
// lineType: LineType
|
8
|
+
lineCurve: string
|
9
|
+
lineWidth: number
|
10
|
+
// labelFn: (d: ComputedDatumSeries) => string
|
11
|
+
// labelPositionFn: (d: ComputedDatumSeries) => 'top' | 'bottom' | 'left' | 'right' | 'center'
|
12
|
+
// labelStyleFn: (d: ComputedDatumSeries) => string
|
13
|
+
// labelFontSizeFn: (d: ComputedDatumSeries) => number
|
14
|
+
// labelColorFn: (d: ComputedDatumSeries) => string
|
15
|
+
// labelPadding: number
|
16
|
+
}
|
17
|
+
|
18
|
+
export interface DotsPluginParams {
|
19
|
+
radius: number
|
20
|
+
fillColorType: ColorType
|
21
|
+
strokeColorType: ColorType
|
22
|
+
strokeWidth: number
|
23
|
+
onlyShowHighlighted: boolean
|
24
|
+
}
|
25
|
+
|
26
|
+
export interface GroupAreaPluginParams {
|
27
|
+
showLine: boolean
|
28
|
+
showLabel: boolean
|
29
|
+
lineDashArray: string
|
30
|
+
lineColorType: ColorType
|
31
|
+
labelColorType: ColorType
|
32
|
+
labelTextColorType: ColorType
|
33
|
+
labelTextFormat: string | ((text: any) => string)
|
34
|
+
labelPadding: number
|
35
|
+
}
|
36
|
+
|
37
|
+
export interface BarsPluginParams {
|
38
|
+
// barType: BarType
|
39
|
+
barWidth: number
|
40
|
+
barPadding: number
|
41
|
+
barGroupPadding: number // 群組和群組間的間隔
|
42
|
+
barRadius: number | boolean
|
43
|
+
}
|
44
|
+
|
45
|
+
export interface BarStackPluginParams {
|
46
|
+
barWidth: number
|
47
|
+
barGroupPadding: number
|
48
|
+
barRadius: number | boolean
|
49
|
+
}
|
50
|
+
|
51
|
+
export interface BarsTrianglePluginParams {
|
52
|
+
barWidth: number
|
53
|
+
barPadding: number
|
54
|
+
barGroupPadding: number // 群組和群組間的間隔
|
55
|
+
linearGradientOpacity: [number, number]
|
56
|
+
}
|
57
|
+
|
58
|
+
export interface GroupingAxisParams {
|
59
|
+
// xLabel: string
|
60
|
+
// labelAnchor: 'start' | 'end'
|
61
|
+
labelOffset: [number, number]
|
62
|
+
labelColorType: ColorType
|
63
|
+
axisLineVisible: boolean
|
64
|
+
axisLineColorType: ColorType
|
65
|
+
tickFormat: string | ((text: any) => string)
|
66
|
+
tickLineVisible: boolean
|
67
|
+
tickPadding: number
|
68
|
+
tickFullLine: boolean
|
69
|
+
tickFullLineDasharray: string
|
70
|
+
tickColorType: ColorType
|
71
|
+
// axisLineColor: string
|
72
|
+
// axisLabelColor: string
|
73
|
+
tickTextRotate: number
|
74
|
+
tickTextColorType: ColorType
|
75
|
+
}
|
76
|
+
|
77
|
+
export interface ValueAxisParams {
|
78
|
+
// xLabel: string
|
79
|
+
// labelAnchor: 'start' | 'end'
|
80
|
+
labelOffset: [number, number]
|
81
|
+
labelColorType: ColorType
|
82
|
+
axisLineVisible: boolean
|
83
|
+
axisLineColorType: ColorType
|
84
|
+
ticks: number
|
85
|
+
tickFormat: string | ((text: d3.NumberValue) => string)
|
86
|
+
tickLineVisible: boolean
|
87
|
+
tickPadding: number
|
88
|
+
tickFullLine: boolean
|
89
|
+
tickFullLineDasharray: string
|
90
|
+
tickColorType: ColorType
|
91
|
+
// axisLineColor: string
|
92
|
+
// axisLabelColor: string
|
93
|
+
tickTextRotate: number
|
94
|
+
tickTextColorType: ColorType
|
95
|
+
}
|
96
|
+
|
97
|
+
export interface ValueStackAxisParams extends ValueAxisParams {}
|
98
|
+
|
99
|
+
export interface ScalingAreaParams {
|
100
|
+
|
101
|
+
}
|
102
|
+
|
package/src/index.ts
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
// export { default as container } from './noneDataPlugins/container'
|
2
|
+
// export { default as pie } from './seriesPlugins/pie'
|
3
|
+
// export { default as pieEventTexts } from './seriesPlugins/pieEventTexts'
|
4
|
+
// export { default as pieLabels } from './seriesPlugins/pieLabels'
|
5
|
+
export * from './grid'
|
6
|
+
export * from './noneData'
|
7
|
+
export * from './series'
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import type { ContainerPluginParams, TooltipParams } from './types'
|
2
|
+
import type { EventSeries, EventGrid } from '@orbcharts/core'
|
3
|
+
|
4
|
+
export const CONTAINER_PLUGIN_PARAMS: ContainerPluginParams = {
|
5
|
+
header: {
|
6
|
+
height: 36,
|
7
|
+
text: [],
|
8
|
+
textStyle: []
|
9
|
+
},
|
10
|
+
footer: {
|
11
|
+
height: 0,
|
12
|
+
text: [],
|
13
|
+
textStyle: []
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
export const TOOLTIP_PARAMS: TooltipParams = {
|
18
|
+
backgroundColorType: 'background',
|
19
|
+
strokeColorType: 'primary',
|
20
|
+
backgroundOpacity: 0.8,
|
21
|
+
textColorType: 'primary',
|
22
|
+
offset: [20, 5],
|
23
|
+
padding: 10,
|
24
|
+
textRenderFn: (eventData) => {
|
25
|
+
if (eventData.highlightTarget === 'datum' && eventData.datum) {
|
26
|
+
return [`${eventData.datum.label}: ${eventData.datum.value}`]
|
27
|
+
} else if (eventData.highlightTarget === 'series') {
|
28
|
+
const label = (eventData as EventSeries).seriesLabel
|
29
|
+
const value = (eventData as EventSeries).series
|
30
|
+
.map(d => {
|
31
|
+
return d.value
|
32
|
+
})
|
33
|
+
.join(',')
|
34
|
+
return [label, value]
|
35
|
+
} else if (eventData.highlightTarget === 'group') {
|
36
|
+
const label = (eventData as EventGrid).groupLabel
|
37
|
+
const value = (eventData as EventGrid).groups
|
38
|
+
.map(d => {
|
39
|
+
return d.value
|
40
|
+
})
|
41
|
+
.join(',')
|
42
|
+
return [label, value]
|
43
|
+
}
|
44
|
+
return []
|
45
|
+
},
|
46
|
+
svgRenderFn: null
|
47
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import * as d3 from 'd3'
|
2
|
+
import {
|
3
|
+
defineNoneDataPlugin } from '@orbcharts/core'
|
4
|
+
import { CONTAINER_PLUGIN_PARAMS } from '../defaults'
|
5
|
+
|
6
|
+
export const Container = defineNoneDataPlugin('Container', CONTAINER_PLUGIN_PARAMS)(({ selection }) => {
|
7
|
+
|
8
|
+
return function unsubscribe () {
|
9
|
+
|
10
|
+
}
|
11
|
+
})
|