@orbcharts/plugin-basic 4.0.0-pre-alpha.0
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/dist/orbcharts-plugin-basic.es.js +25335 -0
- package/dist/orbcharts-plugin-basic.umd.js +341 -0
- package/dist/plugin-basic/src/baseLayers/BaseBars.d.ts +38 -0
- package/dist/plugin-basic/src/baseLayers/BaseBarsTriangle.d.ts +37 -0
- package/dist/plugin-basic/src/baseLayers/BaseCategoryAxis.d.ts +42 -0
- package/dist/plugin-basic/src/baseLayers/BaseDots.d.ts +38 -0
- package/dist/plugin-basic/src/baseLayers/BaseLegend.d.ts +31 -0
- package/dist/plugin-basic/src/baseLayers/BaseLineAreas.d.ts +36 -0
- package/dist/plugin-basic/src/baseLayers/BaseLines.d.ts +36 -0
- package/dist/plugin-basic/src/baseLayers/BaseStackedBars.d.ts +41 -0
- package/dist/plugin-basic/src/baseLayers/BaseTooltip.d.ts +47 -0
- package/dist/plugin-basic/src/baseLayers/BaseValueAxis.d.ts +38 -0
- package/dist/plugin-basic/src/baseLayers/BaseXAxis.d.ts +25 -0
- package/dist/plugin-basic/src/baseLayers/BaseXZoom.d.ts +22 -0
- package/dist/plugin-basic/src/baseLayers/BaseYAxis.d.ts +23 -0
- package/dist/plugin-basic/src/baseLayers/types.d.ts +171 -0
- package/dist/plugin-basic/src/const/layerIndex.d.ts +10 -0
- package/dist/plugin-basic/src/const/sharedPluginParams.d.ts +6 -0
- package/dist/plugin-basic/src/index.d.ts +2 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/CompositionPlot.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/contextObservables.d.ts +40 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/defaults.d.ts +10 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Bubbles.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Indicator.d.ts +0 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Pie.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/PieEventTexts.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/PieLabels.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Rose.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/RoseLabels.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Waffle.d.ts +0 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/types.d.ts +110 -0
- package/dist/plugin-basic/src/plugins/CompositionPlot/utils.d.ts +19 -0
- package/dist/plugin-basic/src/plugins/HierarchyPlot/HierarchyPlot.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/HierarchyPlot/contextObservables.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/HierarchyPlot/defaults.d.ts +4 -0
- package/dist/plugin-basic/src/plugins/HierarchyPlot/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/HierarchyPlot/layers/TreeMap.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/HierarchyPlot/types.d.ts +29 -0
- package/dist/plugin-basic/src/plugins/Legend/Legend.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/Legend/contextObservables.d.ts +9 -0
- package/dist/plugin-basic/src/plugins/Legend/defaults.d.ts +4 -0
- package/dist/plugin-basic/src/plugins/Legend/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/Legend/layers/Legend.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/Legend/types.d.ts +31 -0
- package/dist/plugin-basic/src/plugins/Legend/utils.d.ts +19 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/NetworkPlot.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/contextObservables.d.ts +19 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/defaults.d.ts +5 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/layers/ForceDirected.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/layers/ForceDirectedBubbles.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/NetworkPlot/types.d.ts +117 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/ScatterPlot.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/contextObservables.d.ts +140 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/defaults.d.ts +8 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/layers/Scatter.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/layers/ScatterBubbles.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XYAux.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XYAxes.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XZoom.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/ScatterPlot/types.d.ts +146 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/SeriesPlot.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/contextObservables.d.ts +77 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/defaults.d.ts +15 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Bars.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/BarsPN.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/BarsTriangle.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryAux.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryAxis.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryZoom.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Dots.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/LineAreas.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Lines.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/StackedBars.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/StackedValueAxis.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/layers/ValueAxis.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/SeriesPlot/types.d.ts +140 -0
- package/dist/plugin-basic/src/plugins/Tooltip/Tooltip.d.ts +22 -0
- package/dist/plugin-basic/src/plugins/Tooltip/contextObservables.d.ts +9 -0
- package/dist/plugin-basic/src/plugins/Tooltip/defaults.d.ts +4 -0
- package/dist/plugin-basic/src/plugins/Tooltip/index.d.ts +3 -0
- package/dist/plugin-basic/src/plugins/Tooltip/layers/Tooltip.d.ts +16 -0
- package/dist/plugin-basic/src/plugins/Tooltip/types.d.ts +35 -0
- package/dist/plugin-basic/src/plugins/Tooltip/utils.d.ts +19 -0
- package/dist/plugin-basic/src/plugins/index.d.ts +7 -0
- package/dist/plugin-basic/src/types/BaseLayer.d.ts +3 -0
- package/dist/plugin-basic/src/types/Common.d.ts +14 -0
- package/dist/plugin-basic/src/types/ComputedData.d.ts +27 -0
- package/dist/plugin-basic/src/types/PluginParams.d.ts +66 -0
- package/dist/plugin-basic/src/types/index.d.ts +3 -0
- package/dist/plugin-basic/src/utils/commonUtils.d.ts +3 -0
- package/dist/plugin-basic/src/utils/d3Graphics.d.ts +24 -0
- package/dist/plugin-basic/src/utils/d3Scale.d.ts +28 -0
- package/dist/plugin-basic/src/utils/d3Utils.d.ts +14 -0
- package/dist/plugin-basic/src/utils/graphObservables.d.ts +0 -0
- package/dist/plugin-basic/src/utils/gridObservables.d.ts +51 -0
- package/dist/plugin-basic/src/utils/multivariateObservables.d.ts +74 -0
- package/dist/plugin-basic/src/utils/observables.d.ts +34 -0
- package/dist/plugin-basic/src/utils/orbchartsUtils.d.ts +26 -0
- package/dist/plugin-basic/src/utils/seriesObservables.d.ts +22 -0
- package/dist/plugin-basic/vite.config.d.ts +2 -0
- package/dist/src/index.d.ts +1 -0
- package/package.json +62 -0
- package/src/baseLayers/BaseBars.ts +783 -0
- package/src/baseLayers/BaseBarsTriangle.ts +692 -0
- package/src/baseLayers/BaseCategoryAxis.ts +708 -0
- package/src/baseLayers/BaseDots.ts +495 -0
- package/src/baseLayers/BaseLegend.ts +684 -0
- package/src/baseLayers/BaseLineAreas.ts +644 -0
- package/src/baseLayers/BaseLines.ts +721 -0
- package/src/baseLayers/BaseStackedBars.ts +818 -0
- package/src/baseLayers/BaseTooltip.ts +435 -0
- package/src/baseLayers/BaseValueAxis.ts +612 -0
- package/src/baseLayers/BaseXAxis.ts +412 -0
- package/src/baseLayers/BaseXZoom.ts +250 -0
- package/src/baseLayers/BaseYAxis.ts +371 -0
- package/src/baseLayers/types.ts +174 -0
- package/src/const/layerIndex.ts +36 -0
- package/src/const/sharedPluginParams.ts +29 -0
- package/src/index.ts +3 -0
- package/src/plugins/CompositionPlot/CompositionPlot.ts +308 -0
- package/src/plugins/CompositionPlot/contextObservables.ts +251 -0
- package/src/plugins/CompositionPlot/defaults.ts +162 -0
- package/src/plugins/CompositionPlot/index.ts +3 -0
- package/src/plugins/CompositionPlot/layers/Bubbles.ts +808 -0
- package/src/plugins/CompositionPlot/layers/Indicator.ts +0 -0
- package/src/plugins/CompositionPlot/layers/Pie.ts +776 -0
- package/src/plugins/CompositionPlot/layers/PieEventTexts.ts +326 -0
- package/src/plugins/CompositionPlot/layers/PieLabels.ts +651 -0
- package/src/plugins/CompositionPlot/layers/Rose.ts +546 -0
- package/src/plugins/CompositionPlot/layers/RoseLabels.ts +616 -0
- package/src/plugins/CompositionPlot/layers/Waffle.ts +0 -0
- package/src/plugins/CompositionPlot/types.ts +129 -0
- package/src/plugins/CompositionPlot/utils.ts +53 -0
- package/src/plugins/HierarchyPlot/HierarchyPlot.ts +190 -0
- package/src/plugins/HierarchyPlot/contextObservables.ts +136 -0
- package/src/plugins/HierarchyPlot/defaults.ts +31 -0
- package/src/plugins/HierarchyPlot/index.ts +3 -0
- package/src/plugins/HierarchyPlot/layers/TreeMap.ts +371 -0
- package/src/plugins/HierarchyPlot/types.ts +36 -0
- package/src/plugins/Legend/Legend.ts +151 -0
- package/src/plugins/Legend/contextObservables.ts +55 -0
- package/src/plugins/Legend/defaults.ts +37 -0
- package/src/plugins/Legend/index.ts +3 -0
- package/src/plugins/Legend/layers/Legend.ts +114 -0
- package/src/plugins/Legend/types.ts +45 -0
- package/src/plugins/Legend/utils.ts +53 -0
- package/src/plugins/NetworkPlot/NetworkPlot.ts +228 -0
- package/src/plugins/NetworkPlot/contextObservables.ts +123 -0
- package/src/plugins/NetworkPlot/defaults.ts +147 -0
- package/src/plugins/NetworkPlot/index.ts +3 -0
- package/src/plugins/NetworkPlot/layers/ForceDirected.ts +1048 -0
- package/src/plugins/NetworkPlot/layers/ForceDirectedBubbles.ts +1318 -0
- package/src/plugins/NetworkPlot/types.ts +146 -0
- package/src/plugins/ScatterPlot/ScatterPlot.ts +569 -0
- package/src/plugins/ScatterPlot/contextObservables.ts +901 -0
- package/src/plugins/ScatterPlot/defaults.ts +212 -0
- package/src/plugins/ScatterPlot/index.ts +3 -0
- package/src/plugins/ScatterPlot/layers/Scatter.ts +518 -0
- package/src/plugins/ScatterPlot/layers/ScatterBubbles.ts +670 -0
- package/src/plugins/ScatterPlot/layers/XYAux.ts +686 -0
- package/src/plugins/ScatterPlot/layers/XYAxes.ts +205 -0
- package/src/plugins/ScatterPlot/layers/XZoom.ts +48 -0
- package/src/plugins/ScatterPlot/types.ts +179 -0
- package/src/plugins/SeriesPlot/SeriesPlot.ts +494 -0
- package/src/plugins/SeriesPlot/contextObservables.ts +726 -0
- package/src/plugins/SeriesPlot/defaults.ts +142 -0
- package/src/plugins/SeriesPlot/index.ts +3 -0
- package/src/plugins/SeriesPlot/layers/Bars.ts +84 -0
- package/src/plugins/SeriesPlot/layers/BarsPN.ts +85 -0
- package/src/plugins/SeriesPlot/layers/BarsTriangle.ts +89 -0
- package/src/plugins/SeriesPlot/layers/CategoryAux.ts +1131 -0
- package/src/plugins/SeriesPlot/layers/CategoryAxis.ts +92 -0
- package/src/plugins/SeriesPlot/layers/CategoryZoom.ts +233 -0
- package/src/plugins/SeriesPlot/layers/Dots.ts +91 -0
- package/src/plugins/SeriesPlot/layers/LineAreas.ts +82 -0
- package/src/plugins/SeriesPlot/layers/Lines.ts +75 -0
- package/src/plugins/SeriesPlot/layers/StackedBars.ts +85 -0
- package/src/plugins/SeriesPlot/layers/StackedValueAxis.ts +111 -0
- package/src/plugins/SeriesPlot/layers/ValueAxis.ts +111 -0
- package/src/plugins/SeriesPlot/types.ts +201 -0
- package/src/plugins/Tooltip/Tooltip.ts +159 -0
- package/src/plugins/Tooltip/contextObservables.ts +55 -0
- package/src/plugins/Tooltip/defaults.ts +458 -0
- package/src/plugins/Tooltip/index.ts +3 -0
- package/src/plugins/Tooltip/layers/Tooltip.ts +90 -0
- package/src/plugins/Tooltip/types.ts +55 -0
- package/src/plugins/Tooltip/utils.ts +53 -0
- package/src/plugins/index.ts +8 -0
- package/src/types/BaseLayer.ts +3 -0
- package/src/types/Common.ts +20 -0
- package/src/types/ComputedData.ts +55 -0
- package/src/types/PluginParams.ts +81 -0
- package/src/types/index.ts +3 -0
- package/src/utils/commonUtils.ts +31 -0
- package/src/utils/d3Graphics.ts +177 -0
- package/src/utils/d3Scale.ts +198 -0
- package/src/utils/d3Utils.ts +92 -0
- package/src/utils/graphObservables.ts +0 -0
- package/src/utils/gridObservables.ts +637 -0
- package/src/utils/multivariateObservables.ts +790 -0
- package/src/utils/observables.ts +357 -0
- package/src/utils/orbchartsUtils.ts +335 -0
- package/src/utils/seriesObservables.ts +172 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export type ArcScaleType = 'area' | 'radius'
|
|
5
|
+
|
|
6
|
+
export type Placement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'
|
|
7
|
+
|
|
8
|
+
export interface ContainerSize {
|
|
9
|
+
width: number
|
|
10
|
+
height: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TransformData {
|
|
14
|
+
translate: [number, number]
|
|
15
|
+
scale: [number, number]
|
|
16
|
+
rotate: number
|
|
17
|
+
rotateX: number
|
|
18
|
+
rotateY: number
|
|
19
|
+
value: string
|
|
20
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ModelType, RenderDatumGraphEdge } from '@orbcharts/core'
|
|
2
|
+
import type {
|
|
3
|
+
ModelDatumBase,
|
|
4
|
+
ModelDatumSeries,
|
|
5
|
+
ModelDatumGrid,
|
|
6
|
+
ModelDatumMultivariate,
|
|
7
|
+
ModelDatumGraphNode,
|
|
8
|
+
ModelDatumGraphEdge,
|
|
9
|
+
ModelDatumTree,
|
|
10
|
+
RenderDatumBase,
|
|
11
|
+
} from '@orbcharts/core'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export interface ComputedDatumSeries extends RenderDatumBase<'series'> {
|
|
15
|
+
visible: boolean
|
|
16
|
+
seq: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ComputedDatumGrid extends RenderDatumBase<'grid'> {
|
|
20
|
+
visible: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ComputedDatumMultivariate extends RenderDatumBase<'multivariate'> {
|
|
24
|
+
visible: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ComputedDatumGraphNode extends RenderDatumBase<'graph'> {
|
|
28
|
+
visible: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ComputedDatumGraphEdge extends RenderDatumGraphEdge {
|
|
32
|
+
visible: boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ComputedDatumTree extends RenderDatumBase<'tree'> {
|
|
36
|
+
visible: boolean
|
|
37
|
+
children: ComputedDatumTree[]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type ComputedDatum<T extends ModelType> = T extends 'series' ? ComputedDatumSeries
|
|
41
|
+
: T extends 'grid' ? ComputedDatumGrid
|
|
42
|
+
: T extends 'multivariate' ? ComputedDatumMultivariate
|
|
43
|
+
: T extends 'graph' ? ComputedDatumGraphNode
|
|
44
|
+
: T extends 'tree' ? ComputedDatumTree
|
|
45
|
+
: unknown
|
|
46
|
+
|
|
47
|
+
export type ComputedData<T extends ModelType> = T extends 'series' ? ComputedDatumSeries[]
|
|
48
|
+
: T extends 'grid' ? ComputedDatumGrid[][]
|
|
49
|
+
: T extends 'multivariate' ? ComputedDatumMultivariate[][]
|
|
50
|
+
: T extends 'graph' ? {
|
|
51
|
+
nodes: ComputedDatumGraphNode[]
|
|
52
|
+
edges: ComputedDatumGraphEdge[]
|
|
53
|
+
}
|
|
54
|
+
: T extends 'tree' ? ComputedDatumTree
|
|
55
|
+
: unknown
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ModelType, ModelDatum } from '@orbcharts/core'
|
|
2
|
+
// import type { ComputedDatum } from './ComputedData'
|
|
3
|
+
|
|
4
|
+
export type AxisPosition = 'top' | 'bottom' | 'left' | 'right'
|
|
5
|
+
|
|
6
|
+
export interface XYAxis {
|
|
7
|
+
scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto'];
|
|
8
|
+
scaleRange: [number, number];
|
|
9
|
+
label: string;
|
|
10
|
+
// valueIndex: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ValueAxis {
|
|
13
|
+
position: AxisPosition;
|
|
14
|
+
scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto'];
|
|
15
|
+
scaleRange: [number, number];
|
|
16
|
+
label: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CategoryAxis {
|
|
19
|
+
position: AxisPosition;
|
|
20
|
+
scaleDomain: [number, number | 'max'];
|
|
21
|
+
scalePadding: number;
|
|
22
|
+
label: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type VisibleFilter<T extends ModelType> = (datum: ModelDatum<T>) => boolean | null;
|
|
26
|
+
|
|
27
|
+
export interface Container {
|
|
28
|
+
// gap: number
|
|
29
|
+
columnAmount: number
|
|
30
|
+
rowAmount: number
|
|
31
|
+
columnGap: number | 'auto'
|
|
32
|
+
rowGap: number | 'auto'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ContainerPosition {
|
|
36
|
+
slotIndex: number
|
|
37
|
+
rowIndex: number
|
|
38
|
+
columnIndex: number
|
|
39
|
+
// translate: [number, number]
|
|
40
|
+
startX: number
|
|
41
|
+
startY: number
|
|
42
|
+
centerX: number
|
|
43
|
+
centerY: number
|
|
44
|
+
width: number
|
|
45
|
+
height: number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// container - 有縮放的
|
|
49
|
+
export interface ContainerPositionScaled {
|
|
50
|
+
slotIndex: number
|
|
51
|
+
rowIndex: number
|
|
52
|
+
columnIndex: number
|
|
53
|
+
translate: [number, number]
|
|
54
|
+
scale: [number, number]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface Padding {
|
|
58
|
+
top: number
|
|
59
|
+
right: number
|
|
60
|
+
bottom: number
|
|
61
|
+
left: number
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface Layout extends Padding {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
rootWidth: number;
|
|
68
|
+
rootHeight: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type HighlightTarget = 'series' | 'category' | 'datum' | 'none'
|
|
72
|
+
|
|
73
|
+
export interface GraphicStyles {
|
|
74
|
+
padding: Padding,
|
|
75
|
+
highlightTarget: HighlightTarget
|
|
76
|
+
highlightDefault: string | null
|
|
77
|
+
unhighlightedOpacity: number
|
|
78
|
+
transitionDuration: number
|
|
79
|
+
transitionEase: string
|
|
80
|
+
}
|
|
81
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// 取得文字寬度
|
|
2
|
+
export function measureTextWidth (text: string, size: number = 10) {
|
|
3
|
+
const context = document.createElement("canvas").getContext("2d")
|
|
4
|
+
let width = context?.measureText(text)?.width ?? 0
|
|
5
|
+
return width * size / 10 // 以10為基準
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// 取得最小及最大值 - 數字陣列
|
|
9
|
+
export function getMinMax (data: number[]): [number, number] {
|
|
10
|
+
const defaultMinMax: [number, number] = [0, 0] // default
|
|
11
|
+
if (!data.length) {
|
|
12
|
+
return defaultMinMax
|
|
13
|
+
}
|
|
14
|
+
const minMax: [number, number] = data.reduce((prev, current) => {
|
|
15
|
+
// [min, max]
|
|
16
|
+
return [
|
|
17
|
+
current < prev[0] ? current : prev[0],
|
|
18
|
+
current > prev[1] ? current : prev[1]
|
|
19
|
+
]
|
|
20
|
+
}, [data[0], data[0]])
|
|
21
|
+
return minMax
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function toCurrency (num: number | null): string {
|
|
25
|
+
if (num === null || Number.isNaN(num) == true) {
|
|
26
|
+
return String(num || 0)
|
|
27
|
+
}
|
|
28
|
+
const parts = num.toString().split('.')
|
|
29
|
+
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
30
|
+
return parts.join('.')
|
|
31
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
|
|
2
|
+
type RenderCircleTextParams = {
|
|
3
|
+
text: string,
|
|
4
|
+
radius: number,
|
|
5
|
+
lineHeight: number,
|
|
6
|
+
isBreakAll: boolean,
|
|
7
|
+
limit?:number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type Line = { width: number; text: string }
|
|
11
|
+
|
|
12
|
+
export function renderCircleText (selection: d3.Selection<any, any, any, any>, {
|
|
13
|
+
text,
|
|
14
|
+
radius,
|
|
15
|
+
lineHeight,
|
|
16
|
+
isBreakAll = false,
|
|
17
|
+
limit = 0
|
|
18
|
+
}: RenderCircleTextParams): d3.Selection<SVGTSpanElement, Line, SVGTextElement, any> | undefined {
|
|
19
|
+
if (selection == null || text == null) {
|
|
20
|
+
console.error("selection or text is not defined")
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
if (radius == null) {
|
|
24
|
+
const getBox = selection.node().getBBox()
|
|
25
|
+
radius = getBox.width / 2
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getWords (text: string) {
|
|
29
|
+
let words
|
|
30
|
+
if (isBreakAll) {
|
|
31
|
+
words = text.split('')
|
|
32
|
+
} else {
|
|
33
|
+
words = text.split(/\s+/g) // To hyphenate: /\s+|(?<=-)/
|
|
34
|
+
}
|
|
35
|
+
if (!words[words.length - 1]) words.pop()
|
|
36
|
+
if (!words[0]) words.shift()
|
|
37
|
+
return words
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 省略文章字數
|
|
41
|
+
function ellipisText (text:string, limit:number) {
|
|
42
|
+
if (text && limit) {
|
|
43
|
+
if (text.length > limit) {
|
|
44
|
+
text = text.substring(0, limit) + "..."; // 超過字數以"..."取代
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return text;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function measureWidth (text: string) {
|
|
51
|
+
const context = document.createElement("canvas").getContext("2d")
|
|
52
|
+
// return text => context.measureText(text).width
|
|
53
|
+
return context?.measureText(text)?.width ?? 0
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getTargetWidth (text: string) {
|
|
57
|
+
const m = measureWidth(text.trim())
|
|
58
|
+
const result = Math.sqrt(m * lineHeight)
|
|
59
|
+
return result
|
|
60
|
+
// return(
|
|
61
|
+
// Math.sqrt(measureWidth(text.trim()) * lineHeight)
|
|
62
|
+
// )
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function getLines (words: string[], targetWidth: number) {
|
|
66
|
+
let line: Line = { width: 0, text: '' }
|
|
67
|
+
let lineWidth0 = Infinity
|
|
68
|
+
const lines: Array<Line> = []
|
|
69
|
+
let space = " "
|
|
70
|
+
if (isBreakAll) {
|
|
71
|
+
space = ""
|
|
72
|
+
}
|
|
73
|
+
for (let i = 0, n = words.length; i < n; ++i) {
|
|
74
|
+
const lineText1 = (line.text ? line.text + space : '') + words[i]
|
|
75
|
+
const lineWidth1 = measureWidth(lineText1)
|
|
76
|
+
if ((lineWidth0 + lineWidth1) / 2 < targetWidth) {
|
|
77
|
+
line.width = lineWidth0 = lineWidth1
|
|
78
|
+
line.text = lineText1
|
|
79
|
+
} else {
|
|
80
|
+
lineWidth0 = measureWidth(words[i])
|
|
81
|
+
line = {width: lineWidth0, text: words[i]}
|
|
82
|
+
lines.push(line)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return lines
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getTextRadius (lines: Array<Line>) {
|
|
89
|
+
let radius = 0
|
|
90
|
+
for (let i = 0, n = lines.length; i < n; ++i) {
|
|
91
|
+
const dy: number = (Math.abs(i - n / 2 + 0.5) + 0.5) * lineHeight
|
|
92
|
+
const dx: number = lines[i].width / 2
|
|
93
|
+
radius = Math.max(radius, Math.sqrt(dx ** 2 + dy ** 2))
|
|
94
|
+
}
|
|
95
|
+
return radius
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function draw (selection: d3.Selection<any, any, any, any>, text: string) {
|
|
99
|
+
if(limit > 0) text = ellipisText(text,limit)
|
|
100
|
+
const words = getWords(text)
|
|
101
|
+
const targetWidth = getTargetWidth(text)
|
|
102
|
+
const lines = getLines(words, targetWidth)
|
|
103
|
+
const textRadius = getTextRadius(lines)
|
|
104
|
+
|
|
105
|
+
let t = selection.select<SVGTextElement>("text")
|
|
106
|
+
if (!t.size()) {
|
|
107
|
+
t = selection.append("text")
|
|
108
|
+
}
|
|
109
|
+
t.attr("transform", `translate(${0},${0}) scale(${radius / textRadius})`)
|
|
110
|
+
const tspanUpdate = t.selectAll<SVGTSpanElement, Line>("tspan")
|
|
111
|
+
.data(lines)
|
|
112
|
+
const tspanEnter = tspanUpdate.enter()
|
|
113
|
+
.append<SVGTSpanElement>("tspan")
|
|
114
|
+
.attr("x", 0)
|
|
115
|
+
.merge(tspanUpdate as d3.Selection<SVGTSpanElement, Line, SVGTextElement, undefined>)
|
|
116
|
+
.attr("y", (d: Line, i: number) => (i - lines.length / 2 + 0.8) * lineHeight)
|
|
117
|
+
.text((d: Line) => d.text)
|
|
118
|
+
tspanUpdate.exit().remove()
|
|
119
|
+
|
|
120
|
+
// return selection.node()
|
|
121
|
+
return tspanUpdate.merge(tspanEnter)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return draw(selection, text)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 圖軸上的多行tspan
|
|
128
|
+
export function renderTspansOnAxis (textSelection: d3.Selection<d3.BaseType, unknown, null, undefined>, {
|
|
129
|
+
textArr,
|
|
130
|
+
textSizePx,
|
|
131
|
+
categoryAxisPosition,
|
|
132
|
+
isContainerRotated // 外層是否有變形處理
|
|
133
|
+
}: {
|
|
134
|
+
textArr: string[]
|
|
135
|
+
textSizePx: number
|
|
136
|
+
categoryAxisPosition: 'top' | 'right' | 'bottom' | 'left'
|
|
137
|
+
isContainerRotated: boolean
|
|
138
|
+
}) {
|
|
139
|
+
// -- 將原本單行文字改為多行文字 --
|
|
140
|
+
textSelection.text(null) // 先清空原本的 text
|
|
141
|
+
|
|
142
|
+
const textX = Number(textSelection.attr('x'))
|
|
143
|
+
let textY = Number(textSelection.attr('y'))
|
|
144
|
+
if (isContainerRotated && categoryAxisPosition === 'top') {
|
|
145
|
+
// 當文字在上方時,要往上偏移第一行的高度
|
|
146
|
+
textY -= (textArr.length - 1) * textSizePx
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
textSelection
|
|
150
|
+
.selectAll('tspan')
|
|
151
|
+
.data(textArr)
|
|
152
|
+
.join('tspan')
|
|
153
|
+
.attr('x', textX)
|
|
154
|
+
.attr('y', (_d, _i) => textY + _i * textSizePx)
|
|
155
|
+
.text(d => d)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 四象限上的多行tspan
|
|
159
|
+
export function renderTspansOnQuadrant (textSelection: d3.Selection<d3.BaseType, unknown, null, undefined>, {
|
|
160
|
+
textArr,
|
|
161
|
+
fontSizePx,
|
|
162
|
+
quadrant
|
|
163
|
+
}: {
|
|
164
|
+
textArr: string[]
|
|
165
|
+
fontSizePx: number
|
|
166
|
+
quadrant: number
|
|
167
|
+
}) {
|
|
168
|
+
textSelection
|
|
169
|
+
.selectAll('tspan')
|
|
170
|
+
.data(textArr)
|
|
171
|
+
.join('tspan')
|
|
172
|
+
.attr('x', 0)
|
|
173
|
+
.attr('y', (_d, _i) => quadrant == 1 || quadrant == 2
|
|
174
|
+
? - (textArr.length - 1 - _i) * fontSizePx
|
|
175
|
+
: _i * fontSizePx)
|
|
176
|
+
.text(d => d)
|
|
177
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import * as d3 from 'd3'
|
|
2
|
+
import { DEFAULT_VALUE_AXIS } from '../const/sharedPluginParams'
|
|
3
|
+
|
|
4
|
+
// scaleLinear - 連續資料 -> 座標
|
|
5
|
+
export const createValueToAxisScale = ({
|
|
6
|
+
maxValue = 1,
|
|
7
|
+
minValue = 0,
|
|
8
|
+
axisWidth,
|
|
9
|
+
scaleDomain = DEFAULT_VALUE_AXIS.scaleDomain,
|
|
10
|
+
scaleRange = DEFAULT_VALUE_AXIS.scaleRange,
|
|
11
|
+
reverse = false
|
|
12
|
+
}: {
|
|
13
|
+
maxValue: number
|
|
14
|
+
minValue: number
|
|
15
|
+
axisWidth: number
|
|
16
|
+
scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
|
|
17
|
+
scaleRange: [number, number] // 0-1
|
|
18
|
+
reverse?: boolean
|
|
19
|
+
}) => {
|
|
20
|
+
// if (minValue === maxValue) {
|
|
21
|
+
// maxValue += 1 // 避免最大及最小值相同造成無法計算scale
|
|
22
|
+
// minValue -= 1
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
// -- 無值補上預設值 --
|
|
26
|
+
const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DEFAULT_VALUE_AXIS.scaleDomain[0]
|
|
27
|
+
const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DEFAULT_VALUE_AXIS.scaleDomain[1]
|
|
28
|
+
const rangeMin: number = scaleRange[0] ?? DEFAULT_VALUE_AXIS.scaleRange[0]
|
|
29
|
+
const rangeMax: number = scaleRange[1] ?? DEFAULT_VALUE_AXIS.scaleRange[1]
|
|
30
|
+
|
|
31
|
+
// -- 'auto' | 'max' | 'min' 替換成實際值 --
|
|
32
|
+
let domainMinValue: number = (() => {
|
|
33
|
+
if (domainMin === 'auto') {
|
|
34
|
+
return minValue < 0 ? minValue : 0
|
|
35
|
+
} else if (domainMin === 'min') {
|
|
36
|
+
return minValue
|
|
37
|
+
} else {
|
|
38
|
+
return domainMin
|
|
39
|
+
}
|
|
40
|
+
})()
|
|
41
|
+
|
|
42
|
+
let domainMaxValue: number = (() => {
|
|
43
|
+
if (domainMax === 'auto') {
|
|
44
|
+
return maxValue >= 0 ? maxValue : 0
|
|
45
|
+
} else if (domainMax === 'max') {
|
|
46
|
+
return maxValue
|
|
47
|
+
} else {
|
|
48
|
+
return domainMax
|
|
49
|
+
}
|
|
50
|
+
})()
|
|
51
|
+
// let rangeMinValue = axisWidth * rangeMin
|
|
52
|
+
// let rangeMaxValue = axisWidth * rangeMax
|
|
53
|
+
|
|
54
|
+
// -- 計算padding --
|
|
55
|
+
// if (padding > 0) {
|
|
56
|
+
// const stepAmount = maxValue - minValue + (padding * 2)
|
|
57
|
+
// const eachStepWidth = axisWidth / stepAmount
|
|
58
|
+
// const paddingWidth = eachStepWidth * padding
|
|
59
|
+
// rangeMinValue += paddingWidth
|
|
60
|
+
// rangeMaxValue -= paddingWidth
|
|
61
|
+
// }
|
|
62
|
+
|
|
63
|
+
// -- 依場景大小換算 --
|
|
64
|
+
const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
|
|
65
|
+
const axisDomainMaxValue = domainMaxValue / rangeMax
|
|
66
|
+
|
|
67
|
+
// return d3.scaleLinear()
|
|
68
|
+
// .domain([domainMinValue, domainMaxValue])
|
|
69
|
+
// .range([rangeMinValue, rangeMaxValue])
|
|
70
|
+
if (reverse) {
|
|
71
|
+
return d3.scaleLinear()
|
|
72
|
+
.domain([axisDomainMinValue, axisDomainMaxValue])
|
|
73
|
+
.range([axisWidth, 0])
|
|
74
|
+
} else {
|
|
75
|
+
// console.log('domain', [axisDomainMinValue, axisDomainMaxValue])
|
|
76
|
+
return d3.scaleLinear()
|
|
77
|
+
.domain([axisDomainMinValue, axisDomainMaxValue])
|
|
78
|
+
.range([0, axisWidth])
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// scaleLinear - 座標 -> 連續資料
|
|
83
|
+
export const createAxisToValueScale = ({
|
|
84
|
+
maxValue = 1,
|
|
85
|
+
minValue = 0,
|
|
86
|
+
axisWidth,
|
|
87
|
+
scaleDomain = DEFAULT_VALUE_AXIS.scaleDomain,
|
|
88
|
+
scaleRange = DEFAULT_VALUE_AXIS.scaleRange,
|
|
89
|
+
reverse = false
|
|
90
|
+
}: {
|
|
91
|
+
maxValue: number
|
|
92
|
+
minValue: number
|
|
93
|
+
axisWidth: number
|
|
94
|
+
scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
|
|
95
|
+
scaleRange: [number, number] // 0-1
|
|
96
|
+
reverse?: boolean
|
|
97
|
+
}) => {
|
|
98
|
+
if (minValue === maxValue) {
|
|
99
|
+
maxValue += 1 // 避免最大及最小值相同造成無法計算scale
|
|
100
|
+
minValue -= 1
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// -- 無值補上預設值 --
|
|
104
|
+
const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DEFAULT_VALUE_AXIS.scaleDomain[0]
|
|
105
|
+
const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DEFAULT_VALUE_AXIS.scaleDomain[1]
|
|
106
|
+
const rangeMin: number = scaleRange[0] ?? DEFAULT_VALUE_AXIS.scaleRange[0]
|
|
107
|
+
const rangeMax: number = scaleRange[1] ?? DEFAULT_VALUE_AXIS.scaleRange[1]
|
|
108
|
+
|
|
109
|
+
// -- 'auto' | 'max' | 'min' 替換成實際值 --
|
|
110
|
+
let domainMinValue: number = (() => {
|
|
111
|
+
if (domainMin === 'auto') {
|
|
112
|
+
return minValue < 0 ? minValue : 0
|
|
113
|
+
} else if (domainMin === 'min') {
|
|
114
|
+
return minValue
|
|
115
|
+
} else {
|
|
116
|
+
return domainMin
|
|
117
|
+
}
|
|
118
|
+
})()
|
|
119
|
+
|
|
120
|
+
let domainMaxValue: number = (() => {
|
|
121
|
+
if (domainMax === 'auto') {
|
|
122
|
+
return maxValue >= 0 ? maxValue : 0
|
|
123
|
+
} else if (domainMax === 'max') {
|
|
124
|
+
return maxValue
|
|
125
|
+
} else {
|
|
126
|
+
return domainMax
|
|
127
|
+
}
|
|
128
|
+
})()
|
|
129
|
+
// let rangeMinValue = axisWidth * rangeMin
|
|
130
|
+
// let rangeMaxValue = axisWidth * rangeMax
|
|
131
|
+
|
|
132
|
+
// -- 計算padding --
|
|
133
|
+
// if (padding > 0) {
|
|
134
|
+
// const stepAmount = maxValue - minValue + (padding * 2)
|
|
135
|
+
// const eachStepWidth = axisWidth / stepAmount
|
|
136
|
+
// const paddingWidth = eachStepWidth * padding
|
|
137
|
+
// rangeMinValue += paddingWidth
|
|
138
|
+
// rangeMaxValue -= paddingWidth
|
|
139
|
+
// }
|
|
140
|
+
|
|
141
|
+
// -- 依場景大小換算 --
|
|
142
|
+
const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
|
|
143
|
+
const axisDomainMaxValue = domainMaxValue / rangeMax
|
|
144
|
+
|
|
145
|
+
// return d3.scaleLinear()
|
|
146
|
+
// .domain([domainMinValue, domainMaxValue])
|
|
147
|
+
// .range([rangeMinValue, rangeMaxValue])
|
|
148
|
+
if (reverse) {
|
|
149
|
+
return d3.scaleLinear()
|
|
150
|
+
.domain([axisWidth, 0])
|
|
151
|
+
.range([axisDomainMinValue, axisDomainMaxValue])
|
|
152
|
+
} else {
|
|
153
|
+
return d3.scaleLinear()
|
|
154
|
+
.domain([0, axisWidth])
|
|
155
|
+
.range([axisDomainMinValue, axisDomainMaxValue])
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// scalePoint - 非連續資料 -> 座標
|
|
160
|
+
export const createLabelToAxisScale = ({ axisLabels, axisWidth, padding = 0.5 }: {
|
|
161
|
+
axisLabels: string[]
|
|
162
|
+
axisWidth: number
|
|
163
|
+
padding?: number
|
|
164
|
+
// reverse?: boolean
|
|
165
|
+
}) => {
|
|
166
|
+
let range: [d3.NumberValue, d3.NumberValue] = [0, axisWidth]
|
|
167
|
+
|
|
168
|
+
return d3.scalePoint()
|
|
169
|
+
.domain(axisLabels)
|
|
170
|
+
.range(range)
|
|
171
|
+
.padding(padding)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// scaleQuantize - 座標 -> 非連續資料索引
|
|
175
|
+
export const createAxisToLabelIndexScale = ({ axisLabels, axisWidth, padding = 0, reverse = false }:{
|
|
176
|
+
axisLabels: string[] | Date[],
|
|
177
|
+
axisWidth: number
|
|
178
|
+
padding?: number
|
|
179
|
+
reverse?: boolean
|
|
180
|
+
}) => {
|
|
181
|
+
|
|
182
|
+
let range: number[] = axisLabels.map((d: string | Date, i: number) => i)
|
|
183
|
+
if (reverse) {
|
|
184
|
+
range.reverse()
|
|
185
|
+
}
|
|
186
|
+
if (!range.length) {
|
|
187
|
+
// 至少要有一個值否則scale會出錯
|
|
188
|
+
range = [0]
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const step = range.length - 1 + (padding * 2) // 圖軸刻度分段數量
|
|
192
|
+
const stepWidth = axisWidth / step
|
|
193
|
+
const rangePadding = stepWidth * padding - (stepWidth * 0.5) // 實際要計算的範圍是圖軸左右那邊增加0.5
|
|
194
|
+
|
|
195
|
+
return d3.scaleQuantize<number>()
|
|
196
|
+
.domain([rangePadding, axisWidth - rangePadding])
|
|
197
|
+
.range(range)
|
|
198
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as d3 from 'd3'
|
|
2
|
+
|
|
3
|
+
export function getSvgGElementSize (selection: d3.Selection<SVGGElement, any, any, any>): DOMRect {
|
|
4
|
+
try {
|
|
5
|
+
return selection.node()!.getBBox()
|
|
6
|
+
} catch (e: any) {
|
|
7
|
+
throw new Error(e)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 使用字串加入svg
|
|
12
|
+
export function appendSvg (selection: d3.Selection<any, any, any, any>, svgString: string): void {
|
|
13
|
+
function parseSvg (svgString: string) {
|
|
14
|
+
const div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
|
15
|
+
div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+ svgString +'</svg>';
|
|
16
|
+
const frag = document.createDocumentFragment()
|
|
17
|
+
while (frag && div?.firstChild?.firstChild)
|
|
18
|
+
frag.appendChild(div.firstChild.firstChild);
|
|
19
|
+
return frag;
|
|
20
|
+
}
|
|
21
|
+
// 刪除現有子節點
|
|
22
|
+
const node = selection.node()
|
|
23
|
+
while(node.hasChildNodes())
|
|
24
|
+
{
|
|
25
|
+
node.removeChild(node.firstChild);
|
|
26
|
+
}
|
|
27
|
+
// 加入dom
|
|
28
|
+
selection.node().appendChild(parseSvg(svgString))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getD3TransitionEase (easeName: string) {
|
|
32
|
+
if (easeName.substring(0, 4) !== 'ease') {
|
|
33
|
+
return d3.easeCubic
|
|
34
|
+
}
|
|
35
|
+
return (d3 as any)[easeName] ?? d3.easeCubic
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function makeD3Arc ({ axisWidth, innerRadius, outerRadius, padAngle, cornerRadius }: {
|
|
39
|
+
axisWidth: number
|
|
40
|
+
innerRadius: number
|
|
41
|
+
outerRadius: number
|
|
42
|
+
padAngle: number
|
|
43
|
+
cornerRadius: number
|
|
44
|
+
}): d3.Arc<any, d3.DefaultArcObject> {
|
|
45
|
+
const arcScale = d3.scaleLinear()
|
|
46
|
+
.domain([0, 1])
|
|
47
|
+
.range([0, axisWidth / 2])
|
|
48
|
+
|
|
49
|
+
const _outerRadius = arcScale(outerRadius)!
|
|
50
|
+
|
|
51
|
+
return d3.arc()
|
|
52
|
+
.innerRadius(arcScale(innerRadius)!)
|
|
53
|
+
.outerRadius(_outerRadius)
|
|
54
|
+
.padAngle(padAngle)
|
|
55
|
+
.padRadius(_outerRadius)
|
|
56
|
+
.cornerRadius(cornerRadius)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const parseTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string | d3.NumberValue)) => {
|
|
60
|
+
if (tickFormat! instanceof Function == true) {
|
|
61
|
+
const v = (tickFormat as ((text: d3.NumberValue) => string))(value)
|
|
62
|
+
return String(v ?? '')
|
|
63
|
+
}
|
|
64
|
+
return d3.format(tickFormat as string)!(value)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const parseDateTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string | d3.NumberValue)) => {
|
|
68
|
+
if (tickFormat! instanceof Function == true) {
|
|
69
|
+
return (tickFormat as ((text: d3.NumberValue) => string))(value)
|
|
70
|
+
}
|
|
71
|
+
return d3.timeFormat(tickFormat as string)!(value)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function isLightColor (color: string) {
|
|
75
|
+
// 1. 用 HSL 的亮度(較符合數學)
|
|
76
|
+
// const hslColor = d3.hsl(color) // 轉換為 HSL 格式
|
|
77
|
+
// const lightness = hslColor.l // 取得亮度值 (0 ~ 1)
|
|
78
|
+
// 2. 用 LAB 的明度(較符合人眼感知)
|
|
79
|
+
const labColor = d3.lab(color) // 轉換為 LAB 格式
|
|
80
|
+
const lightness = labColor.l // 取得明度值 (0 ~ 100)
|
|
81
|
+
|
|
82
|
+
// console.log(`顏色的亮度為: ${lightness}`);
|
|
83
|
+
|
|
84
|
+
// 判斷顏色深淺
|
|
85
|
+
if (lightness <= 60) {
|
|
86
|
+
// console.log("這是一個深色系");
|
|
87
|
+
return false
|
|
88
|
+
} else {
|
|
89
|
+
// console.log("這是一個淺色系");
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
}
|
|
File without changes
|