@orbcharts/plugins-basic 3.0.0-alpha.43 → 3.0.0-alpha.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-plugins-basic.es.js +5611 -5571
  3. package/dist/orbcharts-plugins-basic.umd.js +7 -7
  4. package/dist/src/base/BaseLegend.d.ts +1 -0
  5. package/package.json +42 -42
  6. package/src/base/BaseBarStack.ts +881 -881
  7. package/src/base/BaseBars.ts +750 -750
  8. package/src/base/BaseBarsTriangle.ts +659 -659
  9. package/src/base/BaseDots.ts +639 -639
  10. package/src/base/BaseGroupAxis.ts +496 -496
  11. package/src/base/BaseLegend.ts +641 -636
  12. package/src/base/BaseLineAreas.ts +621 -621
  13. package/src/base/BaseLines.ts +692 -692
  14. package/src/base/BaseValueAxis.ts +479 -479
  15. package/src/base/types.ts +2 -2
  16. package/src/grid/defaults.ts +121 -121
  17. package/src/grid/gridObservables.ts +263 -263
  18. package/src/grid/index.ts +15 -15
  19. package/src/grid/plugins/BarStack.ts +37 -37
  20. package/src/grid/plugins/Bars.ts +37 -37
  21. package/src/grid/plugins/BarsDiverging.ts +39 -39
  22. package/src/grid/plugins/BarsTriangle.ts +34 -34
  23. package/src/grid/plugins/Dots.ts +35 -35
  24. package/src/grid/plugins/GridLegend.ts +59 -58
  25. package/src/grid/plugins/GroupAux.ts +646 -643
  26. package/src/grid/plugins/GroupAxis.ts +30 -30
  27. package/src/grid/plugins/LineAreas.ts +36 -36
  28. package/src/grid/plugins/Lines.ts +35 -35
  29. package/src/grid/plugins/ScalingArea.ts +174 -174
  30. package/src/grid/plugins/ValueAxis.ts +31 -31
  31. package/src/grid/plugins/ValueStackAxis.ts +70 -70
  32. package/src/grid/types.ts +120 -120
  33. package/src/index.ts +9 -9
  34. package/src/multiGrid/defaults.ts +147 -147
  35. package/src/multiGrid/index.ts +11 -11
  36. package/src/multiGrid/multiGridObservables.ts +289 -289
  37. package/src/multiGrid/plugins/MultiBarStack.ts +60 -60
  38. package/src/multiGrid/plugins/MultiBars.ts +59 -59
  39. package/src/multiGrid/plugins/MultiBarsTriangle.ts +58 -58
  40. package/src/multiGrid/plugins/MultiDots.ts +58 -58
  41. package/src/multiGrid/plugins/MultiGridLegend.ts +89 -88
  42. package/src/multiGrid/plugins/MultiGroupAxis.ts +53 -53
  43. package/src/multiGrid/plugins/MultiLineAreas.ts +59 -59
  44. package/src/multiGrid/plugins/MultiLines.ts +58 -58
  45. package/src/multiGrid/plugins/MultiValueAxis.ts +53 -53
  46. package/src/multiGrid/plugins/OverlappingValueAxes.ts +164 -164
  47. package/src/multiGrid/types.ts +67 -67
  48. package/src/noneData/defaults.ts +61 -61
  49. package/src/noneData/index.ts +3 -3
  50. package/src/noneData/plugins/Container.ts +10 -10
  51. package/src/noneData/plugins/Tooltip.ts +310 -304
  52. package/src/noneData/types.ts +26 -26
  53. package/src/series/defaults.ts +99 -99
  54. package/src/series/index.ts +6 -6
  55. package/src/series/plugins/Bubbles.ts +551 -551
  56. package/src/series/plugins/Pie.ts +600 -600
  57. package/src/series/plugins/PieEventTexts.ts +194 -194
  58. package/src/series/plugins/PieLabels.ts +288 -288
  59. package/src/series/plugins/SeriesLegend.ts +59 -58
  60. package/src/series/seriesUtils.ts +50 -50
  61. package/src/series/types.ts +67 -67
  62. package/src/tree/defaults.ts +22 -22
  63. package/src/tree/index.ts +3 -3
  64. package/src/tree/plugins/TreeLegend.ts +59 -58
  65. package/src/tree/plugins/TreeMap.ts +305 -302
  66. package/src/tree/types.ts +23 -23
  67. package/src/utils/commonUtils.ts +21 -21
  68. package/src/utils/d3Graphics.ts +124 -124
  69. package/src/utils/d3Utils.ts +73 -73
  70. package/src/utils/observables.ts +14 -14
  71. package/src/utils/orbchartsUtils.ts +100 -100
  72. package/tsconfig.dev.json +16 -16
  73. package/tsconfig.json +13 -13
  74. package/tsconfig.prod.json +13 -13
  75. package/vite.config.js +49 -49
@@ -1,305 +1,311 @@
1
- import * as d3 from 'd3'
2
- import {
3
- combineLatest,
4
- map,
5
- merge,
6
- filter,
7
- switchMap,
8
- first,
9
- iif,
10
- takeUntil,
11
- Subject,
12
- Observable,
13
- distinctUntilChanged } from 'rxjs'
14
- import type {
15
- EventTypeMap, PluginConstructor, ChartType } from '@orbcharts/core'
16
- import { defineNoneDataPlugin } from '@orbcharts/core'
17
- import { getSvgGElementSize, appendSvg } from '../../utils/d3Utils'
18
- import { getColor, getClassName } from '../../utils/orbchartsUtils'
19
- import { TOOLTIP_PARAMS } from '../defaults'
20
-
21
- interface TooltipStyle {
22
- backgroundColor: string
23
- backgroundOpacity: number
24
- strokeColor: string
25
- offset: [number, number]
26
- padding: number
27
- textColor: string
28
- textSize: number
29
- }
30
-
31
- const pluginName = 'Tooltip'
32
- const gClassName = getClassName(pluginName, 'g')
33
- const boxClassName = getClassName(pluginName, 'box')
34
-
35
- function textToSvg (textArr: string[], textStyle: TooltipStyle) {
36
- const lineHeight = textStyle.textSize * 1.5
37
- return textArr
38
- .filter(d => d != '')
39
- .map((text, i) => {
40
- const top = i * lineHeight
41
- return `<text font-size="${textStyle.textSize}" fill="${textStyle.textColor}" x="0" y="${top}" style="dominant-baseline:text-before-edge">${text}</text>`
42
- })
43
- .join()
44
- }
45
-
46
- function renderTooltip ({ rootSelection, pluginName, rootWidth, rootHeight, svgString, tooltipStyle, event }: {
47
- rootSelection: d3.Selection<any, unknown, any, unknown>
48
- pluginName: string
49
- rootWidth: number
50
- rootHeight: number
51
- svgString: string
52
- tooltipStyle: TooltipStyle
53
- event: MouseEvent
54
- }) {
55
- // if (!svgString) {
56
- // return
57
- // }
58
- // const rootSelection = d3.select('svg.bpcharts__root')
59
- // console.log('tooltip', { selection, rootWidth, rootHeight, svgString, event })
60
- rootSelection.interrupt('fadeout')
61
- const radius = 5
62
-
63
- // data(svg string無值則為空陣列)
64
- const contentData = svgString ? [svgString] : []
65
- const styleData = svgString ? [tooltipStyle] : []
66
- // tooltipG <g>
67
- const tooltipG = rootSelection
68
- .selectAll<SVGGElement, string>(`g.${gClassName}`)
69
- .data(contentData)
70
- .join(
71
- enter => {
72
- return enter
73
- .append('g')
74
- .classed(gClassName, true)
75
- .attr('pointer-events', 'none')
76
- },
77
- update => {
78
- return update
79
- },
80
- exit => {
81
- return exit
82
- // .transition('fadeout')
83
- // .duration(0)
84
- // .delay(500)
85
- .style('opacity', 0)
86
- .remove()
87
- }
88
- )
89
- .attr('transform', () => `translate(${event.offsetX}, ${event.offsetY})`)
90
-
91
- // tooltipBox <g><g>
92
- const tooltipBox = tooltipG
93
- .selectAll<SVGGElement, string>(`g.${boxClassName}`)
94
- .data(styleData)
95
- .join(
96
- enter => {
97
- return enter
98
- .append('g')
99
- .classed(getClassName(pluginName, 'box'), true)
100
- },
101
- )
102
-
103
- // rect <g><g><rect>
104
- const rect = tooltipBox
105
- .selectAll<SVGRectElement, string>('rect')
106
- .data(styleData)
107
- .join(
108
- enter => {
109
- return enter
110
- .append('rect')
111
- .attr('rx', radius)
112
- .attr('ry', radius)
113
- }
114
- )
115
- .attr('fill', d => d.backgroundColor)
116
- .attr('stroke', d => d.strokeColor)
117
- .attr('opacity', d => d.backgroundOpacity)
118
-
119
- // text <g><g><g>
120
- const contentG = tooltipBox
121
- .selectAll<SVGGElement, string>('g')
122
- .data(contentData)
123
- .join(
124
- enter => {
125
- return enter
126
- .append('g')
127
- .classed(getClassName(pluginName, 'content'), true)
128
- .attr('transform', () => `translate(${tooltipStyle.padding}, ${tooltipStyle.padding})`)
129
- }
130
- )
131
- // 使用字串加入svg
132
- if (contentData.length) {
133
- appendSvg(contentG, contentData[0])
134
- }
135
- const contentSize = (contentG?.node()) ? getSvgGElementSize(contentG!) : { width: 0, height: 0 }
136
-
137
- // rect size
138
- rect
139
- .attr('width', contentSize.width + tooltipStyle.padding * 2)
140
- .attr('height', contentSize.height + tooltipStyle.padding * 2)
141
-
142
- // -- tooltipG --
143
- // 取得tooltip <g>的尺寸
144
- const tooltipSize = (tooltipBox?.node()) ? getSvgGElementSize(tooltipBox!) : { width: 0, height: 0 }
145
- // const minX = 0
146
- const maxX = rootWidth - tooltipSize.width
147
- // const minY = 0
148
- const maxY = rootHeight - tooltipSize.height
149
-
150
- // -- 相對游標位置的offset --
151
- const offsetX = (event.offsetX + tooltipStyle.offset[0]) > maxX ? maxX - event.offsetX : tooltipStyle.offset[0]
152
- const offsetY = (event.offsetY + tooltipStyle.offset[1]) > maxY ? maxY - event.offsetY : tooltipStyle.offset[1]
153
- tooltipBox.attr('transform', d => `translate(${offsetX}, ${offsetY})`)
154
- tooltipBox.attr('transform', d => `translate(${offsetX}, ${offsetY})`)
155
-
156
-
157
-
158
- // const minX = containerSize.x
159
- // const maxX = containerSize.x + containerSize.width - tooltipSize.width
160
- // const minY = containerSize.y
161
- // const maxY = containerSize.y + containerSize.height - tooltipSize.height
162
-
163
-
164
- // .style('position', 'absolute')
165
- // .style('z-index', 10000)
166
- // .style('left', (d) => {
167
- // const x = d.x + this.fullParams.offsetX! - containerSize.x
168
- // if (x < minX) {
169
- // return `${minX}px`
170
- // } else if (x > maxX) {
171
- // return `${maxX}px`
172
- // }
173
- // return `${x}px`
174
- // })
175
- // .style('top', (d) => {
176
- // const y = d.y + this.fullParams.offsetY! - containerSize.y
177
- // if (y < minY) {
178
- // return `${minY}px`
179
- // } else if (y > maxY) {
180
- // return `${maxY}px`
181
- // }
182
- // return `${y}px`
183
- // })
184
- // .html((d) => d.contentHtml)
185
-
186
-
187
- }
188
-
189
- export const Tooltip: PluginConstructor<any, string, any> = defineNoneDataPlugin(pluginName, TOOLTIP_PARAMS)(({ selection, rootSelection, name, chartType, observer, subject }) => {
190
- const destroy$ = new Subject()
191
-
192
- // 事件觸發
193
- const eventMouseover$: Observable<EventTypeMap<any>> = subject.event$.pipe(
194
- takeUntil(destroy$),
195
- filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
196
- // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
197
- // map(d => d as EventTypeMap<typeof chartType>)
198
- )
199
- const eventMouseout$: Observable<EventTypeMap<any>> = subject.event$.pipe(
200
- takeUntil(destroy$),
201
- filter(d => d.eventName === 'mouseout'),
202
- // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
203
- // map(d => d as EventTypeMap<typeof chartType>)
204
- )
205
-
206
- const tooltipStyle$: Observable<TooltipStyle> = combineLatest({
207
- fullChartParams: observer.fullChartParams$,
208
- fullParams: observer.fullParams$
209
- }).pipe(
210
- takeUntil(destroy$),
211
- switchMap(async d => d),
212
- map(data => {
213
- return {
214
- backgroundColor: getColor(data.fullParams.backgroundColorType, data.fullChartParams),
215
- backgroundOpacity: data.fullParams.backgroundOpacity,
216
- strokeColor: getColor(data.fullParams.strokeColorType, data.fullChartParams),
217
- offset: data.fullParams.offset,
218
- padding: data.fullParams.padding,
219
- textSize: data.fullChartParams.styles.textSize,
220
- textColor: getColor(data.fullParams.textColorType, data.fullChartParams),
221
- }
222
- })
223
- )
224
-
225
- const contentRenderFn$: Observable<((eventData: EventTypeMap<any>) => string)> = combineLatest({
226
- fullParams: observer.fullParams$,
227
- tooltipStyle: tooltipStyle$
228
- }).pipe(
229
- takeUntil(destroy$),
230
- switchMap(async d => d),
231
- map(d => {
232
- if (d.fullParams.svgRenderFn) {
233
- return d.fullParams.svgRenderFn
234
- }
235
- // 將textRenderFn回傳的資料使用<text>包裝起來
236
- return (eventData: EventTypeMap<any>) => {
237
- const textArr = d.fullParams.textRenderFn(eventData as any)
238
- return textToSvg(textArr, d.tooltipStyle)
239
- }
240
- })
241
- )
242
-
243
- const mouseoverTooltipSvg$ = combineLatest({
244
- event: eventMouseover$,
245
- contentRenderFn: contentRenderFn$
246
- }).pipe(
247
- takeUntil(destroy$),
248
- switchMap(async d => d),
249
- map(d => d.contentRenderFn(d.event))
250
- )
251
-
252
- const mouseoutTooltipSvg$ = eventMouseout$.pipe(
253
- takeUntil(destroy$),
254
- map(d => '')
255
- )
256
-
257
- const event$ = merge(eventMouseover$, eventMouseout$)
258
- .pipe(
259
- takeUntil(destroy$),
260
- // filter(d => {
261
- // return (d.eventName === 'mouseover' || d.eventName === 'mousemove' || d.eventName === 'mouseout')
262
- // && d.event != undefined
263
- // }),
264
- map(d => d.event!),
265
- )
266
-
267
- combineLatest({
268
- svgString: merge(mouseoverTooltipSvg$, mouseoutTooltipSvg$),
269
- event: event$,
270
- layout: observer.layout$,
271
- tooltipStyle: tooltipStyle$,
272
- }).pipe(
273
- takeUntil(destroy$),
274
- switchMap(async d => d),
275
- ).subscribe(data => {
276
- // console.log('svgString', data.svgString)
277
- renderTooltip({
278
- rootSelection,
279
- pluginName: name,
280
- rootWidth: data.layout.rootWidth,
281
- rootHeight: data.layout.rootHeight,
282
- svgString: data.svgString,
283
- tooltipStyle: data.tooltipStyle,
284
- event: data.event
285
- })
286
- })
287
-
288
-
289
-
290
- // const chartType$ = eventMouseover$.pipe(
291
- // takeUntil(destroy$),
292
- // map(d => d.type),
293
- // distinctUntilChanged()
294
- // )
295
-
296
-
297
- // eventMouseover$.subscribe(event => {
298
-
299
- // })
300
-
301
-
302
- return function unsubscribe () {
303
- destroy$.next(undefined)
304
- }
1
+ import * as d3 from 'd3'
2
+ import {
3
+ combineLatest,
4
+ map,
5
+ merge,
6
+ filter,
7
+ switchMap,
8
+ first,
9
+ iif,
10
+ takeUntil,
11
+ Subject,
12
+ Observable,
13
+ distinctUntilChanged } from 'rxjs'
14
+ import type {
15
+ EventTypeMap, PluginConstructor, ChartType } from '@orbcharts/core'
16
+ import { defineNoneDataPlugin } from '@orbcharts/core'
17
+ import { getSvgGElementSize, appendSvg } from '../../utils/d3Utils'
18
+ import { getColor, getClassName } from '../../utils/orbchartsUtils'
19
+ import { TOOLTIP_PARAMS } from '../defaults'
20
+ import { textSizePxObservable } from '@orbcharts/core'
21
+
22
+ interface TooltipStyle {
23
+ backgroundColor: string
24
+ backgroundOpacity: number
25
+ strokeColor: string
26
+ offset: [number, number]
27
+ padding: number
28
+ textColor: string
29
+ textSize: number | string // chartParams上的設定
30
+ textSizePx: number
31
+ }
32
+
33
+ const pluginName = 'Tooltip'
34
+ const gClassName = getClassName(pluginName, 'g')
35
+ const boxClassName = getClassName(pluginName, 'box')
36
+
37
+ function textToSvg (textArr: string[], textStyle: TooltipStyle) {
38
+ const lineHeight = textStyle.textSizePx * 1.5
39
+ return textArr
40
+ .filter(d => d != '')
41
+ .map((text, i) => {
42
+ const top = i * lineHeight
43
+ return `<text font-size="${textStyle.textSize}" fill="${textStyle.textColor}" x="0" y="${top}" style="dominant-baseline:text-before-edge">${text}</text>`
44
+ })
45
+ .join()
46
+ }
47
+
48
+ function renderTooltip ({ rootSelection, pluginName, rootWidth, rootHeight, svgString, tooltipStyle, event }: {
49
+ rootSelection: d3.Selection<any, unknown, any, unknown>
50
+ pluginName: string
51
+ rootWidth: number
52
+ rootHeight: number
53
+ svgString: string
54
+ tooltipStyle: TooltipStyle
55
+ event: MouseEvent
56
+ }) {
57
+ // if (!svgString) {
58
+ // return
59
+ // }
60
+ // const rootSelection = d3.select('svg.bpcharts__root')
61
+ // console.log('tooltip', { selection, rootWidth, rootHeight, svgString, event })
62
+ rootSelection.interrupt('fadeout')
63
+ const radius = 5
64
+
65
+ // data(svg string無值則為空陣列)
66
+ const contentData = svgString ? [svgString] : []
67
+ const styleData = svgString ? [tooltipStyle] : []
68
+ // tooltipG <g>
69
+ const tooltipG = rootSelection
70
+ .selectAll<SVGGElement, string>(`g.${gClassName}`)
71
+ .data(contentData)
72
+ .join(
73
+ enter => {
74
+ return enter
75
+ .append('g')
76
+ .classed(gClassName, true)
77
+ .attr('pointer-events', 'none')
78
+ },
79
+ update => {
80
+ return update
81
+ },
82
+ exit => {
83
+ return exit
84
+ // .transition('fadeout')
85
+ // .duration(0)
86
+ // .delay(500)
87
+ .style('opacity', 0)
88
+ .remove()
89
+ }
90
+ )
91
+ .attr('transform', () => `translate(${event.offsetX}, ${event.offsetY})`)
92
+
93
+ // tooltipBox <g><g>
94
+ const tooltipBox = tooltipG
95
+ .selectAll<SVGGElement, string>(`g.${boxClassName}`)
96
+ .data(styleData)
97
+ .join(
98
+ enter => {
99
+ return enter
100
+ .append('g')
101
+ .classed(getClassName(pluginName, 'box'), true)
102
+ },
103
+ )
104
+
105
+ // rect <g><g><rect>
106
+ const rect = tooltipBox
107
+ .selectAll<SVGRectElement, string>('rect')
108
+ .data(styleData)
109
+ .join(
110
+ enter => {
111
+ return enter
112
+ .append('rect')
113
+ .attr('rx', radius)
114
+ .attr('ry', radius)
115
+ }
116
+ )
117
+ .attr('fill', d => d.backgroundColor)
118
+ .attr('stroke', d => d.strokeColor)
119
+ .attr('opacity', d => d.backgroundOpacity)
120
+
121
+ // text <g><g><g>
122
+ const contentG = tooltipBox
123
+ .selectAll<SVGGElement, string>('g')
124
+ .data(contentData)
125
+ .join(
126
+ enter => {
127
+ return enter
128
+ .append('g')
129
+ .classed(getClassName(pluginName, 'content'), true)
130
+ .attr('transform', () => `translate(${tooltipStyle.padding}, ${tooltipStyle.padding})`)
131
+ }
132
+ )
133
+ // 使用字串加入svg
134
+ if (contentData.length) {
135
+ appendSvg(contentG, contentData[0])
136
+ }
137
+ const contentSize = (contentG?.node()) ? getSvgGElementSize(contentG!) : { width: 0, height: 0 }
138
+
139
+ // rect size
140
+ rect
141
+ .attr('width', contentSize.width + tooltipStyle.padding * 2)
142
+ .attr('height', contentSize.height + tooltipStyle.padding * 2)
143
+
144
+ // -- tooltipG --
145
+ // 取得tooltip <g>的尺寸
146
+ const tooltipSize = (tooltipBox?.node()) ? getSvgGElementSize(tooltipBox!) : { width: 0, height: 0 }
147
+ // const minX = 0
148
+ const maxX = rootWidth - tooltipSize.width
149
+ // const minY = 0
150
+ const maxY = rootHeight - tooltipSize.height
151
+
152
+ // -- 相對游標位置的offset --
153
+ const offsetX = (event.offsetX + tooltipStyle.offset[0]) > maxX ? maxX - event.offsetX : tooltipStyle.offset[0]
154
+ const offsetY = (event.offsetY + tooltipStyle.offset[1]) > maxY ? maxY - event.offsetY : tooltipStyle.offset[1]
155
+ tooltipBox.attr('transform', d => `translate(${offsetX}, ${offsetY})`)
156
+ tooltipBox.attr('transform', d => `translate(${offsetX}, ${offsetY})`)
157
+
158
+
159
+
160
+ // const minX = containerSize.x
161
+ // const maxX = containerSize.x + containerSize.width - tooltipSize.width
162
+ // const minY = containerSize.y
163
+ // const maxY = containerSize.y + containerSize.height - tooltipSize.height
164
+
165
+
166
+ // .style('position', 'absolute')
167
+ // .style('z-index', 10000)
168
+ // .style('left', (d) => {
169
+ // const x = d.x + this.fullParams.offsetX! - containerSize.x
170
+ // if (x < minX) {
171
+ // return `${minX}px`
172
+ // } else if (x > maxX) {
173
+ // return `${maxX}px`
174
+ // }
175
+ // return `${x}px`
176
+ // })
177
+ // .style('top', (d) => {
178
+ // const y = d.y + this.fullParams.offsetY! - containerSize.y
179
+ // if (y < minY) {
180
+ // return `${minY}px`
181
+ // } else if (y > maxY) {
182
+ // return `${maxY}px`
183
+ // }
184
+ // return `${y}px`
185
+ // })
186
+ // .html((d) => d.contentHtml)
187
+
188
+
189
+ }
190
+
191
+ export const Tooltip: PluginConstructor<any, string, any> = defineNoneDataPlugin(pluginName, TOOLTIP_PARAMS)(({ selection, rootSelection, name, chartType, observer, subject }) => {
192
+ const destroy$ = new Subject()
193
+
194
+ // 事件觸發
195
+ const eventMouseover$: Observable<EventTypeMap<any>> = subject.event$.pipe(
196
+ takeUntil(destroy$),
197
+ filter(d => d.eventName === 'mouseover' || d.eventName === 'mousemove'),
198
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
199
+ // map(d => d as EventTypeMap<typeof chartType>)
200
+ )
201
+ const eventMouseout$: Observable<EventTypeMap<any>> = subject.event$.pipe(
202
+ takeUntil(destroy$),
203
+ filter(d => d.eventName === 'mouseout'),
204
+ // distinctUntilChanged((prev, current) => prev.eventName === current.eventName)
205
+ // map(d => d as EventTypeMap<typeof chartType>)
206
+ )
207
+
208
+ const textSizePx$ = textSizePxObservable(observer.fullChartParams$)
209
+
210
+ const tooltipStyle$: Observable<TooltipStyle> = combineLatest({
211
+ fullChartParams: observer.fullChartParams$,
212
+ fullParams: observer.fullParams$,
213
+ textSizePx: textSizePx$
214
+ }).pipe(
215
+ takeUntil(destroy$),
216
+ switchMap(async d => d),
217
+ map(data => {
218
+ return {
219
+ backgroundColor: getColor(data.fullParams.backgroundColorType, data.fullChartParams),
220
+ backgroundOpacity: data.fullParams.backgroundOpacity,
221
+ strokeColor: getColor(data.fullParams.strokeColorType, data.fullChartParams),
222
+ offset: data.fullParams.offset,
223
+ padding: data.fullParams.padding,
224
+ textSize: data.fullChartParams.styles.textSize,
225
+ textSizePx: data.textSizePx,
226
+ textColor: getColor(data.fullParams.textColorType, data.fullChartParams),
227
+ }
228
+ })
229
+ )
230
+
231
+ const contentRenderFn$: Observable<((eventData: EventTypeMap<any>) => string)> = combineLatest({
232
+ fullParams: observer.fullParams$,
233
+ tooltipStyle: tooltipStyle$
234
+ }).pipe(
235
+ takeUntil(destroy$),
236
+ switchMap(async d => d),
237
+ map(d => {
238
+ if (d.fullParams.svgRenderFn) {
239
+ return d.fullParams.svgRenderFn
240
+ }
241
+ // 將textRenderFn回傳的資料使用<text>包裝起來
242
+ return (eventData: EventTypeMap<any>) => {
243
+ const textArr = d.fullParams.textRenderFn(eventData as any)
244
+ return textToSvg(textArr, d.tooltipStyle)
245
+ }
246
+ })
247
+ )
248
+
249
+ const mouseoverTooltipSvg$ = combineLatest({
250
+ event: eventMouseover$,
251
+ contentRenderFn: contentRenderFn$
252
+ }).pipe(
253
+ takeUntil(destroy$),
254
+ switchMap(async d => d),
255
+ map(d => d.contentRenderFn(d.event))
256
+ )
257
+
258
+ const mouseoutTooltipSvg$ = eventMouseout$.pipe(
259
+ takeUntil(destroy$),
260
+ map(d => '')
261
+ )
262
+
263
+ const event$ = merge(eventMouseover$, eventMouseout$)
264
+ .pipe(
265
+ takeUntil(destroy$),
266
+ // filter(d => {
267
+ // return (d.eventName === 'mouseover' || d.eventName === 'mousemove' || d.eventName === 'mouseout')
268
+ // && d.event != undefined
269
+ // }),
270
+ map(d => d.event!),
271
+ )
272
+
273
+ combineLatest({
274
+ svgString: merge(mouseoverTooltipSvg$, mouseoutTooltipSvg$),
275
+ event: event$,
276
+ layout: observer.layout$,
277
+ tooltipStyle: tooltipStyle$,
278
+ }).pipe(
279
+ takeUntil(destroy$),
280
+ switchMap(async d => d),
281
+ ).subscribe(data => {
282
+ // console.log('svgString', data.svgString)
283
+ renderTooltip({
284
+ rootSelection,
285
+ pluginName: name,
286
+ rootWidth: data.layout.rootWidth,
287
+ rootHeight: data.layout.rootHeight,
288
+ svgString: data.svgString,
289
+ tooltipStyle: data.tooltipStyle,
290
+ event: data.event
291
+ })
292
+ })
293
+
294
+
295
+
296
+ // const chartType$ = eventMouseover$.pipe(
297
+ // takeUntil(destroy$),
298
+ // map(d => d.type),
299
+ // distinctUntilChanged()
300
+ // )
301
+
302
+
303
+ // eventMouseover$.subscribe(event => {
304
+
305
+ // })
306
+
307
+
308
+ return function unsubscribe () {
309
+ destroy$.next(undefined)
310
+ }
305
311
  })