@orbcharts/plugins-basic 3.0.0-alpha.57 → 3.0.0-alpha.58

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-plugins-basic.es.js +200 -195
  3. package/dist/orbcharts-plugins-basic.umd.js +2 -2
  4. package/package.json +43 -43
  5. package/src/base/BaseBarStack.ts +778 -778
  6. package/src/base/BaseBars.ts +764 -764
  7. package/src/base/BaseBarsTriangle.ts +672 -672
  8. package/src/base/BaseDots.ts +513 -513
  9. package/src/base/BaseGroupAxis.ts +558 -558
  10. package/src/base/BaseLegend.ts +641 -641
  11. package/src/base/BaseLineAreas.ts +628 -628
  12. package/src/base/BaseLines.ts +704 -704
  13. package/src/base/BaseValueAxis.ts +478 -478
  14. package/src/base/types.ts +2 -2
  15. package/src/grid/defaults.ts +128 -128
  16. package/src/grid/gridObservables.ts +541 -538
  17. package/src/grid/index.ts +15 -15
  18. package/src/grid/plugins/BarStack.ts +43 -43
  19. package/src/grid/plugins/Bars.ts +44 -44
  20. package/src/grid/plugins/BarsPN.ts +41 -41
  21. package/src/grid/plugins/BarsTriangle.ts +42 -42
  22. package/src/grid/plugins/Dots.ts +37 -37
  23. package/src/grid/plugins/GridLegend.ts +59 -59
  24. package/src/grid/plugins/GroupAux.ts +976 -976
  25. package/src/grid/plugins/GroupAxis.ts +35 -35
  26. package/src/grid/plugins/LineAreas.ts +40 -40
  27. package/src/grid/plugins/Lines.ts +40 -40
  28. package/src/grid/plugins/ScalingArea.ts +173 -173
  29. package/src/grid/plugins/ValueAxis.ts +36 -36
  30. package/src/grid/plugins/ValueStackAxis.ts +38 -38
  31. package/src/grid/types.ts +123 -123
  32. package/src/index.ts +9 -9
  33. package/src/multiGrid/defaults.ts +158 -158
  34. package/src/multiGrid/index.ts +13 -13
  35. package/src/multiGrid/multiGridObservables.ts +49 -49
  36. package/src/multiGrid/plugins/MultiBarStack.ts +78 -78
  37. package/src/multiGrid/plugins/MultiBars.ts +77 -77
  38. package/src/multiGrid/plugins/MultiBarsTriangle.ts +77 -77
  39. package/src/multiGrid/plugins/MultiDots.ts +65 -65
  40. package/src/multiGrid/plugins/MultiGridLegend.ts +89 -89
  41. package/src/multiGrid/plugins/MultiGroupAxis.ts +69 -69
  42. package/src/multiGrid/plugins/MultiLineAreas.ts +77 -77
  43. package/src/multiGrid/plugins/MultiLines.ts +77 -77
  44. package/src/multiGrid/plugins/MultiValueAxis.ts +69 -69
  45. package/src/multiGrid/plugins/MultiValueStackAxis.ts +69 -69
  46. package/src/multiGrid/plugins/OverlappingValueAxes.ts +167 -167
  47. package/src/multiGrid/plugins/OverlappingValueStackAxes.ts +168 -168
  48. package/src/multiGrid/types.ts +72 -72
  49. package/src/noneData/defaults.ts +102 -102
  50. package/src/noneData/index.ts +3 -3
  51. package/src/noneData/plugins/Container.ts +10 -10
  52. package/src/noneData/plugins/Tooltip.ts +310 -310
  53. package/src/noneData/types.ts +26 -26
  54. package/src/series/defaults.ts +144 -144
  55. package/src/series/index.ts +9 -9
  56. package/src/series/plugins/Bubbles.ts +545 -545
  57. package/src/series/plugins/Pie.ts +576 -576
  58. package/src/series/plugins/PieEventTexts.ts +262 -262
  59. package/src/series/plugins/PieLabels.ts +304 -304
  60. package/src/series/plugins/Rose.ts +472 -472
  61. package/src/series/plugins/RoseLabels.ts +362 -362
  62. package/src/series/plugins/SeriesLegend.ts +59 -59
  63. package/src/series/seriesObservables.ts +145 -145
  64. package/src/series/seriesUtils.ts +51 -51
  65. package/src/series/types.ts +83 -83
  66. package/src/tree/defaults.ts +23 -23
  67. package/src/tree/index.ts +3 -3
  68. package/src/tree/plugins/TreeLegend.ts +59 -59
  69. package/src/tree/plugins/TreeMap.ts +305 -305
  70. package/src/tree/types.ts +23 -23
  71. package/src/utils/commonUtils.ts +21 -21
  72. package/src/utils/d3Graphics.ts +124 -124
  73. package/src/utils/d3Utils.ts +73 -73
  74. package/src/utils/observables.ts +14 -14
  75. package/src/utils/orbchartsUtils.ts +100 -100
  76. package/tsconfig.base.json +13 -13
  77. package/tsconfig.json.bak.vite-plugin-tsconfig +7 -7
  78. package/tsconfig.prod.json +2 -2
  79. package/vite.config.mjs +40 -40
@@ -1,311 +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
- 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
- }
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
+ }
311
311
  })
@@ -1,26 +1,26 @@
1
- import type { ColorType, ChartType, EventTypeMap, EventBase } from '@orbcharts/core'
2
-
3
- export interface ContainerPluginParams {
4
- header: {
5
- height: number
6
- text: string[]
7
- textStyle: string[]
8
- }
9
- footer: {
10
- height: number
11
- text: string[]
12
- textStyle: string[]
13
- }
14
- }
15
-
16
- export type TooltipParams = {
17
- backgroundColorType: ColorType
18
- backgroundOpacity: number
19
- strokeColorType: ColorType
20
- textColorType: ColorType
21
- offset: [number, number]
22
- padding: number
23
- textRenderFn: <T extends ChartType> (eventData: EventTypeMap<T>) => string[]
24
- svgRenderFn: (<T extends ChartType> (eventData: EventTypeMap<T>) => string) | null
25
- }
26
-
1
+ import type { ColorType, ChartType, EventTypeMap, EventBase } from '@orbcharts/core'
2
+
3
+ export interface ContainerPluginParams {
4
+ header: {
5
+ height: number
6
+ text: string[]
7
+ textStyle: string[]
8
+ }
9
+ footer: {
10
+ height: number
11
+ text: string[]
12
+ textStyle: string[]
13
+ }
14
+ }
15
+
16
+ export type TooltipParams = {
17
+ backgroundColorType: ColorType
18
+ backgroundOpacity: number
19
+ strokeColorType: ColorType
20
+ textColorType: ColorType
21
+ offset: [number, number]
22
+ padding: number
23
+ textRenderFn: <T extends ChartType> (eventData: EventTypeMap<T>) => string[]
24
+ svgRenderFn: (<T extends ChartType> (eventData: EventTypeMap<T>) => string) | null
25
+ }
26
+