@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,644 @@
1
+ import * as d3 from 'd3'
2
+ import {
3
+ combineLatest,
4
+ map,
5
+ filter,
6
+ switchMap,
7
+ takeUntil,
8
+ distinctUntilChanged,
9
+ Observable,
10
+ Subject } from 'rxjs'
11
+ import type { BaseLayerFn } from '../types/BaseLayer'
12
+ import type {
13
+ EventData,
14
+ } from '@orbcharts/core'
15
+ import type { TransformData, Layout, ComputedData, ComputedDatumGrid, ContainerPositionScaled, GraphicStyles } from '../types'
16
+ import type { ComputedLayoutDatumGrid, ComputedAxesDataGrid, SeriesPlotPluginParams } from '../plugins/SeriesPlot/types'
17
+ import { getD3TransitionEase } from '../utils/d3Utils'
18
+ import { createClassName, createUniID, getMinMaxValue } from '../utils/orbchartsUtils'
19
+ import { gridCategoryPositionFnObservable, gridSelectionsObservable } from '../utils/gridObservables'
20
+
21
+ export interface BaseLineAreasParams {
22
+ lineCurve: string;
23
+ linearGradientOpacity: [number, number];
24
+ }
25
+
26
+ interface BaseLineAreasContext {
27
+ selection: d3.Selection<any, unknown, any, unknown>
28
+ pluginName: string
29
+ layerName: string
30
+ computedData$: Observable<ComputedData<'grid'>>
31
+ // computedAxesData$: Observable<ComputedAxesDataGrid>
32
+ // visibleComputedData$: Observable<ComputedDatumGrid[][]>
33
+ visibleComputedAxesData$: Observable<ComputedAxesDataGrid>
34
+ seriesLabels$: Observable<string[]>
35
+ SeriesDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
36
+ CategoryDataMap$: Observable<Map<string, ComputedDatumGrid[]>>
37
+ pluginParams$: Observable<SeriesPlotPluginParams>
38
+ baseLineAreasParams$: Observable<BaseLineAreasParams>
39
+ styles$: Observable<GraphicStyles>
40
+ gridAxesTransform$: Observable<TransformData>
41
+ gridGraphicTransform$: Observable<TransformData>
42
+ gridAxesSize$: Observable<{
43
+ width: number;
44
+ height: number;
45
+ }>
46
+ gridHighlight$: Observable<ComputedDatumGrid[]>
47
+ gridContainerPosition$: Observable<ContainerPositionScaled[]>
48
+ allContainerPosition$: Observable<ContainerPositionScaled[]>
49
+ layout$: Observable<Layout>
50
+ eventTrigger$: Subject<EventData<'grid'>>
51
+ }
52
+
53
+ type ClipPathDatum = {
54
+ id: string;
55
+ // x: number;
56
+ // y: number;
57
+ width: number;
58
+ height: number;
59
+ }
60
+
61
+ // const pluginName = 'Lines'
62
+ // const pathClassName = createClassName(pluginName, 'path')
63
+
64
+
65
+ function createAreaPath (lineCurve: string = 'curveLinear', valueAxisStart: number): d3.Line<ComputedLayoutDatumGrid> {
66
+ return d3.area<ComputedLayoutDatumGrid>()
67
+ .x((d) => d.axisX)
68
+ .y0(d => valueAxisStart)
69
+ .y1((d) => d.axisY)
70
+ .curve((d3 as any)[lineCurve])
71
+
72
+ }
73
+
74
+ // 依無值的資料分段
75
+ function makeSegmentData (data: ComputedLayoutDatumGrid[]): ComputedLayoutDatumGrid[][] {
76
+ let segmentData: ComputedLayoutDatumGrid[][] = [[]]
77
+
78
+ let currentIndex = 0
79
+ for (let i in data) {
80
+ if (data[i].visible == false || data[i].value === undefined || data[i].value === null) {
81
+ // 換下一段的 index
82
+ if (segmentData[currentIndex].length) {
83
+ currentIndex ++
84
+ segmentData[currentIndex] = []
85
+ }
86
+ continue
87
+ }
88
+ segmentData[currentIndex].push(data[i])
89
+ }
90
+
91
+ return segmentData
92
+ }
93
+
94
+
95
+ function renderLineAreas ({ selection, pathClassName, segmentData, areaPath, linearGradientIds, params }: {
96
+ selection: d3.Selection<SVGGElement, unknown, any, unknown>
97
+ pathClassName: string
98
+ segmentData: ComputedLayoutDatumGrid[][]
99
+ areaPath: d3.Line<ComputedLayoutDatumGrid>
100
+ linearGradientIds: string[]
101
+ params: BaseLineAreasParams
102
+ }): d3.Selection<SVGPathElement, ComputedLayoutDatumGrid[], any, any> {
103
+ // if (!data[0]) {
104
+ // return undefined
105
+ // }
106
+
107
+ const lineAreas = selection
108
+ .selectAll<SVGPathElement, ComputedLayoutDatumGrid[]>('path')
109
+ .data(segmentData, (d, i) => d.length ? `${d[0].id}_${d[d.length - 1].id}` : i) // 以線段起迄id結合為線段id
110
+ .join(
111
+ enter => {
112
+ return enter
113
+ .append<SVGPathElement>('path')
114
+ .classed(pathClassName, true)
115
+ .attr("fill","none")
116
+ // .attr('pointer-events', 'visibleStroke') // 只對線條產生事件
117
+ .style('vector-effect', 'non-scaling-stroke')
118
+ .style('cursor', 'pointer')
119
+ },
120
+ update => update,
121
+ exit => exit.remove()
122
+ )
123
+ // .attr("stroke-width", params.lineWidth)
124
+ // .attr("stroke", (d, i) => d[0] && d[0].color)
125
+ .attr("fill", (d, i) => d[0] ? `url(#${linearGradientIds[d[0].seriesIndex]})` : '')
126
+ .attr("d", (d) => {
127
+ return areaPath(d)
128
+ })
129
+
130
+ return lineAreas
131
+ }
132
+
133
+ function highlightLineAreas ({ selection, seriesLabel, styles }: {
134
+ selection: d3.Selection<any, string, any, any>
135
+ seriesLabel: string | null
136
+ styles: GraphicStyles
137
+ }) {
138
+ selection.interrupt('highlight')
139
+ if (!seriesLabel) {
140
+ // remove highlight
141
+ selection
142
+ .transition('highlight')
143
+ .duration(200)
144
+ .style('opacity', 1)
145
+ return
146
+ }
147
+
148
+ selection
149
+ .each((currentSeriesLabel, i, n) => {
150
+ // const currentSeriesLabel = d[0] ? d[0].seriesLabel : ''
151
+
152
+ if (currentSeriesLabel === seriesLabel) {
153
+ d3.select(n[i])
154
+ .style('opacity', 1)
155
+ } else {
156
+ d3.select(n[i])
157
+ .style('opacity', styles.unhighlightedOpacity)
158
+ }
159
+ })
160
+ }
161
+
162
+ function renderLinearGradient ({ defsSelection, computedData, linearGradientIds, params }: {
163
+ defsSelection: d3.Selection<SVGDefsElement, any, any, any>
164
+ computedData: ComputedData<'grid'>
165
+ linearGradientIds: string[]
166
+ params: BaseLineAreasParams
167
+ }) {
168
+ defsSelection!
169
+ .selectAll<SVGLinearGradientElement, ComputedDatumGrid>('linearGradient')
170
+ .data(computedData ?? [])
171
+ .join(
172
+ enter => {
173
+ return enter
174
+ .append('linearGradient')
175
+ .attr('x1', '0%')
176
+ .attr('x2', '0%')
177
+ .attr('y1', '100%')
178
+ .attr('y2', '0%')
179
+ .attr('spreadMethod', 'pad')
180
+ },
181
+ update => update,
182
+ exit => exit.remove()
183
+ )
184
+ .attr('id', (d, i) => {
185
+ return d[0] ? linearGradientIds[d[0].seriesIndex] : ''
186
+ })
187
+ .html((d, i) => {
188
+ const color = d[0] ? d[0].color : ''
189
+ return `
190
+ <stop offset="0%" stop-color="${color}" stop-opacity="${params.linearGradientOpacity[0]}"/>
191
+ <stop offset="100%" stop-color="${color}" stop-opacity="${params.linearGradientOpacity[1]}"/>
192
+ `
193
+ })
194
+
195
+ }
196
+
197
+ function renderClipPath ({ defsSelection, clipPathData, transitionDuration, transitionEase }: {
198
+ defsSelection: d3.Selection<SVGDefsElement, any, any, any>
199
+ clipPathData: ClipPathDatum[]
200
+ transitionDuration: number
201
+ transitionEase: string
202
+ }) {
203
+ const clipPath = defsSelection
204
+ .selectAll<SVGClipPathElement, Layout>('clipPath')
205
+ .data(clipPathData)
206
+ .join(
207
+ enter => {
208
+ return enter
209
+ .append('clipPath')
210
+ },
211
+ update => update,
212
+ exit => exit.remove()
213
+ )
214
+ .attr('id', d => d.id)
215
+ .each((d, i, g) => {
216
+ const rect = d3.select(g[i])
217
+ .selectAll<SVGRectElement, typeof d>('rect')
218
+ .data([d])
219
+ .join(
220
+ enter => {
221
+ const enterSelection = enter
222
+ .append('rect')
223
+ enterSelection
224
+ .transition()
225
+ .duration(transitionDuration)
226
+ .ease(getD3TransitionEase(transitionEase))
227
+ // .delay(100) // @Q@ 不知為何如果沒加 delay位置會有點跑掉
228
+ .tween('tween', (_d, _i, _g) => {
229
+ return (t) => {
230
+ const transitionWidth = _d.width * t
231
+
232
+ enterSelection
233
+ .attr('x', 0)
234
+ .attr('y', 0)
235
+ .attr('width', _d => transitionWidth)
236
+ .attr('height', _d => _d.height)
237
+ }
238
+ })
239
+ return enterSelection
240
+ },
241
+ update => {
242
+ return update
243
+ .attr('x', 0)
244
+ .attr('y', 0)
245
+ .attr('width', _d => _d.width)
246
+ .attr('height', _d => _d.height)
247
+ },
248
+ exit => exit.remove()
249
+ )
250
+ })
251
+
252
+ }
253
+
254
+ export const createBaseLineAreas: BaseLayerFn<BaseLineAreasContext> = ({
255
+ selection,
256
+ pluginName,
257
+ layerName,
258
+ computedData$,
259
+ visibleComputedAxesData$,
260
+ seriesLabels$,
261
+ SeriesDataMap$,
262
+ CategoryDataMap$,
263
+ pluginParams$,
264
+ baseLineAreasParams$,
265
+ styles$,
266
+ gridAxesTransform$,
267
+ gridGraphicTransform$,
268
+ gridAxesSize$,
269
+ gridHighlight$,
270
+ gridContainerPosition$,
271
+ layout$,
272
+ eventTrigger$
273
+ }) => {
274
+
275
+ const destroy$ = new Subject()
276
+
277
+ const clipPathID = createUniID(pluginName, layerName, 'clipPath-box')
278
+ const pathClassName = createClassName(pluginName, layerName, 'path')
279
+
280
+ const {
281
+ seriesSelection$,
282
+ axesSelection$,
283
+ defsSelection$,
284
+ graphicGSelection$
285
+ } = gridSelectionsObservable({
286
+ selection,
287
+ pluginName,
288
+ layerName,
289
+ clipPathID,
290
+ seriesLabels$,
291
+ gridContainerPosition$,
292
+ gridAxesTransform$,
293
+ gridGraphicTransform$
294
+ })
295
+
296
+ // valueAxis 的起始座標
297
+ const valueAxisStart$: Observable<number> = gridGraphicTransform$.pipe(
298
+ takeUntil(destroy$),
299
+ map(data => {
300
+ // 抵消掉外層的變型
301
+ return - data.translate[1] / data.scale[1]
302
+ })
303
+ )
304
+
305
+ const areaPath$: Observable<d3.Line<ComputedLayoutDatumGrid>> = new Observable(subscriber => {
306
+ const paramsSubscription = combineLatest({
307
+ baseLineAreasParams: baseLineAreasParams$,
308
+ valueAxisStart: valueAxisStart$
309
+ }).pipe(
310
+ takeUntil(destroy$)
311
+ )
312
+ .subscribe(d => {
313
+ const areaPath = createAreaPath(d.baseLineAreasParams.lineCurve, d.valueAxisStart)
314
+ subscriber.next(areaPath)
315
+ })
316
+ return () => {
317
+ paramsSubscription.unsubscribe()
318
+ }
319
+ })
320
+
321
+ // // 顯示範圍內的series labels
322
+ // const seriesLabels$: Observable<string[]> = new Observable(subscriber => {
323
+ // computedData$.pipe(
324
+ // takeUntil(destroy$),
325
+ // switchMap(async (d) => d),
326
+ // ).subscribe(data => {
327
+ // const labels = data[0] && data[0][0]
328
+ // ? data.map(d => d[0].seriesLabel)
329
+ // : []
330
+ // subscriber.next(labels)
331
+ // })
332
+ // })
333
+
334
+ // const axisSize$ = gridAxisSizeObservable({
335
+ // fullDataFormatter$,
336
+ // computedLayout$
337
+ // })
338
+
339
+ const transitionDuration$ = styles$
340
+ .pipe(
341
+ map(d => d.transitionDuration),
342
+ distinctUntilChanged()
343
+ )
344
+
345
+ const transitionEase$ = styles$
346
+ .pipe(
347
+ map(d => d.transitionEase),
348
+ distinctUntilChanged()
349
+ )
350
+
351
+ const clipPathSubscription = combineLatest({
352
+ defsSelection: defsSelection$,
353
+ seriesLabels: seriesLabels$,
354
+ axisSize: gridAxesSize$,
355
+ transitionDuration: transitionDuration$,
356
+ transitionEase: transitionEase$
357
+ }).pipe(
358
+ takeUntil(destroy$),
359
+ switchMap(async (d) => d),
360
+ ).subscribe(data => {
361
+ // 外層的遮罩
362
+ const clipPathBox = [{
363
+ id: clipPathID,
364
+ width: data.axisSize.width,
365
+ height: data.axisSize.height
366
+ }]
367
+ // 各別線條的遮罩(各別動畫)
368
+ const clipPathData = clipPathBox.concat(
369
+ data.seriesLabels.map(d => {
370
+ return {
371
+ id: `orbcharts__clipPath_${d}`,
372
+ width: data.axisSize.width,
373
+ height: data.axisSize.height
374
+ }
375
+ })
376
+ )
377
+ renderClipPath({
378
+ defsSelection: data.defsSelection,
379
+ clipPathData,
380
+ transitionDuration: data.transitionDuration,
381
+ transitionEase: data.transitionEase
382
+ })
383
+ })
384
+
385
+ // const SeriesDataMap$ = computedData$.pipe(
386
+ // map(d => makeGridSeriesDataMap(d))
387
+ // )
388
+
389
+ // const CategoryDataMap$ = computedData$.pipe(
390
+ // map(d => makeGridCategoryDataMap(d))
391
+ // )
392
+
393
+ const DataMap$ = computedData$.pipe(
394
+ map(d => {
395
+ const DataMap: Map<string, ComputedDatumGrid> = new Map()
396
+ d.flat().forEach(_d => DataMap.set(_d.id, _d))
397
+ return DataMap
398
+ })
399
+ )
400
+
401
+ // 取得事件座標的group資料
402
+ const gridCategoryPositionFn$ = gridCategoryPositionFnObservable({
403
+ // fullDataFormatter$,
404
+ pluginParams$,
405
+ gridAxesSize$: gridAxesSize$,
406
+ computedData$: computedData$,
407
+ // fullChartParams$: fullChartParams$,
408
+ gridContainerPosition$: gridContainerPosition$,
409
+ layout$: layout$
410
+ })
411
+
412
+ const highlightTarget$ = styles$.pipe(
413
+ takeUntil(destroy$),
414
+ map(d => d.highlightTarget),
415
+ distinctUntilChanged()
416
+ )
417
+
418
+ const linearGradientIds$ = seriesLabels$.pipe(
419
+ takeUntil(destroy$),
420
+ map(d => d.map((d, i) => {
421
+ return createUniID(pluginName, layerName, `lineargradient-${d}`)
422
+ }))
423
+ )
424
+
425
+ const pathSelectionArr$ = combineLatest({
426
+ graphicGSelection: graphicGSelection$,
427
+ defsSelection: defsSelection$,
428
+ visibleComputedAxesData: visibleComputedAxesData$,
429
+ linearGradientIds: linearGradientIds$,
430
+ areaPath: areaPath$,
431
+ params: baseLineAreasParams$,
432
+ }).pipe(
433
+ takeUntil(destroy$),
434
+ switchMap(async (d) => d),
435
+ map(data => {
436
+ // const updateGraphic = data.graphicGSelection
437
+ // .selectAll<SVGGElement, number>('g')
438
+ // .data(data.seriesLabels, (d, i) => d)
439
+ // const enterGraphic = updateGraphic.enter()
440
+ // .append('g')
441
+ // .classed(graphicClassName, true)
442
+ // updateGraphic.exit().remove()
443
+ // const graphicSelection = updateGraphic.merge(enterGraphic)
444
+ // .attr('clip-path', (d, i) => `url(#orbcharts__clipPath_${d})`)
445
+ let pathSelectionArr: d3.Selection<SVGPathElement, ComputedLayoutDatumGrid[], any, any>[] = []
446
+
447
+ // 繪圖
448
+ data.graphicGSelection.each((d, i, all) => {
449
+ // 將資料分段
450
+ const segmentData = makeSegmentData(data.visibleComputedAxesData[i] ?? [])
451
+
452
+ pathSelectionArr[i] = renderLineAreas({
453
+ selection: d3.select(all[i]),
454
+ pathClassName,
455
+ areaPath: data.areaPath,
456
+ segmentData: segmentData,
457
+ linearGradientIds: data.linearGradientIds,
458
+ params: data.params
459
+ })
460
+ renderLinearGradient({
461
+ defsSelection: data.defsSelection,
462
+ computedData: data.visibleComputedAxesData,
463
+ linearGradientIds: data.linearGradientIds,
464
+ params: data.params
465
+ })
466
+ })
467
+
468
+ return pathSelectionArr
469
+ })
470
+ )
471
+
472
+ combineLatest({
473
+ pathSelectionArr: pathSelectionArr$,
474
+ computedData: computedData$,
475
+ SeriesDataMap: SeriesDataMap$,
476
+ CategoryDataMap: CategoryDataMap$,
477
+ highlightTarget: highlightTarget$,
478
+ gridCategoryPositionFn: gridCategoryPositionFn$,
479
+ }).pipe(
480
+ takeUntil(destroy$),
481
+ switchMap(async (d) => d),
482
+ ).subscribe(data => {
483
+ data.pathSelectionArr.forEach(pathSelection => {
484
+ pathSelection
485
+ .on('mouseover', (event, datum) => {
486
+ // event.stopPropagation()
487
+
488
+ const seriesLabel = datum[0] ? datum[0].series : ''
489
+ const { categoryIndex, categoryLabel } = data.gridCategoryPositionFn(event)
490
+ const groupData = data.CategoryDataMap.get(categoryLabel)!
491
+ const targetDatum = groupData.find(d => d.series === seriesLabel)
492
+ const _datum = targetDatum ?? datum[0]
493
+
494
+ eventTrigger$.next({
495
+ // type: 'grid',
496
+ // eventName: 'mouseover',
497
+ // pluginName,
498
+ // highlightTarget: data.highlightTarget,
499
+ // datum: _datum,
500
+ // gridIndex: _datum.gridIndex,
501
+ // series: data.SeriesDataMap.get(_datum.seriesLabel)!,
502
+ // seriesIndex: _datum.seriesIndex,
503
+ // seriesLabel: _datum.seriesLabel,
504
+ // group: data.CategoryDataMap.get(_datum.categoryLabel)!,
505
+ // categoryIndex: _datum.categoryIndex,
506
+ // categoryLabel: _datum.categoryLabel,
507
+ // event,
508
+ // data: data.computedData
509
+ eventName: 'mouseover',
510
+ pluginName,
511
+ layerName,
512
+ target: _datum,
513
+ event,
514
+ })
515
+ })
516
+ .on('mousemove', (event, datum) => {
517
+ // event.stopPropagation()
518
+
519
+ const seriesLabel = datum[0] ? datum[0].series : ''
520
+ const { categoryIndex, categoryLabel } = data.gridCategoryPositionFn(event)
521
+ const groupData = data.CategoryDataMap.get(categoryLabel)!
522
+ const targetDatum = groupData.find(d => d.series === seriesLabel)
523
+ const _datum = targetDatum ?? datum[0]
524
+
525
+ eventTrigger$.next({
526
+ // type: 'grid',
527
+ // eventName: 'mousemove',
528
+ // pluginName,
529
+ // highlightTarget: data.highlightTarget,
530
+ // datum: _datum,
531
+ // gridIndex: _datum.gridIndex,
532
+ // series: data.SeriesDataMap.get(_datum.seriesLabel)!,
533
+ // seriesIndex: _datum.seriesIndex,
534
+ // seriesLabel: _datum.seriesLabel,
535
+ // group: data.CategoryDataMap.get(_datum.categoryLabel)!,
536
+ // categoryIndex: _datum.categoryIndex,
537
+ // categoryLabel: _datum.categoryLabel,
538
+ // event,
539
+ // data: data.computedData
540
+ eventName: 'mousemove',
541
+ pluginName,
542
+ layerName,
543
+ target: _datum,
544
+ event,
545
+ })
546
+ })
547
+ .on('mouseout', (event, datum) => {
548
+ // event.stopPropagation()
549
+
550
+ const seriesLabel = datum[0] ? datum[0].series : ''
551
+ const { categoryIndex, categoryLabel } = data.gridCategoryPositionFn(event)
552
+ const groupData = data.CategoryDataMap.get(categoryLabel)!
553
+ const targetDatum = groupData.find(d => d.series === seriesLabel)
554
+ const _datum = targetDatum ?? datum[0]
555
+
556
+ eventTrigger$.next({
557
+ // type: 'grid',
558
+ // eventName: 'mouseout',
559
+ // pluginName,
560
+ // highlightTarget: data.highlightTarget,
561
+ // datum: _datum,
562
+ // gridIndex: _datum.gridIndex,
563
+ // series: data.SeriesDataMap.get(_datum.seriesLabel)!,
564
+ // seriesIndex: _datum.seriesIndex,
565
+ // seriesLabel: _datum.seriesLabel,
566
+ // group: data.CategoryDataMap.get(_datum.categoryLabel)!,
567
+ // categoryIndex: _datum.categoryIndex,
568
+ // categoryLabel: _datum.categoryLabel,
569
+ // event,
570
+ // data: data.computedData
571
+ eventName: 'mouseout',
572
+ pluginName,
573
+ layerName,
574
+ target: _datum,
575
+ event,
576
+ })
577
+ })
578
+ .on('click', (event, datum) => {
579
+ // event.stopPropagation()
580
+
581
+ const seriesLabel = datum[0] ? datum[0].series : ''
582
+ const { categoryIndex, categoryLabel } = data.gridCategoryPositionFn(event)
583
+ const groupData = data.CategoryDataMap.get(categoryLabel)!
584
+ const targetDatum = groupData.find(d => d.series === seriesLabel)
585
+ const _datum = targetDatum ?? datum[0]
586
+
587
+ eventTrigger$.next({
588
+ // type: 'grid',
589
+ // eventName: 'click',
590
+ // pluginName,
591
+ // highlightTarget: data.highlightTarget,
592
+ // datum: _datum,
593
+ // gridIndex: _datum.gridIndex,
594
+ // series: data.SeriesDataMap.get(_datum.seriesLabel)!,
595
+ // seriesIndex: _datum.seriesIndex,
596
+ // seriesLabel: _datum.seriesLabel,
597
+ // group: data.CategoryDataMap.get(_datum.categoryLabel)!,
598
+ // categoryIndex: _datum.categoryIndex,
599
+ // categoryLabel: _datum.categoryLabel,
600
+ // event,
601
+ // data: data.computedData
602
+ eventName: 'click',
603
+ pluginName,
604
+ layerName,
605
+ target: _datum,
606
+ event,
607
+ })
608
+ })
609
+ })
610
+ })
611
+
612
+ // const datumList$ = computedData$.pipe(
613
+ // takeUntil(destroy$),
614
+ // map(d => d.flat())
615
+ // )
616
+ // const highlight$ = highlightObservable({ datumList$, fullChartParams$, eventTrigger$: store.eventTrigger$ })
617
+ // const highlightSubscription = gridHighlight$.subscribe()
618
+
619
+ styles$.pipe(
620
+ takeUntil(destroy$),
621
+ filter(d => d.highlightTarget === 'series'),
622
+ switchMap(d => combineLatest({
623
+ graphicGSelection: graphicGSelection$,
624
+ gridHighlight: gridHighlight$,
625
+ DataMap: DataMap$,
626
+ styles: styles$
627
+ }).pipe(
628
+ takeUntil(destroy$),
629
+ switchMap(async d => d)
630
+ ))
631
+ ).subscribe(data => {
632
+ const seriesLabel = data.gridHighlight[0] ? data.gridHighlight[0].series : null
633
+ highlightLineAreas({
634
+ selection: data.graphicGSelection,
635
+ seriesLabel,
636
+ styles: data.styles
637
+ })
638
+ })
639
+
640
+ return () => {
641
+ destroy$.next(undefined)
642
+ // highlightSubscription.unsubscribe()
643
+ }
644
+ }