@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,371 @@
1
+ import * as d3 from 'd3'
2
+ import {
3
+ combineLatest,
4
+ map,
5
+ of,
6
+ first,
7
+ switchMap,
8
+ debounceTime,
9
+ takeUntil,
10
+ distinctUntilChanged,
11
+ shareReplay,
12
+ iif,
13
+ EMPTY,
14
+ Observable,
15
+ Subject,
16
+ BehaviorSubject
17
+ } from 'rxjs'
18
+ import type { Theme, EventData } from '@orbcharts/core'
19
+ import type { HierarchyPlotPluginParams, HierarchyPlotExtendContext, TreeMapParams } from '../types'
20
+ import { defineSVGLayer } from '@orbcharts/core'
21
+ import { validateObject } from '@orbcharts/core'
22
+ import { DEFAULT_TREE_MAP_PARAMS } from "../defaults"
23
+ import { multivariateSelectionsObservable } from "../../../utils/multivariateObservables"
24
+ import { getColor, getDatumColor } from '../../../utils/orbchartsUtils'
25
+ import { createClassName, createUniID } from '../../../utils/orbchartsUtils'
26
+ import type { ComputedData, ComputedDatumTree } from '../../../types/ComputedData'
27
+ import type { ContainerPosition, GraphicStyles, Layout } from '../../../types/PluginParams'
28
+ import { LAYER_INDEX_OF_GRAPHIC } from '../../../const/layerIndex'
29
+
30
+ const pluginName = 'HierarchyPlot'
31
+ const layerName = 'TreeMap'
32
+
33
+ const treeClassName = createClassName(pluginName, layerName, 'tree')
34
+ const tileClassName = createClassName(pluginName, layerName, 'tile')
35
+
36
+ function renderTree ({ selection, treeData, layerParams, theme, fontSizePx }: {
37
+ selection: d3.Selection<any, any, any, any>
38
+ treeData: d3.HierarchyRectangularNode<ComputedData<'tree'>>[]
39
+ layerParams: TreeMapParams
40
+ theme: Theme
41
+ fontSizePx: number
42
+ }) {
43
+ const padding = fontSizePx / 2
44
+ const lineHeight = fontSizePx // 行高
45
+
46
+ const cell = selection.selectAll<SVGGElement, d3.HierarchyRectangularNode<ComputedData<'tree'>>>(`g.${treeClassName}`)
47
+ .data(treeData, d => d.data.id)
48
+ .join('g')
49
+ .attr('class', treeClassName)
50
+
51
+ cell
52
+ // .transition()
53
+ // .duration(fullChartParams.transitionDuration)
54
+ .attr('transform', (d) => !d.x0 || !d.y0 ? null : `translate(${d.x0},${d.y0})`)
55
+ .each((d, i, nodes) => {
56
+ const eachCell = d3.select(nodes[i])
57
+
58
+ const tile = eachCell
59
+ .selectAll<SVGRectElement, d3.HierarchyRectangularNode<ComputedData<'tree'>>>(`rect.${tileClassName}`)
60
+ .data([d], d => d.data.id)
61
+ .join('rect')
62
+ .attr("id", d => d.data.id)
63
+ .attr("class", tileClassName)
64
+ .attr('cursor', 'pointer')
65
+ .attr("width", (d) => d.x1 - d.x0)
66
+ .attr("height", (d) => d.y1 - d.y0)
67
+ .attr('fill', d => d.data.color)
68
+ .attr('data-name', d => d.data.name)
69
+ .attr('data-category', d => d.data.series)
70
+ .attr('data-value', d => d.data.value)
71
+
72
+ const label = eachCell
73
+ .selectAll('g')
74
+ .data([d])
75
+ .join('g')
76
+ .each((d, i, nodes) => {
77
+ const eachLabel = d3.select(nodes[i])
78
+ const text = eachLabel
79
+ .selectAll('text')
80
+ .data([d])
81
+ .join('text')
82
+ .text(d => d.data.name)
83
+ .attr('dominant-baseline', 'hanging')
84
+ .attr("x", padding)
85
+ .attr("y", padding)
86
+ .attr('font-size', theme.fontSize)
87
+ .each(function(d) {
88
+ // -- tspan(自動斷行) --
89
+ const textElement = d3.select(this);
90
+ const words = d.data.name.split(/\s+/).reverse() // 以空隔分割字串
91
+ let word;
92
+ let line: string[] = []
93
+ const x = textElement.attr("x")
94
+ let y = textElement.attr("y")
95
+ let dy = 0
96
+ let tspan = textElement
97
+ .text(null)
98
+ .append("tspan")
99
+ .attr('cursor', 'pointer')
100
+ .attr('fill', getDatumColor({
101
+ colorType: layerParams.labelColorType,
102
+ datum: d.data,
103
+ theme
104
+ }))
105
+ .attr('font-size', theme.fontSize)
106
+ .attr("x", x)
107
+ .attr("y", y)
108
+
109
+ while (word = words.pop()) {
110
+ line.push(word)
111
+ tspan.text(line.join(" "))
112
+ if (tspan.node().getComputedTextLength() > (d.x1 - d.x0 - padding)) {
113
+ line.pop()
114
+ tspan.text(line.join(" "))
115
+ line = [word]
116
+ dy += lineHeight
117
+ tspan = textElement
118
+ .append("tspan")
119
+ .attr('cursor', 'pointer')
120
+ .attr('fill', getDatumColor({
121
+ colorType: layerParams.labelColorType,
122
+ datum: d.data,
123
+ theme
124
+ }))
125
+ .attr('font-size', theme.fontSize)
126
+ .attr("x", x)
127
+ .attr("y", y)
128
+ .attr("dy", dy + "px")
129
+ .text(word)
130
+ }
131
+ }
132
+ })
133
+ })
134
+
135
+ })
136
+
137
+ return cell
138
+ }
139
+
140
+ function highlight ({ selection, ids, styles }: {
141
+ selection: d3.Selection<any, d3.HierarchyRectangularNode<ComputedData<'tree'>>, any, any>
142
+ ids: string[]
143
+ styles: GraphicStyles
144
+ }) {
145
+ selection.interrupt('highlight')
146
+
147
+ if (!ids.length) {
148
+ // remove highlight
149
+ selection
150
+ .transition('highlight')
151
+ .duration(200)
152
+ .style('opacity', 1)
153
+ return
154
+ }
155
+
156
+ selection
157
+ .each((d, i, n) => {
158
+ if (ids.includes(d.data.id)) {
159
+ d3.select(n[i])
160
+ .style('opacity', 1)
161
+ } else {
162
+ d3.select(n[i])
163
+ .style('opacity', styles.unhighlightedOpacity)
164
+ }
165
+ })
166
+ }
167
+
168
+ export const TreeMap = defineSVGLayer<HierarchyPlotExtendContext, HierarchyPlotPluginParams, TreeMapParams>({
169
+ name: layerName,
170
+ defaultParams: DEFAULT_TREE_MAP_PARAMS,
171
+ layerIndex: LAYER_INDEX_OF_GRAPHIC,
172
+ initShow: true,
173
+ validator: (params) => {
174
+ const result = validateObject(params, {
175
+ paddingInner: {
176
+ toBeTypes: ['number']
177
+ },
178
+ paddingOuter: {
179
+ toBeTypes: ['number']
180
+ },
181
+ labelColorType: {
182
+ toBeOption: 'ColorType'
183
+ },
184
+ squarifyRatio: {
185
+ toBeTypes: ['number']
186
+ },
187
+ sort: {
188
+ toBeTypes: ['Function']
189
+ }
190
+ })
191
+ return result
192
+ },
193
+ setup: ({ svgG, pluginParams$, layerParams$, context }) => {
194
+
195
+ const destroy$ = new Subject()
196
+
197
+ const selection = d3.select(svgG)
198
+
199
+ context.layout$
200
+ .pipe(
201
+ takeUntil(destroy$)
202
+ )
203
+ .subscribe(layout => {
204
+ selection
205
+ .attr('transform', `translate(${layout.left}, ${layout.top})`)
206
+ })
207
+
208
+ const treeData$ = combineLatest({
209
+ layout: context.layout$,
210
+ visibleComputedData: context.visibleComputedData$,
211
+ layerParams: layerParams$
212
+ }).pipe(
213
+ takeUntil(destroy$),
214
+ debounceTime(0),
215
+ map(data => {
216
+ const treemap = d3.treemap()
217
+ .size([data.layout.width, data.layout.height])
218
+ .paddingInner(data.layerParams.paddingInner)
219
+ .paddingOuter(data.layerParams.paddingOuter)
220
+ .round(true)
221
+ .tile(d3.treemapSquarify.ratio(data.layerParams.squarifyRatio))
222
+
223
+ const root = d3.hierarchy(data.visibleComputedData)
224
+ .sum(d => d.value)
225
+ .sort(data.layerParams.sort as (a: any, b: any) => number)
226
+
227
+ //call treemap
228
+ treemap(root)
229
+
230
+ const treeData: d3.HierarchyRectangularNode<ComputedDatumTree>[] = root.leaves() as any
231
+
232
+ return treeData
233
+ })
234
+ )
235
+
236
+ const cellSelection$ = combineLatest({
237
+ selection: of(selection),
238
+ treeData: treeData$,
239
+ layerParams: layerParams$,
240
+ theme: context.theme$,
241
+ fontSizePx: context.fontSizePx$
242
+ }).pipe(
243
+ takeUntil(destroy$),
244
+ debounceTime(0),
245
+ map(data => {
246
+ return renderTree({
247
+ selection,
248
+ treeData: data.treeData,
249
+ layerParams: data.layerParams,
250
+ theme: data.theme,
251
+ fontSizePx: data.fontSizePx
252
+ })
253
+ })
254
+ )
255
+
256
+ // const highlightTarget$ = pluginParams$.pipe(
257
+ // takeUntil(destroy$),
258
+ // map(d => d.styles.highlightTarget),
259
+ // distinctUntilChanged()
260
+ // )
261
+
262
+ cellSelection$.subscribe(cellSelection => {
263
+ cellSelection
264
+ .on('mouseover', (event, datum) => {
265
+ event.stopPropagation()
266
+
267
+ context.eventTrigger$.next({
268
+ // type: 'tree',
269
+ // eventName: 'mouseover',
270
+ // pluginName,
271
+ // highlightTarget: data.highlightTarget,
272
+ // datum: datum.data,
273
+ // category: data.CategoryDataMap.get(datum.data.categoryLabel)!,
274
+ // categoryIndex: datum.data.categoryIndex,
275
+ // categoryLabel: datum.data.categoryLabel,
276
+ // event,
277
+ // data: data.computedData
278
+ eventName: 'mouseover',
279
+ pluginName,
280
+ layerName,
281
+ target: datum.data,
282
+ event
283
+ })
284
+ })
285
+ .on('mousemove', (event, datum) => {
286
+ event.stopPropagation()
287
+
288
+ context.eventTrigger$.next({
289
+ // type: 'tree',
290
+ // eventName: 'mousemove',
291
+ // pluginName,
292
+ // highlightTarget: data.highlightTarget,
293
+ // datum: datum.data,
294
+ // category: data.CategoryDataMap.get(datum.data.categoryLabel)!,
295
+ // categoryIndex: datum.data.categoryIndex,
296
+ // categoryLabel: datum.data.categoryLabel,
297
+ // event,
298
+ // data: data.computedData
299
+ eventName: 'mousemove',
300
+ pluginName,
301
+ layerName,
302
+ target: datum.data,
303
+ event
304
+ })
305
+ })
306
+ .on('mouseout', (event, datum) => {
307
+ event.stopPropagation()
308
+
309
+ context.eventTrigger$.next({
310
+ // type: 'tree',
311
+ // eventName: 'mouseout',
312
+ // pluginName,
313
+ // highlightTarget: data.highlightTarget,
314
+ // datum: datum.data,
315
+ // category: data.CategoryDataMap.get(datum.data.categoryLabel)!,
316
+ // categoryIndex: datum.data.categoryIndex,
317
+ // categoryLabel: datum.data.categoryLabel,
318
+ // event,
319
+ // data: data.computedData
320
+ eventName: 'mouseout',
321
+ pluginName,
322
+ layerName,
323
+ target: datum.data,
324
+ event
325
+ })
326
+ })
327
+ .on('click', (event, datum) => {
328
+ event.stopPropagation()
329
+
330
+ context.eventTrigger$.next({
331
+ // type: 'tree',
332
+ // eventName: 'click',
333
+ // pluginName,
334
+ // highlightTarget: data.highlightTarget,
335
+ // datum: datum.data,
336
+ // category: data.CategoryDataMap.get(datum.data.categoryLabel)!,
337
+ // categoryIndex: datum.data.categoryIndex,
338
+ // categoryLabel: datum.data.categoryLabel,
339
+ // event,
340
+ // data: data.computedData
341
+ eventName: 'click',
342
+ pluginName,
343
+ layerName,
344
+ target: datum.data,
345
+ event
346
+ })
347
+ })
348
+ })
349
+
350
+ combineLatest({
351
+ cellSelection: cellSelection$,
352
+ highlight: context.treeHighlight$.pipe(
353
+ map(data => data.map(d => d.id))
354
+ ),
355
+ styles: pluginParams$.pipe(map(p => p.styles)),
356
+ }).pipe(
357
+ takeUntil(destroy$),
358
+ debounceTime(0)
359
+ ).subscribe(data => {
360
+ highlight({
361
+ selection: data.cellSelection,
362
+ ids: data.highlight,
363
+ styles: data.styles
364
+ })
365
+ })
366
+
367
+ return () => {
368
+ destroy$.next(undefined)
369
+ }
370
+ }
371
+ })
@@ -0,0 +1,36 @@
1
+
2
+ import { Observable, Subject } from 'rxjs'
3
+ import type { ColorType, ModelDatumSeries, EventData } from '@orbcharts/core'
4
+ import type { AxisPosition, ContainerPosition, ContainerPositionScaled, Container, GraphicStyles, Layout, VisibleFilter, XYAxis, CategoryAxis } from '../../types/PluginParams'
5
+ import type { ComputedData, ComputedDatumTree } from '../../types'
6
+
7
+ export interface HierarchyPlotExtendContext {
8
+ layout$: Observable<Layout>
9
+ computedData$: Observable<ComputedData<'tree'>>
10
+ fontSizePx$: Observable<number>
11
+ treeHighlight$: Observable<ComputedDatumTree[]>
12
+ categoryLabels$: Observable<string[]>
13
+ CategoryDataMap$: Observable<Map<string, ComputedDatumTree[]>>
14
+ visibleComputedData$: Observable<ComputedData<'tree'>>
15
+ }
16
+
17
+ // plugin params
18
+ export interface HierarchyPlotPluginParams {
19
+ styles: GraphicStyles
20
+ visibleFilter: VisibleFilter<'grid'>
21
+ datasetIndex: number
22
+ }
23
+
24
+ // all layer params
25
+ export interface HierarchyPlotAllLayerParams {
26
+ TreeMap: TreeMapParams
27
+ }
28
+
29
+ // -- layer params --
30
+ export interface TreeMapParams {
31
+ paddingInner: number
32
+ paddingOuter: number
33
+ labelColorType: ColorType
34
+ squarifyRatio: number
35
+ sort: (a: ComputedDatumTree, b: ComputedDatumTree) => number
36
+ }
@@ -0,0 +1,151 @@
1
+ import {
2
+ shareReplay,
3
+ map,
4
+ combineLatest,
5
+ debounceTime} from 'rxjs'
6
+
7
+ import type { LegendExtendContext, LegendPluginParams, LegendAllLayerParams } from './types'
8
+ import { defineSVGPlugin } from '@orbcharts/core'
9
+ import { validateObject } from '@orbcharts/core'
10
+ import { DEFAULT_SERIES_LEGEND_PLUGIN_PARAMS } from './defaults'
11
+ import {
12
+ layoutObservable,
13
+ fontSizePxObservable,
14
+ seriesDataMapObservable
15
+ } from '../../utils/observables'
16
+ import {
17
+ seriesComputedDataObservable,
18
+ } from './contextObservables'
19
+ import { Legend as LegendLayer } from './layers/Legend'
20
+
21
+ const seriesLegend = new LegendLayer()
22
+
23
+ export const Legend = defineSVGPlugin<
24
+ LegendExtendContext,
25
+ LegendPluginParams,
26
+ LegendAllLayerParams
27
+ >({
28
+ name: 'Legend',
29
+ defaultParams: DEFAULT_SERIES_LEGEND_PLUGIN_PARAMS,
30
+ layers: [seriesLegend],
31
+ setup: (props) => {
32
+
33
+ const selectedSeriesData$ = combineLatest({
34
+ seriesData: props.context.seriesData$,
35
+ datasetIndex: props.pluginParams$.pipe(
36
+ map(pluginParams => pluginParams.datasetIndex)
37
+ )
38
+ }).pipe(
39
+ debounceTime(0),
40
+ map(({ seriesData, datasetIndex }) => seriesData[datasetIndex]),
41
+ shareReplay(1)
42
+ )
43
+
44
+ const layout$ = layoutObservable({
45
+ size$: props.context.size$,
46
+ padding$: props.pluginParams$.pipe(
47
+ map(pluginParams => pluginParams.styles.padding)
48
+ )
49
+ }).pipe(
50
+ shareReplay(1)
51
+ )
52
+
53
+ // const layoutSubscription = layout$.subscribe(layout => {
54
+ // props.svg.setAttribute('transform', `translate(${layout.left}, ${layout.top})`)
55
+ // })
56
+
57
+ const computedData$ = seriesComputedDataObservable({
58
+ selectedSeriesData$,
59
+ pluginParams$: props.pluginParams$
60
+ }).pipe(
61
+ shareReplay(1)
62
+ )
63
+
64
+ const fontSizePx$ = fontSizePxObservable(props.context.theme$).pipe(
65
+ shareReplay(1)
66
+ )
67
+
68
+ const datumList$ = computedData$.pipe(
69
+ map(d => d.flat())
70
+ ).pipe(
71
+ shareReplay(1)
72
+ )
73
+
74
+ const SeriesDataMap$ = seriesDataMapObservable({
75
+ datumList$
76
+ }).pipe(
77
+ shareReplay(1)
78
+ )
79
+
80
+ const extendsContext: LegendExtendContext = {
81
+ layout$,
82
+ fontSizePx$,
83
+ SeriesDataMap$,
84
+ }
85
+
86
+ props.context = {
87
+ ...props.context,
88
+ ...extendsContext,
89
+ }
90
+
91
+ return () => {
92
+ // layoutSubscription.unsubscribe()
93
+ }
94
+ },
95
+ validator: (params: LegendPluginParams) => {
96
+ const result = validateObject(params, {
97
+ styles: {
98
+ toBeTypes: ['object'],
99
+ },
100
+ datasetIndex: {
101
+ toBeTypes: ['number']
102
+ }
103
+ })
104
+ if (params.styles) {
105
+ const stylesResult = validateObject(params.styles, {
106
+ padding: {
107
+ toBeTypes: ['object']
108
+ },
109
+ highlightTarget: {
110
+ toBeTypes: ['string']
111
+ },
112
+ highlightDefault: {
113
+ toBeTypes: ['string', 'null']
114
+ },
115
+ unhighlightedOpacity: {
116
+ toBeTypes: ['number']
117
+ },
118
+ transitionDuration: {
119
+ toBeTypes: ['number']
120
+ },
121
+ transitionEase: {
122
+ toBeTypes: ['string']
123
+ }
124
+ })
125
+ if (stylesResult.status === 'error') {
126
+ return stylesResult
127
+ }
128
+ if (params.styles.padding) {
129
+ const paddingResult = validateObject(params.styles.padding, {
130
+ top: {
131
+ toBeTypes: ['number']
132
+ },
133
+ right: {
134
+ toBeTypes: ['number']
135
+ },
136
+ bottom: {
137
+ toBeTypes: ['number']
138
+ },
139
+ left: {
140
+ toBeTypes: ['number']
141
+ }
142
+ })
143
+ if (paddingResult.status === 'error') {
144
+ return paddingResult
145
+ }
146
+ }
147
+ }
148
+
149
+ return result
150
+ },
151
+ })
@@ -0,0 +1,55 @@
1
+ import {
2
+ combineLatest,
3
+ distinctUntilChanged,
4
+ debounceTime,
5
+ filter,
6
+ map,
7
+ merge,
8
+ takeUntil,
9
+ shareReplay,
10
+ switchMap,
11
+ Subject,
12
+ Observable
13
+ } from 'rxjs'
14
+ import type {
15
+ ModelDataSeries,
16
+ } from '@orbcharts/core'
17
+ import type { LegendPluginParams } from './types'
18
+ import type { ComputedDatumSeries } from '../../types/ComputedData'
19
+
20
+ export const seriesComputedDataObservable = ({ selectedSeriesData$, pluginParams$ }: {
21
+ selectedSeriesData$: Observable<ModelDataSeries>
22
+ pluginParams$: Observable<LegendPluginParams>
23
+ }): Observable<ComputedDatumSeries[][]> => {
24
+ return combineLatest({
25
+ selectedSeriesData: selectedSeriesData$,
26
+ pluginParams: pluginParams$
27
+ }).pipe(
28
+ debounceTime(0),
29
+ map(({ selectedSeriesData, pluginParams }) => {
30
+ return selectedSeriesData
31
+ // 攤為一維陣列
32
+ .flat()
33
+ // 排序後給 seq
34
+ .sort(pluginParams.sort ?? undefined)
35
+ .map((datum, index) => {
36
+ const visibleFilter = pluginParams.visibleFilter
37
+ return {
38
+ ...datum,
39
+ visible: visibleFilter ? visibleFilter(datum) : true,
40
+ seq: index
41
+ }
42
+ })
43
+ // 恢復原排序
44
+ .sort((a, b) => a.index - b.index)
45
+ // 依seriesIndex分組(二維陣列)
46
+ .reduce((acc, datum) => {
47
+ if (!acc[datum.seriesIndex]) {
48
+ acc[datum.seriesIndex] = []
49
+ }
50
+ acc[datum.seriesIndex].push(datum)
51
+ return acc
52
+ }, [])
53
+ })
54
+ )
55
+ }
@@ -0,0 +1,37 @@
1
+ import type { LegendParams, LegendPluginParams } from './types'
2
+
3
+ export const DEFAULT_SERIES_LEGEND_PLUGIN_PARAMS: LegendPluginParams = {
4
+ styles: {
5
+ padding: {
6
+ top: 60,
7
+ right: 60,
8
+ bottom: 60,
9
+ left: 60
10
+ },
11
+ highlightTarget: 'datum',
12
+ highlightDefault: null,
13
+ unhighlightedOpacity: 0.3,
14
+ transitionDuration: 800,
15
+ transitionEase: 'easeCubic'
16
+ },
17
+ visibleFilter: (datum) => true,
18
+ sort: null,
19
+ datasetIndex: 0
20
+ }
21
+ DEFAULT_SERIES_LEGEND_PLUGIN_PARAMS.visibleFilter.toString = () => '(datum) => true'
22
+
23
+ export const DEFAULT_SERIES_LEGEND_PARAMS: LegendParams = {
24
+ // position: 'right',
25
+ // justify: 'end',
26
+ placement: 'bottom',
27
+ padding: 5,
28
+ // offset: [0, 0],
29
+ backgroundFill: 'none',
30
+ backgroundStroke: 'none',
31
+ gap: 10,
32
+ listRectWidth: 14,
33
+ listRectHeight: 14,
34
+ listRectRadius: 0,
35
+ // highlightEvent: false
36
+ textColorType: 'primary'
37
+ }
@@ -0,0 +1,3 @@
1
+ export { Legend } from './Legend'
2
+ export * from './defaults'
3
+ export * from './types'