@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.
Files changed (208) hide show
  1. package/LICENSE +201 -0
  2. package/dist/orbcharts-plugin-basic.es.js +25335 -0
  3. package/dist/orbcharts-plugin-basic.umd.js +341 -0
  4. package/dist/plugin-basic/src/baseLayers/BaseBars.d.ts +38 -0
  5. package/dist/plugin-basic/src/baseLayers/BaseBarsTriangle.d.ts +37 -0
  6. package/dist/plugin-basic/src/baseLayers/BaseCategoryAxis.d.ts +42 -0
  7. package/dist/plugin-basic/src/baseLayers/BaseDots.d.ts +38 -0
  8. package/dist/plugin-basic/src/baseLayers/BaseLegend.d.ts +31 -0
  9. package/dist/plugin-basic/src/baseLayers/BaseLineAreas.d.ts +36 -0
  10. package/dist/plugin-basic/src/baseLayers/BaseLines.d.ts +36 -0
  11. package/dist/plugin-basic/src/baseLayers/BaseStackedBars.d.ts +41 -0
  12. package/dist/plugin-basic/src/baseLayers/BaseTooltip.d.ts +47 -0
  13. package/dist/plugin-basic/src/baseLayers/BaseValueAxis.d.ts +38 -0
  14. package/dist/plugin-basic/src/baseLayers/BaseXAxis.d.ts +25 -0
  15. package/dist/plugin-basic/src/baseLayers/BaseXZoom.d.ts +22 -0
  16. package/dist/plugin-basic/src/baseLayers/BaseYAxis.d.ts +23 -0
  17. package/dist/plugin-basic/src/baseLayers/types.d.ts +171 -0
  18. package/dist/plugin-basic/src/const/layerIndex.d.ts +10 -0
  19. package/dist/plugin-basic/src/const/sharedPluginParams.d.ts +6 -0
  20. package/dist/plugin-basic/src/index.d.ts +2 -0
  21. package/dist/plugin-basic/src/plugins/CompositionPlot/CompositionPlot.d.ts +22 -0
  22. package/dist/plugin-basic/src/plugins/CompositionPlot/contextObservables.d.ts +40 -0
  23. package/dist/plugin-basic/src/plugins/CompositionPlot/defaults.d.ts +10 -0
  24. package/dist/plugin-basic/src/plugins/CompositionPlot/index.d.ts +3 -0
  25. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Bubbles.d.ts +16 -0
  26. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Indicator.d.ts +0 -0
  27. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Pie.d.ts +16 -0
  28. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/PieEventTexts.d.ts +16 -0
  29. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/PieLabels.d.ts +16 -0
  30. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Rose.d.ts +16 -0
  31. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/RoseLabels.d.ts +16 -0
  32. package/dist/plugin-basic/src/plugins/CompositionPlot/layers/Waffle.d.ts +0 -0
  33. package/dist/plugin-basic/src/plugins/CompositionPlot/types.d.ts +110 -0
  34. package/dist/plugin-basic/src/plugins/CompositionPlot/utils.d.ts +19 -0
  35. package/dist/plugin-basic/src/plugins/HierarchyPlot/HierarchyPlot.d.ts +22 -0
  36. package/dist/plugin-basic/src/plugins/HierarchyPlot/contextObservables.d.ts +16 -0
  37. package/dist/plugin-basic/src/plugins/HierarchyPlot/defaults.d.ts +4 -0
  38. package/dist/plugin-basic/src/plugins/HierarchyPlot/index.d.ts +3 -0
  39. package/dist/plugin-basic/src/plugins/HierarchyPlot/layers/TreeMap.d.ts +16 -0
  40. package/dist/plugin-basic/src/plugins/HierarchyPlot/types.d.ts +29 -0
  41. package/dist/plugin-basic/src/plugins/Legend/Legend.d.ts +22 -0
  42. package/dist/plugin-basic/src/plugins/Legend/contextObservables.d.ts +9 -0
  43. package/dist/plugin-basic/src/plugins/Legend/defaults.d.ts +4 -0
  44. package/dist/plugin-basic/src/plugins/Legend/index.d.ts +3 -0
  45. package/dist/plugin-basic/src/plugins/Legend/layers/Legend.d.ts +16 -0
  46. package/dist/plugin-basic/src/plugins/Legend/types.d.ts +31 -0
  47. package/dist/plugin-basic/src/plugins/Legend/utils.d.ts +19 -0
  48. package/dist/plugin-basic/src/plugins/NetworkPlot/NetworkPlot.d.ts +22 -0
  49. package/dist/plugin-basic/src/plugins/NetworkPlot/contextObservables.d.ts +19 -0
  50. package/dist/plugin-basic/src/plugins/NetworkPlot/defaults.d.ts +5 -0
  51. package/dist/plugin-basic/src/plugins/NetworkPlot/index.d.ts +3 -0
  52. package/dist/plugin-basic/src/plugins/NetworkPlot/layers/ForceDirected.d.ts +16 -0
  53. package/dist/plugin-basic/src/plugins/NetworkPlot/layers/ForceDirectedBubbles.d.ts +16 -0
  54. package/dist/plugin-basic/src/plugins/NetworkPlot/types.d.ts +117 -0
  55. package/dist/plugin-basic/src/plugins/ScatterPlot/ScatterPlot.d.ts +22 -0
  56. package/dist/plugin-basic/src/plugins/ScatterPlot/contextObservables.d.ts +140 -0
  57. package/dist/plugin-basic/src/plugins/ScatterPlot/defaults.d.ts +8 -0
  58. package/dist/plugin-basic/src/plugins/ScatterPlot/index.d.ts +3 -0
  59. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/Scatter.d.ts +16 -0
  60. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/ScatterBubbles.d.ts +16 -0
  61. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XYAux.d.ts +16 -0
  62. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XYAxes.d.ts +16 -0
  63. package/dist/plugin-basic/src/plugins/ScatterPlot/layers/XZoom.d.ts +16 -0
  64. package/dist/plugin-basic/src/plugins/ScatterPlot/types.d.ts +146 -0
  65. package/dist/plugin-basic/src/plugins/SeriesPlot/SeriesPlot.d.ts +22 -0
  66. package/dist/plugin-basic/src/plugins/SeriesPlot/contextObservables.d.ts +77 -0
  67. package/dist/plugin-basic/src/plugins/SeriesPlot/defaults.d.ts +15 -0
  68. package/dist/plugin-basic/src/plugins/SeriesPlot/index.d.ts +3 -0
  69. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Bars.d.ts +16 -0
  70. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/BarsPN.d.ts +16 -0
  71. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/BarsTriangle.d.ts +16 -0
  72. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryAux.d.ts +16 -0
  73. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryAxis.d.ts +16 -0
  74. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/CategoryZoom.d.ts +16 -0
  75. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Dots.d.ts +16 -0
  76. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/LineAreas.d.ts +16 -0
  77. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/Lines.d.ts +16 -0
  78. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/StackedBars.d.ts +16 -0
  79. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/StackedValueAxis.d.ts +16 -0
  80. package/dist/plugin-basic/src/plugins/SeriesPlot/layers/ValueAxis.d.ts +16 -0
  81. package/dist/plugin-basic/src/plugins/SeriesPlot/types.d.ts +140 -0
  82. package/dist/plugin-basic/src/plugins/Tooltip/Tooltip.d.ts +22 -0
  83. package/dist/plugin-basic/src/plugins/Tooltip/contextObservables.d.ts +9 -0
  84. package/dist/plugin-basic/src/plugins/Tooltip/defaults.d.ts +4 -0
  85. package/dist/plugin-basic/src/plugins/Tooltip/index.d.ts +3 -0
  86. package/dist/plugin-basic/src/plugins/Tooltip/layers/Tooltip.d.ts +16 -0
  87. package/dist/plugin-basic/src/plugins/Tooltip/types.d.ts +35 -0
  88. package/dist/plugin-basic/src/plugins/Tooltip/utils.d.ts +19 -0
  89. package/dist/plugin-basic/src/plugins/index.d.ts +7 -0
  90. package/dist/plugin-basic/src/types/BaseLayer.d.ts +3 -0
  91. package/dist/plugin-basic/src/types/Common.d.ts +14 -0
  92. package/dist/plugin-basic/src/types/ComputedData.d.ts +27 -0
  93. package/dist/plugin-basic/src/types/PluginParams.d.ts +66 -0
  94. package/dist/plugin-basic/src/types/index.d.ts +3 -0
  95. package/dist/plugin-basic/src/utils/commonUtils.d.ts +3 -0
  96. package/dist/plugin-basic/src/utils/d3Graphics.d.ts +24 -0
  97. package/dist/plugin-basic/src/utils/d3Scale.d.ts +28 -0
  98. package/dist/plugin-basic/src/utils/d3Utils.d.ts +14 -0
  99. package/dist/plugin-basic/src/utils/graphObservables.d.ts +0 -0
  100. package/dist/plugin-basic/src/utils/gridObservables.d.ts +51 -0
  101. package/dist/plugin-basic/src/utils/multivariateObservables.d.ts +74 -0
  102. package/dist/plugin-basic/src/utils/observables.d.ts +34 -0
  103. package/dist/plugin-basic/src/utils/orbchartsUtils.d.ts +26 -0
  104. package/dist/plugin-basic/src/utils/seriesObservables.d.ts +22 -0
  105. package/dist/plugin-basic/vite.config.d.ts +2 -0
  106. package/dist/src/index.d.ts +1 -0
  107. package/package.json +62 -0
  108. package/src/baseLayers/BaseBars.ts +783 -0
  109. package/src/baseLayers/BaseBarsTriangle.ts +692 -0
  110. package/src/baseLayers/BaseCategoryAxis.ts +708 -0
  111. package/src/baseLayers/BaseDots.ts +495 -0
  112. package/src/baseLayers/BaseLegend.ts +684 -0
  113. package/src/baseLayers/BaseLineAreas.ts +644 -0
  114. package/src/baseLayers/BaseLines.ts +721 -0
  115. package/src/baseLayers/BaseStackedBars.ts +818 -0
  116. package/src/baseLayers/BaseTooltip.ts +435 -0
  117. package/src/baseLayers/BaseValueAxis.ts +612 -0
  118. package/src/baseLayers/BaseXAxis.ts +412 -0
  119. package/src/baseLayers/BaseXZoom.ts +250 -0
  120. package/src/baseLayers/BaseYAxis.ts +371 -0
  121. package/src/baseLayers/types.ts +174 -0
  122. package/src/const/layerIndex.ts +36 -0
  123. package/src/const/sharedPluginParams.ts +29 -0
  124. package/src/index.ts +3 -0
  125. package/src/plugins/CompositionPlot/CompositionPlot.ts +308 -0
  126. package/src/plugins/CompositionPlot/contextObservables.ts +251 -0
  127. package/src/plugins/CompositionPlot/defaults.ts +162 -0
  128. package/src/plugins/CompositionPlot/index.ts +3 -0
  129. package/src/plugins/CompositionPlot/layers/Bubbles.ts +808 -0
  130. package/src/plugins/CompositionPlot/layers/Indicator.ts +0 -0
  131. package/src/plugins/CompositionPlot/layers/Pie.ts +776 -0
  132. package/src/plugins/CompositionPlot/layers/PieEventTexts.ts +326 -0
  133. package/src/plugins/CompositionPlot/layers/PieLabels.ts +651 -0
  134. package/src/plugins/CompositionPlot/layers/Rose.ts +546 -0
  135. package/src/plugins/CompositionPlot/layers/RoseLabels.ts +616 -0
  136. package/src/plugins/CompositionPlot/layers/Waffle.ts +0 -0
  137. package/src/plugins/CompositionPlot/types.ts +129 -0
  138. package/src/plugins/CompositionPlot/utils.ts +53 -0
  139. package/src/plugins/HierarchyPlot/HierarchyPlot.ts +190 -0
  140. package/src/plugins/HierarchyPlot/contextObservables.ts +136 -0
  141. package/src/plugins/HierarchyPlot/defaults.ts +31 -0
  142. package/src/plugins/HierarchyPlot/index.ts +3 -0
  143. package/src/plugins/HierarchyPlot/layers/TreeMap.ts +371 -0
  144. package/src/plugins/HierarchyPlot/types.ts +36 -0
  145. package/src/plugins/Legend/Legend.ts +151 -0
  146. package/src/plugins/Legend/contextObservables.ts +55 -0
  147. package/src/plugins/Legend/defaults.ts +37 -0
  148. package/src/plugins/Legend/index.ts +3 -0
  149. package/src/plugins/Legend/layers/Legend.ts +114 -0
  150. package/src/plugins/Legend/types.ts +45 -0
  151. package/src/plugins/Legend/utils.ts +53 -0
  152. package/src/plugins/NetworkPlot/NetworkPlot.ts +228 -0
  153. package/src/plugins/NetworkPlot/contextObservables.ts +123 -0
  154. package/src/plugins/NetworkPlot/defaults.ts +147 -0
  155. package/src/plugins/NetworkPlot/index.ts +3 -0
  156. package/src/plugins/NetworkPlot/layers/ForceDirected.ts +1048 -0
  157. package/src/plugins/NetworkPlot/layers/ForceDirectedBubbles.ts +1318 -0
  158. package/src/plugins/NetworkPlot/types.ts +146 -0
  159. package/src/plugins/ScatterPlot/ScatterPlot.ts +569 -0
  160. package/src/plugins/ScatterPlot/contextObservables.ts +901 -0
  161. package/src/plugins/ScatterPlot/defaults.ts +212 -0
  162. package/src/plugins/ScatterPlot/index.ts +3 -0
  163. package/src/plugins/ScatterPlot/layers/Scatter.ts +518 -0
  164. package/src/plugins/ScatterPlot/layers/ScatterBubbles.ts +670 -0
  165. package/src/plugins/ScatterPlot/layers/XYAux.ts +686 -0
  166. package/src/plugins/ScatterPlot/layers/XYAxes.ts +205 -0
  167. package/src/plugins/ScatterPlot/layers/XZoom.ts +48 -0
  168. package/src/plugins/ScatterPlot/types.ts +179 -0
  169. package/src/plugins/SeriesPlot/SeriesPlot.ts +494 -0
  170. package/src/plugins/SeriesPlot/contextObservables.ts +726 -0
  171. package/src/plugins/SeriesPlot/defaults.ts +142 -0
  172. package/src/plugins/SeriesPlot/index.ts +3 -0
  173. package/src/plugins/SeriesPlot/layers/Bars.ts +84 -0
  174. package/src/plugins/SeriesPlot/layers/BarsPN.ts +85 -0
  175. package/src/plugins/SeriesPlot/layers/BarsTriangle.ts +89 -0
  176. package/src/plugins/SeriesPlot/layers/CategoryAux.ts +1131 -0
  177. package/src/plugins/SeriesPlot/layers/CategoryAxis.ts +92 -0
  178. package/src/plugins/SeriesPlot/layers/CategoryZoom.ts +233 -0
  179. package/src/plugins/SeriesPlot/layers/Dots.ts +91 -0
  180. package/src/plugins/SeriesPlot/layers/LineAreas.ts +82 -0
  181. package/src/plugins/SeriesPlot/layers/Lines.ts +75 -0
  182. package/src/plugins/SeriesPlot/layers/StackedBars.ts +85 -0
  183. package/src/plugins/SeriesPlot/layers/StackedValueAxis.ts +111 -0
  184. package/src/plugins/SeriesPlot/layers/ValueAxis.ts +111 -0
  185. package/src/plugins/SeriesPlot/types.ts +201 -0
  186. package/src/plugins/Tooltip/Tooltip.ts +159 -0
  187. package/src/plugins/Tooltip/contextObservables.ts +55 -0
  188. package/src/plugins/Tooltip/defaults.ts +458 -0
  189. package/src/plugins/Tooltip/index.ts +3 -0
  190. package/src/plugins/Tooltip/layers/Tooltip.ts +90 -0
  191. package/src/plugins/Tooltip/types.ts +55 -0
  192. package/src/plugins/Tooltip/utils.ts +53 -0
  193. package/src/plugins/index.ts +8 -0
  194. package/src/types/BaseLayer.ts +3 -0
  195. package/src/types/Common.ts +20 -0
  196. package/src/types/ComputedData.ts +55 -0
  197. package/src/types/PluginParams.ts +81 -0
  198. package/src/types/index.ts +3 -0
  199. package/src/utils/commonUtils.ts +31 -0
  200. package/src/utils/d3Graphics.ts +177 -0
  201. package/src/utils/d3Scale.ts +198 -0
  202. package/src/utils/d3Utils.ts +92 -0
  203. package/src/utils/graphObservables.ts +0 -0
  204. package/src/utils/gridObservables.ts +637 -0
  205. package/src/utils/multivariateObservables.ts +790 -0
  206. package/src/utils/observables.ts +357 -0
  207. package/src/utils/orbchartsUtils.ts +335 -0
  208. package/src/utils/seriesObservables.ts +172 -0
@@ -0,0 +1,114 @@
1
+ import * as d3 from 'd3'
2
+ import {
3
+ combineLatest,
4
+ map,
5
+ filter,
6
+ switchMap,
7
+ takeUntil,
8
+ distinctUntilChanged,
9
+ shareReplay,
10
+ debounceTime,
11
+ Observable,
12
+ Subject,
13
+ BehaviorSubject} from 'rxjs'
14
+ import type { LegendExtendContext, LegendPluginParams, LegendParams } from "../types"
15
+ import { defineSVGLayer } from '@orbcharts/core'
16
+ import { validateObject } from '@orbcharts/core'
17
+ import { createBaseLegend } from "../../../baseLayers/BaseLegend"
18
+ import { DEFAULT_SERIES_LEGEND_PARAMS } from "../defaults"
19
+ import { LAYER_INDEX_OF_INFO } from '../../../const/layerIndex'
20
+
21
+ const pluginName = 'Legend'
22
+ const layerName = 'Legend'
23
+
24
+ export const Legend = defineSVGLayer<LegendExtendContext, LegendPluginParams, LegendParams>({
25
+ name: layerName,
26
+ defaultParams: DEFAULT_SERIES_LEGEND_PARAMS,
27
+ layerIndex: LAYER_INDEX_OF_INFO,
28
+ initShow: true,
29
+ validator: (params) => {
30
+ const result = validateObject(params, {
31
+ placement: {
32
+ toBe: '"top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end" | "right" | "right-start" | "right-end"',
33
+ test: (value) => {
34
+ return [
35
+ 'top', 'top-start', 'top-end',
36
+ 'bottom', 'bottom-start', 'bottom-end',
37
+ 'left', 'left-start', 'left-end',
38
+ 'right', 'right-start', 'right-end'
39
+ ].includes(value)
40
+ }
41
+ },
42
+ padding: {
43
+ toBeTypes: ['number']
44
+ },
45
+ backgroundFill: {
46
+ toBeOption: 'ColorType',
47
+ },
48
+ backgroundStroke: {
49
+ toBeOption: 'ColorType',
50
+ },
51
+ gap: {
52
+ toBeTypes: ['number']
53
+ },
54
+ listRectWidth: {
55
+ toBeTypes: ['number']
56
+ },
57
+ listRectHeight: {
58
+ toBeTypes: ['number']
59
+ },
60
+ listRectRadius: {
61
+ toBeTypes: ['number']
62
+ },
63
+ textColorType: {
64
+ toBeOption: 'ColorType',
65
+ }
66
+ })
67
+ return result
68
+ },
69
+ setup: ({ svgG, pluginParams$, layerParams$, context }) => {
70
+
71
+ const destroy$ = new Subject()
72
+
73
+ const legendLabels$: Observable<string[]> = context.SeriesDataMap$.pipe(
74
+ takeUntil(destroy$),
75
+ map(data => {
76
+ return Array.from(data.keys())
77
+ })
78
+ )
79
+
80
+ // 全部列點矩型使用相同樣式參數
81
+ const baseLegendParams$ = layerParams$.pipe(
82
+ takeUntil(destroy$),
83
+ map(d => {
84
+ const labelList = [
85
+ {
86
+ listRectWidth: d.listRectWidth,
87
+ listRectHeight: d.listRectHeight,
88
+ listRectRadius: d.listRectRadius,
89
+ }
90
+ ]
91
+ return {
92
+ ...d,
93
+ labelList
94
+ }
95
+ })
96
+ )
97
+
98
+ const unsubscribeBaseLegend = createBaseLegend({
99
+ pluginName,
100
+ layerName,
101
+ rootSelection: d3.select(context.svg),
102
+ legendLabels$,
103
+ baseLegendParams$,
104
+ layout$: context.layout$,
105
+ theme$: context.theme$,
106
+ fontSizePx$: context.fontSizePx$
107
+ })
108
+
109
+ return () => {
110
+ destroy$.next(undefined)
111
+ unsubscribeBaseLegend()
112
+ }
113
+ }
114
+ })
@@ -0,0 +1,45 @@
1
+
2
+ import { Observable } from 'rxjs'
3
+ import type { ColorType, ModelDatumSeries, EventData } from '@orbcharts/core'
4
+ import type { GraphicStyles, Layout } from '../../types/PluginParams'
5
+ import { ComputedDatumSeries } from '../../types/ComputedData'
6
+ import type { Placement } from '../../types/Common'
7
+
8
+ // context
9
+ export interface LegendExtendContext {
10
+ layout$: Observable<Layout>
11
+ fontSizePx$: Observable<number>
12
+ SeriesDataMap$: Observable<Map<string, ComputedDatumSeries[]>>
13
+ }
14
+
15
+ // plugin params
16
+ export interface LegendPluginParams {
17
+ styles: GraphicStyles
18
+ visibleFilter: (datum: ModelDatumSeries) => boolean | null
19
+ sort: ((a: ModelDatumSeries, b: ModelDatumSeries) => number) | null
20
+ // container: Container
21
+ // separateSeries: boolean
22
+ // separateName: boolean
23
+ datasetIndex: number
24
+ }
25
+
26
+ // all layer params
27
+ export interface LegendAllLayerParams {
28
+ Legend: LegendParams
29
+ }
30
+
31
+ // -- layer params --
32
+
33
+ export interface LegendParams {
34
+ // position: 'top' | 'bottom' | 'left' | 'right'
35
+ // justify: 'start' | 'center' | 'end'
36
+ placement: Placement
37
+ padding: number
38
+ backgroundFill: ColorType
39
+ backgroundStroke: ColorType
40
+ gap: number
41
+ listRectWidth: number
42
+ listRectHeight: number
43
+ listRectRadius: number
44
+ textColorType: ColorType
45
+ }
@@ -0,0 +1,53 @@
1
+ import * as d3 from 'd3'
2
+ // import type { ModelDatumSeries } from '@orbcharts/core'
3
+ import type { ComputedDatumSeries } from '../../types/ComputedData'
4
+ // import type { D3PieDatum, PieDatum } from '../types'
5
+
6
+ // 由d3.pie()建出來的資料格式
7
+ export interface D3PieDatum {
8
+ data: any
9
+ index: number,
10
+ value: number,
11
+ startAngle: number,
12
+ endAngle: number,
13
+ padAngle: number,
14
+ }
15
+
16
+ export interface PieDatum extends D3PieDatum {
17
+ data: ComputedDatumSeries
18
+ id: string
19
+ }
20
+
21
+ export function makePieData ({ data, startAngle, endAngle }: {
22
+ data: ComputedDatumSeries[]
23
+ startAngle: number
24
+ endAngle: number
25
+ // itemLabels: string[]
26
+ // arcLabels: string[]
27
+ }): PieDatum[] {
28
+ let pie = d3.pie<any, any>()
29
+ .startAngle(startAngle)
30
+ // .endAngle(startAngle + (endAngle - startAngle) * t)
31
+ .endAngle(endAngle)
32
+ .value(d => d.value)
33
+ // .value((d) => d.visible == false ? 0 : d.value)
34
+ // .sort(null) // 不要排序
35
+ .sort((a, b) => a.seq - b.seq)
36
+ // .sort((a: any, b: any) => {
37
+ // return b.value - a.value
38
+ // })
39
+ // .sort(d3.ascending)
40
+ const pieData = pie(data)
41
+ return pieData.map((d: D3PieDatum, i: number) => {
42
+ // const itemLabel = d.data.itemLabel
43
+ let _d: any = d
44
+ _d.id = d.data.id
45
+ return _d
46
+ // return {
47
+ // ...d,
48
+ // itemIndex: itemLabels.indexOf(itemLabel),
49
+ // itemLabel,
50
+ // id: d.data.id,
51
+ // }
52
+ })
53
+ }
@@ -0,0 +1,228 @@
1
+ import * as d3 from 'd3'
2
+ import {
3
+ shareReplay,
4
+ map,
5
+ filter,
6
+ combineLatest,
7
+ debounceTime,
8
+ distinctUntilChanged,
9
+ Subject,
10
+ switchMap,
11
+ Observable,
12
+ BehaviorSubject
13
+ } from 'rxjs'
14
+
15
+ import type { NetworkPlotExtendContext, NetworkPlotPluginParams, NetworkPlotAllLayerParams } from './types'
16
+ import { defineSVGPlugin } from '@orbcharts/core'
17
+ import { validateObject } from '@orbcharts/core'
18
+ import { DEFAULT_NETWORK_PLOT_PARAMS } from './defaults'
19
+ import {
20
+ categoryDataMapObservable,
21
+ containerSizeObservable,
22
+ layoutObservable,
23
+ fontSizePxObservable,
24
+ highlightObservable,
25
+ seriesDataMapObservable
26
+ } from '../../utils/observables'
27
+ import {
28
+ multivariateComputedDataObservable,
29
+ categoryLabelsObservable,
30
+ NodeMapObservable,
31
+ EdgeMapObservable,
32
+ graphVisibleComputedDataObservable
33
+ } from './contextObservables'
34
+ import { ForceDirected } from './layers/ForceDirected'
35
+ import { ForceDirectedBubbles } from './layers/ForceDirectedBubbles'
36
+ const forceDirected = new ForceDirected()
37
+ const forceDirectedBubbles = new ForceDirectedBubbles()
38
+
39
+ export const NetworkPlot = defineSVGPlugin<
40
+ NetworkPlotExtendContext,
41
+ NetworkPlotPluginParams,
42
+ NetworkPlotAllLayerParams
43
+ >({
44
+ name: 'NetworkPlot',
45
+ defaultParams: DEFAULT_NETWORK_PLOT_PARAMS,
46
+ layers: [forceDirected, forceDirectedBubbles],
47
+ setup: (props) => {
48
+
49
+ const selectedGraphData$ = combineLatest({
50
+ graphData: props.context.graphData$,
51
+ datasetIndex: props.pluginParams$.pipe(
52
+ map(pluginParams => pluginParams.datasetIndex)
53
+ )
54
+ }).pipe(
55
+ debounceTime(0),
56
+ map(({ graphData, datasetIndex }) => graphData[datasetIndex]),
57
+ shareReplay(1)
58
+ )
59
+
60
+ const layout$ = layoutObservable({
61
+ size$: props.context.size$,
62
+ padding$: props.pluginParams$.pipe(
63
+ map(pluginParams => pluginParams.styles.padding)
64
+ )
65
+ }).pipe(
66
+ shareReplay(1)
67
+ )
68
+
69
+ // combineLatest({
70
+ // layout: layout$,
71
+ // plugins: props.context.plugins$
72
+ // }).pipe(
73
+ // debounceTime(0)
74
+ // ).subscribe(data => {
75
+ // d3
76
+ // .select(props.context.svg)
77
+ // .selectAll(':scope > g') // 所有 layer
78
+ // .attr('transform', `translate(${data.layout.left}, ${data.layout.top})`)
79
+ // })
80
+
81
+ // const layoutSubscription = layout$.subscribe(layout => {
82
+ // props.svg.setAttribute('transform', `translate(${layout.left}, ${layout.top})`)
83
+ // })
84
+
85
+ const computedData$ = multivariateComputedDataObservable({
86
+ selectedGraphData$: selectedGraphData$,
87
+ pluginParams$: props.pluginParams$
88
+ }).pipe(
89
+ shareReplay(1)
90
+ )
91
+
92
+ const fontSizePx$ = fontSizePxObservable(props.context.theme$).pipe(
93
+ shareReplay(1)
94
+ )
95
+
96
+ const graphHighlightNodes$ = highlightObservable({
97
+ datumList$: computedData$.pipe(map(data => data.nodes)),
98
+ styles$: props.pluginParams$.pipe(map(pluginParams => pluginParams.styles)),
99
+ event$: props.context.event$
100
+ }).pipe(
101
+ shareReplay(1)
102
+ )
103
+
104
+ const graphHighlightEdges$ = highlightObservable({
105
+ datumList$: computedData$.pipe(map(data => data.edges)),
106
+ styles$: props.pluginParams$.pipe(map(pluginParams => pluginParams.styles)),
107
+ event$: props.context.event$
108
+ }).pipe(
109
+ shareReplay(1)
110
+ )
111
+
112
+ const CategoryNodeMap$ = categoryDataMapObservable({
113
+ datumList$: computedData$.pipe(map(data => data.nodes))
114
+ }).pipe(
115
+ shareReplay(1)
116
+ )
117
+
118
+ const CategoryEdgeMap$ = categoryDataMapObservable({
119
+ datumList$: computedData$.pipe(map(data => data.edges))
120
+ }).pipe(
121
+ shareReplay(1)
122
+ )
123
+
124
+ const NodeMap$ = NodeMapObservable(computedData$).pipe(
125
+ shareReplay(1)
126
+ )
127
+
128
+ const EdgeMap$ = EdgeMapObservable(computedData$).pipe(
129
+ shareReplay(1)
130
+ )
131
+
132
+ const categoryLabels$ = categoryLabelsObservable(CategoryNodeMap$, CategoryEdgeMap$).pipe(
133
+ shareReplay(1)
134
+ )
135
+
136
+ const visibleComputedData$ = graphVisibleComputedDataObservable({
137
+ computedData$: computedData$,
138
+ NodeMap$
139
+ }).pipe(
140
+ shareReplay(1)
141
+ )
142
+
143
+ const extendsContext: NetworkPlotExtendContext = {
144
+ layout$,
145
+ computedData$,
146
+ fontSizePx$,
147
+ graphHighlightNodes$,
148
+ graphHighlightEdges$,
149
+ categoryLabels$,
150
+ CategoryNodeMap$,
151
+ CategoryEdgeMap$,
152
+ NodeMap$,
153
+ EdgeMap$,
154
+ visibleComputedData$
155
+ }
156
+
157
+ props.context = {
158
+ ...props.context,
159
+ ...extendsContext,
160
+ }
161
+
162
+ return () => {
163
+ // layoutSubscription.unsubscribe()
164
+ }
165
+ },
166
+ validator: (params: NetworkPlotPluginParams) => {
167
+ const result = validateObject(params, {
168
+ styles: {
169
+ toBeTypes: ['object'],
170
+ },
171
+ visibleFilter: {
172
+ toBeTypes: ['Function']
173
+ },
174
+ datasetIndex: {
175
+ toBeTypes: ['number']
176
+ }
177
+ })
178
+ if (result.status === 'error') {
179
+ return result
180
+ }
181
+ if (params.styles) {
182
+ const stylesResult = validateObject(params.styles, {
183
+ padding: {
184
+ toBeTypes: ['object']
185
+ },
186
+ highlightTarget: {
187
+ toBeTypes: ['string']
188
+ },
189
+ highlightDefault: {
190
+ toBeTypes: ['string', 'null']
191
+ },
192
+ unhighlightedOpacity: {
193
+ toBeTypes: ['number']
194
+ },
195
+ transitionDuration: {
196
+ toBeTypes: ['number']
197
+ },
198
+ transitionEase: {
199
+ toBeTypes: ['string']
200
+ }
201
+ })
202
+ if (stylesResult.status === 'error') {
203
+ return stylesResult
204
+ }
205
+ if (params.styles.padding) {
206
+ const paddingResult = validateObject(params.styles.padding, {
207
+ top: {
208
+ toBeTypes: ['number']
209
+ },
210
+ right: {
211
+ toBeTypes: ['number']
212
+ },
213
+ bottom: {
214
+ toBeTypes: ['number']
215
+ },
216
+ left: {
217
+ toBeTypes: ['number']
218
+ }
219
+ })
220
+ if (paddingResult.status === 'error') {
221
+ return paddingResult
222
+ }
223
+ }
224
+ }
225
+
226
+ return result
227
+ },
228
+ })
@@ -0,0 +1,123 @@
1
+ import {
2
+ combineLatest,
3
+ distinctUntilChanged,
4
+ debounceTime,
5
+ filter,
6
+ map,
7
+ merge,
8
+ takeUntil,
9
+ shareReplay,
10
+ switchMap,
11
+ Subject,
12
+ Observable } from 'rxjs'
13
+ import type { ModelData, ModelDatumSeries } from '@orbcharts/core'
14
+ import type {
15
+ ComputedData,
16
+ ComputedDatumGraphNode,
17
+ ComputedDatumGraphEdge,
18
+ } from '../../types'
19
+ import { NetworkPlotPluginParams } from './types'
20
+
21
+ export const multivariateComputedDataObservable = ({ selectedGraphData$, pluginParams$ }: {
22
+ selectedGraphData$: Observable<ModelData<'graph'>>
23
+ pluginParams$: Observable<NetworkPlotPluginParams>
24
+ }): Observable<ComputedData<'graph'>> => {
25
+ return combineLatest({
26
+ selectedGraphData: selectedGraphData$,
27
+ pluginParams: pluginParams$
28
+ }).pipe(
29
+ debounceTime(0),
30
+ map(({ selectedGraphData, pluginParams }) => {
31
+ const filteredNodes = selectedGraphData.nodes.map((datum, index) => {
32
+ const visibleFilter = pluginParams.visibleFilter
33
+ return {
34
+ ...datum,
35
+ visible: visibleFilter ? visibleFilter(datum) : true,
36
+ }
37
+ })
38
+ const NodesMap: Map<string, ComputedDatumGraphNode> = new Map(
39
+ filteredNodes.map(d => [d.id, d])
40
+ )
41
+ const filteredEdges = selectedGraphData.edges.map((datum, index) => {
42
+ const sourceNode = NodesMap.get(datum.source)
43
+ const targetNode = NodesMap.get(datum.target)
44
+ return {
45
+ ...datum,
46
+ visible: sourceNode && targetNode && sourceNode.visible && targetNode.visible
47
+ ? true
48
+ : false
49
+ }
50
+ })
51
+ return {
52
+ nodes: filteredNodes,
53
+ edges: filteredEdges
54
+ }
55
+ })
56
+ )
57
+ }
58
+
59
+ export const categoryLabelsObservable = (
60
+ CategoryNodeMap$: Observable<Map<string, ComputedDatumGraphNode[]>>,
61
+ CategoryEdgeMap$: Observable<Map<string, ComputedDatumGraphEdge[]>>
62
+ ): Observable<string[]> => {
63
+ return combineLatest({
64
+ CategoryNodeMap: CategoryNodeMap$,
65
+ CategoryEdgeMap: CategoryEdgeMap$
66
+ }).pipe(
67
+ switchMap(async d => d),
68
+ map(data => {
69
+ return [...Array.from(data.CategoryNodeMap.keys()), ...Array.from(data.CategoryEdgeMap.keys())]
70
+ }),
71
+ distinctUntilChanged((a, b) => {
72
+ return JSON.stringify(a) === JSON.stringify(b)
73
+ }),
74
+ )
75
+ }
76
+
77
+ export const NodeMapObservable = (computedData$: Observable<ComputedData<'graph'>>) => {
78
+ return computedData$.pipe(
79
+ map(data => {
80
+ const nodeMap = new Map<string, ComputedDatumGraphNode>()
81
+ data.nodes.forEach(node => {
82
+ nodeMap.set(node.id, node)
83
+ })
84
+ return nodeMap
85
+ }),
86
+ )
87
+ }
88
+
89
+ export const EdgeMapObservable = (computedData$: Observable<ComputedData<'graph'>>) => {
90
+ return computedData$.pipe(
91
+ map(data => {
92
+ const edgeMap = new Map<string, ComputedDatumGraphEdge>()
93
+ data.edges.forEach(edge => {
94
+ edgeMap.set(edge.id, edge)
95
+ })
96
+ return edgeMap
97
+ }),
98
+ )
99
+ }
100
+
101
+ // 所有可見的節點
102
+ export const graphVisibleComputedDataObservable = ({ computedData$, NodeMap$ }: {
103
+ computedData$: Observable<ComputedData<'graph'>>
104
+ NodeMap$: Observable<Map<string, ComputedDatumGraphNode>>
105
+ }) => {
106
+ return combineLatest({
107
+ computedData: computedData$,
108
+ NodeMap: NodeMap$
109
+ }).pipe(
110
+ switchMap(async d => d),
111
+ map(data => {
112
+ return {
113
+ nodes: data.computedData.nodes.filter(node => node.visible),
114
+ edges: data.computedData.edges
115
+ .filter(edge => edge.visible)
116
+ // 依照節點是否存在篩選
117
+ .filter(edge => {
118
+ return data.NodeMap.has(edge.source) && data.NodeMap.has(edge.target)
119
+ })
120
+ }
121
+ })
122
+ )
123
+ }
@@ -0,0 +1,147 @@
1
+ import type {
2
+ ForceDirectedParams,
3
+ ForceDirectedBubblesParams,
4
+ } from './types'
5
+ import { NetworkPlotPluginParams } from './types'
6
+
7
+ export const DEFAULT_NETWORK_PLOT_PARAMS: NetworkPlotPluginParams = {
8
+ styles: {
9
+ padding: {
10
+ top: 20,
11
+ right: 20,
12
+ bottom: 20,
13
+ left: 20
14
+ },
15
+ highlightTarget: 'datum',
16
+ highlightDefault: null,
17
+ unhighlightedOpacity: 0.3,
18
+ transitionDuration: 800,
19
+ transitionEase: 'easeCubic'
20
+ },
21
+ visibleFilter: (datum) => true,
22
+ datasetIndex: 0
23
+ }
24
+
25
+ export const DEFAULT_FORCE_DIRECTED_PARAMS: ForceDirectedParams = {
26
+ // node: {
27
+ // dotRadius: 10,
28
+ // dotFillColorType: 'label',
29
+ // dotStrokeColorType: 'label',
30
+ // dotStrokeWidth: 1,
31
+ // dotStyleFn: (node) => '',
32
+ // labelColorType: 'primary',
33
+ // labelSizeFixed: false,
34
+ // labelStyleFn: (node) => 'text-shadow:0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff'
35
+ // },
36
+ // edge: {
37
+ // arrowColorType: 'primary',
38
+ // arrowStrokeWidth: 1.5,
39
+ // arrowWidth: 5,
40
+ // arrowHeight: 5,
41
+ // arrowStyleFn: (node) => '',
42
+ // labelColorType: 'secondary',
43
+ // labelSizeFixed: false,
44
+ // labelStyleFn: (node) => ''
45
+ // },
46
+ dot: {
47
+ radius: 10,
48
+ fillColorType: 'data',
49
+ strokeColorType: 'data',
50
+ strokeWidth: 1,
51
+ styleFn: (node) => '',
52
+ },
53
+ dotLabel: {
54
+ colorType: 'primary',
55
+ sizeFixed: false,
56
+ // styleFn: (node) => 'text-shadow:0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff'
57
+ styleFn: (node) => ''
58
+ },
59
+ arrow: {
60
+ colorType: 'primary',
61
+ strokeWidth: 1.5,
62
+ pointerWidth: 5,
63
+ pointerHeight: 5,
64
+ styleFn: (node) => '',
65
+ },
66
+ arrowLabel: {
67
+ colorType: 'primary',
68
+ sizeFixed: false,
69
+ styleFn: (node) => ''
70
+ },
71
+ force: {
72
+ nodeStrength: -500, // 泡泡引力
73
+ linkDistance: 100, // 連結長度
74
+ velocityDecay: 0.1, // 衰減數
75
+ alphaDecay: 0.05
76
+ // collisionSpacing: 2 // 泡泡間距
77
+ },
78
+ zoomable: true,
79
+ transform: {
80
+ x: 0,
81
+ y: 0,
82
+ k: 1
83
+ },
84
+ scaleExtent: {
85
+ min: 0,
86
+ max: Infinity
87
+ }
88
+ }
89
+ DEFAULT_FORCE_DIRECTED_PARAMS.dot.styleFn.toString = () => `(node) => ''`
90
+ DEFAULT_FORCE_DIRECTED_PARAMS.dotLabel.styleFn.toString = () => `(node) => ''`
91
+ DEFAULT_FORCE_DIRECTED_PARAMS.arrow.styleFn.toString = () => `(edge) => ''`
92
+ DEFAULT_FORCE_DIRECTED_PARAMS.arrowLabel.styleFn.toString = () => `(edge) => ''`
93
+
94
+ export const DEFAULT_FORCE_DIRECTED_BUBBLES_PARAMS: ForceDirectedBubblesParams = {
95
+ bubble: {
96
+ radiusMin: 15,
97
+ radiusMax: 45,
98
+ arcScaleType: 'area',
99
+ fillColorType: 'data',
100
+ strokeColorType: 'data',
101
+ strokeWidth: 1,
102
+ styleFn: (node) => '',
103
+ },
104
+ bubbleLabel: {
105
+ fillRate: 0.9,
106
+ lineHeight: 1,
107
+ maxLineLength: 6,
108
+ wordBreakAll: true,
109
+ colorType: 'dataContrast',
110
+ styleFn: (node) => ''
111
+ },
112
+ arrow: {
113
+ colorType: 'primary',
114
+ strokeWidthMin: 1.5,
115
+ strokeWidthMax: 4.5,
116
+ pointerWidth: 5,
117
+ pointerHeight: 5,
118
+ styleFn: (node) => '',
119
+ },
120
+ arrowLabel: {
121
+ colorType: 'primary',
122
+ sizeFixed: false,
123
+ styleFn: (node) => ''
124
+ },
125
+ force: {
126
+ nodeStrength: -500, // 泡泡引力
127
+ linkDistance: 130, // 連結長度
128
+ velocityDecay: 0.1, // 衰減數
129
+ alphaDecay: 0.05
130
+ // collisionSpacing: 2 // 泡泡間距
131
+ },
132
+ zoomable: true,
133
+ transform: {
134
+ x: 0,
135
+ y: 0,
136
+ k: 1
137
+ },
138
+ scaleExtent: {
139
+ min: 0,
140
+ max: Infinity
141
+ }
142
+ }
143
+ DEFAULT_FORCE_DIRECTED_BUBBLES_PARAMS.bubble.styleFn.toString = () => `(node) => ''`
144
+ DEFAULT_FORCE_DIRECTED_BUBBLES_PARAMS.bubbleLabel.styleFn.toString = () => `(node) => ''`
145
+ DEFAULT_FORCE_DIRECTED_BUBBLES_PARAMS.arrow.styleFn.toString = () => `(edge) => ''`
146
+ DEFAULT_FORCE_DIRECTED_BUBBLES_PARAMS.arrowLabel.styleFn.toString = () => `(edge) => ''`
147
+