@orbcharts/plugins-basic 3.0.0-beta.4 → 3.0.0-beta.6

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 (192) hide show
  1. package/LICENSE +200 -200
  2. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseBarStack.d.ts +2 -2
  3. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseBars.d.ts +2 -2
  4. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseBarsTriangle.d.ts +2 -2
  5. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseDots.d.ts +2 -2
  6. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseGroupAxis.d.ts +2 -2
  7. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseLegend.d.ts +1 -1
  8. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseLineAreas.d.ts +3 -3
  9. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseLines.d.ts +3 -3
  10. package/dist/{src → orbcharts-plugins-basic/src}/base/BaseValueAxis.d.ts +3 -2
  11. package/dist/{src → orbcharts-plugins-basic/src}/grid/defaults.d.ts +1 -1
  12. package/dist/{src → orbcharts-plugins-basic/src}/grid/gridObservables.d.ts +5 -5
  13. package/dist/orbcharts-plugins-basic/src/index.d.ts +6 -0
  14. package/dist/orbcharts-plugins-basic/src/multiValue/defaults.d.ts +9 -0
  15. package/dist/orbcharts-plugins-basic/src/multiValue/index.d.ts +8 -0
  16. package/dist/orbcharts-plugins-basic/src/multiValue/multiValueObservables.d.ts +33 -0
  17. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/MultiValueLegend.d.ts +1 -0
  18. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/MultiValueTooltip.d.ts +1 -0
  19. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/Scatter.d.ts +3 -0
  20. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/ScatterBubbles.d.ts +3 -0
  21. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/XYAux.d.ts +3 -0
  22. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/XYAxes.d.ts +3 -0
  23. package/dist/orbcharts-plugins-basic/src/multiValue/plugins/XYZoom.d.ts +1 -0
  24. package/dist/{src → orbcharts-plugins-basic/src}/series/seriesObservables.d.ts +3 -3
  25. package/dist/{src → orbcharts-plugins-basic/src}/utils/observables.d.ts +1 -1
  26. package/dist/{src → orbcharts-plugins-basic/src}/utils/orbchartsUtils.d.ts +3 -3
  27. package/dist/orbcharts-plugins-basic.es.js +11809 -10185
  28. package/dist/orbcharts-plugins-basic.umd.js +66 -34
  29. package/dist/src/index.d.ts +1 -5
  30. package/lib/core-types.ts +7 -7
  31. package/lib/core.ts +6 -6
  32. package/lib/plugins-basic-types.ts +6 -6
  33. package/package.json +44 -44
  34. package/src/base/BaseBarStack.ts +780 -780
  35. package/src/base/BaseBars.ts +765 -765
  36. package/src/base/BaseBarsTriangle.ts +674 -674
  37. package/src/base/BaseDots.ts +464 -515
  38. package/src/base/BaseGroupAxis.ts +679 -679
  39. package/src/base/BaseLegend.ts +684 -680
  40. package/src/base/BaseLineAreas.ts +629 -629
  41. package/src/base/BaseLines.ts +706 -706
  42. package/src/base/BaseTooltip.ts +385 -385
  43. package/src/base/BaseValueAxis.ts +583 -580
  44. package/src/base/types.ts +2 -2
  45. package/src/const.ts +30 -30
  46. package/src/grid/defaults.ts +244 -244
  47. package/src/grid/gridObservables.ts +554 -545
  48. package/src/grid/index.ts +16 -16
  49. package/src/grid/plugins/BarStack.ts +64 -64
  50. package/src/grid/plugins/Bars.ts +69 -69
  51. package/src/grid/plugins/BarsPN.ts +66 -66
  52. package/src/grid/plugins/BarsTriangle.ts +73 -73
  53. package/src/grid/plugins/Dots.ts +68 -68
  54. package/src/grid/plugins/GridLegend.ts +107 -107
  55. package/src/grid/plugins/GridTooltip.ts +66 -66
  56. package/src/grid/plugins/GridZoom.ts +218 -218
  57. package/src/grid/plugins/GroupAux.ts +1103 -1098
  58. package/src/grid/plugins/GroupAxis.ts +97 -97
  59. package/src/grid/plugins/LineAreas.ts +65 -65
  60. package/src/grid/plugins/Lines.ts +59 -59
  61. package/src/grid/plugins/ValueAxis.ts +94 -93
  62. package/src/grid/plugins/ValueStackAxis.ts +96 -95
  63. package/src/index.ts +10 -9
  64. package/src/multiGrid/defaults.ts +224 -224
  65. package/src/multiGrid/index.ts +14 -14
  66. package/src/multiGrid/multiGridObservables.ts +49 -49
  67. package/src/multiGrid/plugins/MultiBarStack.ts +106 -106
  68. package/src/multiGrid/plugins/MultiBars.ts +108 -108
  69. package/src/multiGrid/plugins/MultiBarsTriangle.ts +114 -114
  70. package/src/multiGrid/plugins/MultiDots.ts +102 -102
  71. package/src/multiGrid/plugins/MultiGridLegend.ts +159 -159
  72. package/src/multiGrid/plugins/MultiGridTooltip.ts +66 -66
  73. package/src/multiGrid/plugins/MultiGroupAxis.ts +137 -137
  74. package/src/multiGrid/plugins/MultiLineAreas.ts +107 -107
  75. package/src/multiGrid/plugins/MultiLines.ts +101 -101
  76. package/src/multiGrid/plugins/MultiValueAxis.ts +134 -133
  77. package/src/multiGrid/plugins/MultiValueStackAxis.ts +134 -133
  78. package/src/multiGrid/plugins/OverlappingValueAxes.ts +300 -299
  79. package/src/multiGrid/plugins/OverlappingValueStackAxes.ts +299 -298
  80. package/src/multiValue/defaults.ts +163 -0
  81. package/src/multiValue/index.ts +9 -0
  82. package/src/multiValue/multiValueObservables.ts +258 -0
  83. package/src/multiValue/plugins/MultiValueLegend.ts +107 -0
  84. package/src/multiValue/plugins/MultiValueTooltip.ts +66 -0
  85. package/src/multiValue/plugins/Scatter.ts +426 -0
  86. package/src/multiValue/plugins/ScatterBubbles.ts +551 -0
  87. package/src/multiValue/plugins/XYAux.ts +682 -0
  88. package/src/multiValue/plugins/XYAxes.ts +677 -0
  89. package/src/multiValue/plugins/XYZoom.ts +300 -0
  90. package/src/noneData/defaults.ts +102 -102
  91. package/src/noneData/index.ts +3 -3
  92. package/src/noneData/plugins/Container.ts +27 -27
  93. package/src/noneData/plugins/Tooltip.ts +373 -373
  94. package/src/series/defaults.ts +206 -206
  95. package/src/series/index.ts +9 -9
  96. package/src/series/plugins/Bubbles.ts +603 -603
  97. package/src/series/plugins/Pie.ts +623 -623
  98. package/src/series/plugins/PieEventTexts.ts +283 -283
  99. package/src/series/plugins/PieLabels.ts +640 -640
  100. package/src/series/plugins/Rose.ts +516 -516
  101. package/src/series/plugins/RoseLabels.ts +600 -600
  102. package/src/series/plugins/SeriesLegend.ts +107 -107
  103. package/src/series/plugins/SeriesTooltip.ts +66 -66
  104. package/src/series/seriesObservables.ts +145 -145
  105. package/src/series/seriesUtils.ts +51 -51
  106. package/src/tree/defaults.ts +78 -78
  107. package/src/tree/index.ts +4 -4
  108. package/src/tree/plugins/TreeLegend.ts +100 -107
  109. package/src/tree/plugins/TreeMap.ts +333 -333
  110. package/src/tree/plugins/TreeTooltip.ts +66 -66
  111. package/src/utils/commonUtils.ts +21 -21
  112. package/src/utils/d3Graphics.ts +174 -174
  113. package/src/utils/d3Utils.ts +74 -73
  114. package/src/utils/observables.ts +14 -14
  115. package/src/utils/orbchartsUtils.ts +101 -100
  116. package/tsconfig.base.json +13 -13
  117. package/tsconfig.json +2 -2
  118. package/vite.config.js +22 -22
  119. package/dist/src/base/BaseGroupArea.d.ts +0 -0
  120. package/dist/src/multiValue/plugins/Scatter.d.ts +0 -0
  121. package/dist/src/multiValue/plugins/ScatterAxes.d.ts +0 -0
  122. package/dist/src/relationship/index.d.ts +0 -0
  123. package/src/base/BaseGroupArea.ts +0 -0
  124. package/src/multiValue/plugins/ScatterAxes.ts +0 -0
  125. /package/dist/{lib → orbcharts-plugins-basic/lib}/core-types.d.ts +0 -0
  126. /package/dist/{lib → orbcharts-plugins-basic/lib}/core.d.ts +0 -0
  127. /package/dist/{lib → orbcharts-plugins-basic/lib}/plugins-basic-types.d.ts +0 -0
  128. /package/dist/{src → orbcharts-plugins-basic/src}/base/BaseTooltip.d.ts +0 -0
  129. /package/dist/{src → orbcharts-plugins-basic/src}/base/types.d.ts +0 -0
  130. /package/dist/{src → orbcharts-plugins-basic/src}/const.d.ts +0 -0
  131. /package/dist/{src → orbcharts-plugins-basic/src}/grid/index.d.ts +0 -0
  132. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/BarStack.d.ts +0 -0
  133. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/Bars.d.ts +0 -0
  134. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/BarsPN.d.ts +0 -0
  135. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/BarsTriangle.d.ts +0 -0
  136. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/Dots.d.ts +0 -0
  137. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/GridLegend.d.ts +0 -0
  138. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/GridTooltip.d.ts +0 -0
  139. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/GridZoom.d.ts +0 -0
  140. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/GroupAux.d.ts +0 -0
  141. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/GroupAxis.d.ts +0 -0
  142. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/LineAreas.d.ts +0 -0
  143. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/Lines.d.ts +0 -0
  144. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/ValueAxis.d.ts +0 -0
  145. /package/dist/{src → orbcharts-plugins-basic/src}/grid/plugins/ValueStackAxis.d.ts +0 -0
  146. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/defaults.d.ts +0 -0
  147. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/index.d.ts +0 -0
  148. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/multiGridObservables.d.ts +0 -0
  149. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiBarStack.d.ts +0 -0
  150. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiBars.d.ts +0 -0
  151. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiBarsTriangle.d.ts +0 -0
  152. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiDots.d.ts +0 -0
  153. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiGridLegend.d.ts +0 -0
  154. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiGridTooltip.d.ts +0 -0
  155. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiGroupAxis.d.ts +0 -0
  156. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiLineAreas.d.ts +0 -0
  157. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiLines.d.ts +0 -0
  158. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiValueAxis.d.ts +0 -0
  159. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/MultiValueStackAxis.d.ts +0 -0
  160. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/OverlappingValueAxes.d.ts +0 -0
  161. /package/dist/{src → orbcharts-plugins-basic/src}/multiGrid/plugins/OverlappingValueStackAxes.d.ts +0 -0
  162. /package/dist/{src/grid → orbcharts-plugins-basic/src/multiValue}/plugins/Ranking.d.ts +0 -0
  163. /package/dist/{src/grid → orbcharts-plugins-basic/src/multiValue}/plugins/RankingAxis.d.ts +0 -0
  164. /package/dist/{src → orbcharts-plugins-basic/src}/noneData/defaults.d.ts +0 -0
  165. /package/dist/{src → orbcharts-plugins-basic/src}/noneData/index.d.ts +0 -0
  166. /package/dist/{src → orbcharts-plugins-basic/src}/noneData/plugins/Container.d.ts +0 -0
  167. /package/dist/{src → orbcharts-plugins-basic/src}/noneData/plugins/Tooltip.d.ts +0 -0
  168. /package/dist/{src/multiValue → orbcharts-plugins-basic/src/relationship}/index.d.ts +0 -0
  169. /package/dist/{src → orbcharts-plugins-basic/src}/relationship/plugins/Relationship.d.ts +0 -0
  170. /package/dist/{src → orbcharts-plugins-basic/src}/series/defaults.d.ts +0 -0
  171. /package/dist/{src → orbcharts-plugins-basic/src}/series/index.d.ts +0 -0
  172. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/Bubbles.d.ts +0 -0
  173. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/Pie.d.ts +0 -0
  174. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/PieEventTexts.d.ts +0 -0
  175. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/PieLabels.d.ts +0 -0
  176. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/Rose.d.ts +0 -0
  177. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/RoseLabels.d.ts +0 -0
  178. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/SeriesLegend.d.ts +0 -0
  179. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/SeriesTooltip.d.ts +0 -0
  180. /package/dist/{src → orbcharts-plugins-basic/src}/series/plugins/Waffle.d.ts +0 -0
  181. /package/dist/{src → orbcharts-plugins-basic/src}/series/seriesUtils.d.ts +0 -0
  182. /package/dist/{src → orbcharts-plugins-basic/src}/tree/defaults.d.ts +0 -0
  183. /package/dist/{src → orbcharts-plugins-basic/src}/tree/index.d.ts +0 -0
  184. /package/dist/{src → orbcharts-plugins-basic/src}/tree/plugins/TreeLegend.d.ts +0 -0
  185. /package/dist/{src → orbcharts-plugins-basic/src}/tree/plugins/TreeMap.d.ts +0 -0
  186. /package/dist/{src → orbcharts-plugins-basic/src}/tree/plugins/TreeTooltip.d.ts +0 -0
  187. /package/dist/{src → orbcharts-plugins-basic/src}/utils/commonUtils.d.ts +0 -0
  188. /package/dist/{src → orbcharts-plugins-basic/src}/utils/d3Graphics.d.ts +0 -0
  189. /package/dist/{src → orbcharts-plugins-basic/src}/utils/d3Utils.d.ts +0 -0
  190. /package/dist/{vite.config.d.ts → orbcharts-plugins-basic/vite.config.d.ts} +0 -0
  191. /package/src/{grid → multiValue}/plugins/Ranking.ts +0 -0
  192. /package/src/{grid → multiValue}/plugins/RankingAxis.ts +0 -0
@@ -1,66 +1,66 @@
1
- import {
2
- Subject,
3
- } from 'rxjs'
4
- import type { DefinePluginConfig } from '../../../lib/core-types'
5
- import {
6
- defineTreePlugin } from '../../../lib/core'
7
- import { DEFAULT_TREE_TOOLTIP_PARAMS } from '../defaults'
8
- import { LAYER_INDEX_OF_TOOLTIP } from '../../const'
9
- import { createBaseTooltip } from '../../base/BaseTooltip'
10
-
11
- const pluginName = 'TreeTooltip'
12
-
13
- const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_TREE_TOOLTIP_PARAMS> = {
14
- name: pluginName,
15
- defaultParams: DEFAULT_TREE_TOOLTIP_PARAMS,
16
- layerIndex: LAYER_INDEX_OF_TOOLTIP,
17
- validator: (params, { validateColumns }) => {
18
- const result = validateColumns(params, {
19
- backgroundColorType: {
20
- toBeOption: 'ColorType',
21
- },
22
- backgroundOpacity: {
23
- toBeTypes: ['number']
24
- },
25
- strokeColorType: {
26
- toBeOption: 'ColorType',
27
- },
28
- offset: {
29
- toBe: '[number, number]',
30
- test: (value: any) => {
31
- return Array.isArray(value)
32
- && value.length === 2
33
- && typeof value[0] === 'number'
34
- && typeof value[1] === 'number'
35
- }
36
- },
37
- padding: {
38
- toBeTypes: ['number']
39
- },
40
- textColorType: {
41
- toBeOption: 'ColorType',
42
- },
43
- renderFn: {
44
- toBeTypes: ['Function']
45
- },
46
- })
47
- return result
48
- }
49
- }
50
-
51
- export const TreeTooltip = defineTreePlugin(pluginConfig)(({ selection, rootSelection, name, subject, observer }) => {
52
- const destroy$ = new Subject()
53
-
54
- const unsubscribeTooltip = createBaseTooltip(pluginName, {
55
- rootSelection,
56
- fullParams$: observer.fullParams$,
57
- fullChartParams$: observer.fullChartParams$,
58
- layout$: observer.layout$,
59
- event$: subject.event$,
60
- })
61
-
62
- return () => {
63
- destroy$.next(undefined)
64
- unsubscribeTooltip()
65
- }
66
- })
1
+ import {
2
+ Subject,
3
+ } from 'rxjs'
4
+ import type { DefinePluginConfig } from '../../../lib/core-types'
5
+ import {
6
+ defineTreePlugin } from '../../../lib/core'
7
+ import { DEFAULT_TREE_TOOLTIP_PARAMS } from '../defaults'
8
+ import { LAYER_INDEX_OF_TOOLTIP } from '../../const'
9
+ import { createBaseTooltip } from '../../base/BaseTooltip'
10
+
11
+ const pluginName = 'TreeTooltip'
12
+
13
+ const pluginConfig: DefinePluginConfig<typeof pluginName, typeof DEFAULT_TREE_TOOLTIP_PARAMS> = {
14
+ name: pluginName,
15
+ defaultParams: DEFAULT_TREE_TOOLTIP_PARAMS,
16
+ layerIndex: LAYER_INDEX_OF_TOOLTIP,
17
+ validator: (params, { validateColumns }) => {
18
+ const result = validateColumns(params, {
19
+ backgroundColorType: {
20
+ toBeOption: 'ColorType',
21
+ },
22
+ backgroundOpacity: {
23
+ toBeTypes: ['number']
24
+ },
25
+ strokeColorType: {
26
+ toBeOption: 'ColorType',
27
+ },
28
+ offset: {
29
+ toBe: '[number, number]',
30
+ test: (value: any) => {
31
+ return Array.isArray(value)
32
+ && value.length === 2
33
+ && typeof value[0] === 'number'
34
+ && typeof value[1] === 'number'
35
+ }
36
+ },
37
+ padding: {
38
+ toBeTypes: ['number']
39
+ },
40
+ textColorType: {
41
+ toBeOption: 'ColorType',
42
+ },
43
+ renderFn: {
44
+ toBeTypes: ['Function']
45
+ },
46
+ })
47
+ return result
48
+ }
49
+ }
50
+
51
+ export const TreeTooltip = defineTreePlugin(pluginConfig)(({ selection, rootSelection, name, subject, observer }) => {
52
+ const destroy$ = new Subject()
53
+
54
+ const unsubscribeTooltip = createBaseTooltip(pluginName, {
55
+ rootSelection,
56
+ fullParams$: observer.fullParams$,
57
+ fullChartParams$: observer.fullChartParams$,
58
+ layout$: observer.layout$,
59
+ event$: subject.event$,
60
+ })
61
+
62
+ return () => {
63
+ destroy$.next(undefined)
64
+ unsubscribeTooltip()
65
+ }
66
+ })
@@ -1,22 +1,22 @@
1
- // 取得文字寬度
2
- export function measureTextWidth (text: string, size: number = 10) {
3
- const context = document.createElement("canvas").getContext("2d")
4
- let width = context?.measureText(text)?.width ?? 0
5
- return width * size / 10 // 以10為基準
6
- }
7
-
8
- // 取得最小及最大值 - 數字陣列
9
- export function getMinAndMax (data: number[]): [number, number] {
10
- const defaultMinAndMax: [number, number] = [0, 0] // default
11
- if (!data.length) {
12
- return defaultMinAndMax
13
- }
14
- const minAndMax: [number, number] = data.reduce((prev, current) => {
15
- // [min, max]
16
- return [
17
- current < prev[0] ? current : prev[0],
18
- current > prev[1] ? current : prev[1]
19
- ]
20
- }, [data[0], data[0]])
21
- return minAndMax
1
+ // 取得文字寬度
2
+ export function measureTextWidth (text: string, size: number = 10) {
3
+ const context = document.createElement("canvas").getContext("2d")
4
+ let width = context?.measureText(text)?.width ?? 0
5
+ return width * size / 10 // 以10為基準
6
+ }
7
+
8
+ // 取得最小及最大值 - 數字陣列
9
+ export function getMinAndMax (data: number[]): [number, number] {
10
+ const defaultMinAndMax: [number, number] = [0, 0] // default
11
+ if (!data.length) {
12
+ return defaultMinAndMax
13
+ }
14
+ const minAndMax: [number, number] = data.reduce((prev, current) => {
15
+ // [min, max]
16
+ return [
17
+ current < prev[0] ? current : prev[0],
18
+ current > prev[1] ? current : prev[1]
19
+ ]
20
+ }, [data[0], data[0]])
21
+ return minAndMax
22
22
  }
@@ -1,175 +1,175 @@
1
-
2
- type RenderCircleTextParams = {
3
- text: string,
4
- radius: number,
5
- lineHeight: number,
6
- isBreakAll: boolean,
7
- limit?:number
8
- }
9
-
10
- type Line = { width: number; text: string }
11
-
12
- export function renderCircleText (selection: d3.Selection<any, any, any, any>, {
13
- text,
14
- radius,
15
- lineHeight,
16
- isBreakAll = false,
17
- limit = 0
18
- }: RenderCircleTextParams): d3.Selection<SVGTSpanElement, Line, SVGTextElement, any> | undefined {
19
- if (selection == null || text == null) {
20
- console.error("selection or text is not defined")
21
- return
22
- }
23
- if (radius == null) {
24
- const getBox = selection.node().getBBox()
25
- radius = getBox.width / 2
26
- }
27
-
28
- function getWords (text: string) {
29
- let words
30
- if (isBreakAll) {
31
- words = text.split('')
32
- } else {
33
- words = text.split(/\s+/g) // To hyphenate: /\s+|(?<=-)/
34
- }
35
- if (!words[words.length - 1]) words.pop()
36
- if (!words[0]) words.shift()
37
- return words
38
- }
39
-
40
- // 省略文章字數
41
- function ellipisText (text:string, limit:number) {
42
- if (text && limit) {
43
- if (text.length > limit) {
44
- text = text.substring(0, limit) + "..."; // 超過字數以"..."取代
45
- }
46
- }
47
- return text;
48
- }
49
-
50
- function measureWidth (text: string) {
51
- const context = document.createElement("canvas").getContext("2d")
52
- // return text => context.measureText(text).width
53
- return context?.measureText(text)?.width ?? 0
54
- }
55
-
56
- function getTargetWidth (text: string) {
57
- const m = measureWidth(text.trim())
58
- const result = Math.sqrt(m * lineHeight)
59
- return result
60
- // return(
61
- // Math.sqrt(measureWidth(text.trim()) * lineHeight)
62
- // )
63
- }
64
-
65
- function getLines (words: string[], targetWidth: number) {
66
- let line: Line = { width: 0, text: '' }
67
- let lineWidth0 = Infinity
68
- const lines: Array<Line> = []
69
- let space = " "
70
- if (isBreakAll) {
71
- space = ""
72
- }
73
- for (let i = 0, n = words.length; i < n; ++i) {
74
- const lineText1 = (line.text ? line.text + space : '') + words[i]
75
- const lineWidth1 = measureWidth(lineText1)
76
- if ((lineWidth0 + lineWidth1) / 2 < targetWidth) {
77
- line.width = lineWidth0 = lineWidth1
78
- line.text = lineText1
79
- } else {
80
- lineWidth0 = measureWidth(words[i])
81
- line = {width: lineWidth0, text: words[i]}
82
- lines.push(line)
83
- }
84
- }
85
- return lines
86
- }
87
-
88
- function getTextRadius (lines: Array<Line>) {
89
- let radius = 0
90
- for (let i = 0, n = lines.length; i < n; ++i) {
91
- const dy: number = (Math.abs(i - n / 2 + 0.5) + 0.5) * lineHeight
92
- const dx: number = lines[i].width / 2
93
- radius = Math.max(radius, Math.sqrt(dx ** 2 + dy ** 2))
94
- }
95
- return radius
96
- }
97
-
98
- function draw (selection: d3.Selection<any, any, any, any>, text: string) {
99
- if(limit > 0) text = ellipisText(text,limit)
100
- const words = getWords(text)
101
- const targetWidth = getTargetWidth(text)
102
- const lines = getLines(words, targetWidth)
103
- const textRadius = getTextRadius(lines)
104
-
105
- let t = selection.select<SVGTextElement>("text")
106
- if (!t.size()) {
107
- t = selection.append("text")
108
- }
109
- t.attr("transform", `translate(${0},${0}) scale(${radius / textRadius})`)
110
- const tspanUpdate = t.selectAll<SVGTSpanElement, Line>("tspan")
111
- .data(lines)
112
- const tspanEnter = tspanUpdate.enter()
113
- .append<SVGTSpanElement>("tspan")
114
- .attr("x", 0)
115
- .merge(tspanUpdate as d3.Selection<SVGTSpanElement, Line, SVGTextElement, undefined>)
116
- .attr("y", (d: Line, i: number) => (i - lines.length / 2 + 0.8) * lineHeight)
117
- .text((d: Line) => d.text)
118
- tspanUpdate.exit().remove()
119
-
120
- // return selection.node()
121
- return tspanUpdate.merge(tspanEnter)
122
- }
123
-
124
- return draw(selection, text)
125
- }
126
-
127
- // 圖軸上的多行tspan
128
- export function renderTspansOnAxis (textSelection: d3.Selection<d3.BaseType, unknown, null, undefined>, {
129
- textArr,
130
- textSizePx,
131
- groupAxisPosition
132
- }: {
133
- textArr: string[]
134
- textSizePx: number
135
- groupAxisPosition: 'top' | 'right' | 'bottom' | 'left'
136
- }) {
137
- // -- 將原本單行文字改為多行文字 --
138
- textSelection.text(null) // 先清空原本的 text
139
-
140
- const textX = Number(textSelection.attr('x'))
141
- let textY = Number(textSelection.attr('y'))
142
- if (groupAxisPosition === 'top') {
143
- // 當文字在上方時,要往上偏移第一行的高度
144
- textY -= (textArr.length - 1) * textSizePx
145
- }
146
-
147
- textSelection
148
- .selectAll('tspan')
149
- .data(textArr)
150
- .join('tspan')
151
- .attr('x', textX)
152
- .attr('y', (_d, _i) => textY + _i * textSizePx)
153
- .text(d => d)
154
- }
155
-
156
- // 四象限上的多行tspan
157
- export function renderTspansOnQuadrant (textSelection: d3.Selection<d3.BaseType, unknown, null, undefined>, {
158
- textArr,
159
- textSizePx,
160
- quadrant
161
- }: {
162
- textArr: string[]
163
- textSizePx: number
164
- quadrant: number
165
- }) {
166
- textSelection
167
- .selectAll('tspan')
168
- .data(textArr)
169
- .join('tspan')
170
- .attr('x', 0)
171
- .attr('y', (_d, _i) => quadrant == 1 || quadrant == 2
172
- ? - (textArr.length - 1 - _i) * textSizePx
173
- : _i * textSizePx)
174
- .text(d => d)
1
+
2
+ type RenderCircleTextParams = {
3
+ text: string,
4
+ radius: number,
5
+ lineHeight: number,
6
+ isBreakAll: boolean,
7
+ limit?:number
8
+ }
9
+
10
+ type Line = { width: number; text: string }
11
+
12
+ export function renderCircleText (selection: d3.Selection<any, any, any, any>, {
13
+ text,
14
+ radius,
15
+ lineHeight,
16
+ isBreakAll = false,
17
+ limit = 0
18
+ }: RenderCircleTextParams): d3.Selection<SVGTSpanElement, Line, SVGTextElement, any> | undefined {
19
+ if (selection == null || text == null) {
20
+ console.error("selection or text is not defined")
21
+ return
22
+ }
23
+ if (radius == null) {
24
+ const getBox = selection.node().getBBox()
25
+ radius = getBox.width / 2
26
+ }
27
+
28
+ function getWords (text: string) {
29
+ let words
30
+ if (isBreakAll) {
31
+ words = text.split('')
32
+ } else {
33
+ words = text.split(/\s+/g) // To hyphenate: /\s+|(?<=-)/
34
+ }
35
+ if (!words[words.length - 1]) words.pop()
36
+ if (!words[0]) words.shift()
37
+ return words
38
+ }
39
+
40
+ // 省略文章字數
41
+ function ellipisText (text:string, limit:number) {
42
+ if (text && limit) {
43
+ if (text.length > limit) {
44
+ text = text.substring(0, limit) + "..."; // 超過字數以"..."取代
45
+ }
46
+ }
47
+ return text;
48
+ }
49
+
50
+ function measureWidth (text: string) {
51
+ const context = document.createElement("canvas").getContext("2d")
52
+ // return text => context.measureText(text).width
53
+ return context?.measureText(text)?.width ?? 0
54
+ }
55
+
56
+ function getTargetWidth (text: string) {
57
+ const m = measureWidth(text.trim())
58
+ const result = Math.sqrt(m * lineHeight)
59
+ return result
60
+ // return(
61
+ // Math.sqrt(measureWidth(text.trim()) * lineHeight)
62
+ // )
63
+ }
64
+
65
+ function getLines (words: string[], targetWidth: number) {
66
+ let line: Line = { width: 0, text: '' }
67
+ let lineWidth0 = Infinity
68
+ const lines: Array<Line> = []
69
+ let space = " "
70
+ if (isBreakAll) {
71
+ space = ""
72
+ }
73
+ for (let i = 0, n = words.length; i < n; ++i) {
74
+ const lineText1 = (line.text ? line.text + space : '') + words[i]
75
+ const lineWidth1 = measureWidth(lineText1)
76
+ if ((lineWidth0 + lineWidth1) / 2 < targetWidth) {
77
+ line.width = lineWidth0 = lineWidth1
78
+ line.text = lineText1
79
+ } else {
80
+ lineWidth0 = measureWidth(words[i])
81
+ line = {width: lineWidth0, text: words[i]}
82
+ lines.push(line)
83
+ }
84
+ }
85
+ return lines
86
+ }
87
+
88
+ function getTextRadius (lines: Array<Line>) {
89
+ let radius = 0
90
+ for (let i = 0, n = lines.length; i < n; ++i) {
91
+ const dy: number = (Math.abs(i - n / 2 + 0.5) + 0.5) * lineHeight
92
+ const dx: number = lines[i].width / 2
93
+ radius = Math.max(radius, Math.sqrt(dx ** 2 + dy ** 2))
94
+ }
95
+ return radius
96
+ }
97
+
98
+ function draw (selection: d3.Selection<any, any, any, any>, text: string) {
99
+ if(limit > 0) text = ellipisText(text,limit)
100
+ const words = getWords(text)
101
+ const targetWidth = getTargetWidth(text)
102
+ const lines = getLines(words, targetWidth)
103
+ const textRadius = getTextRadius(lines)
104
+
105
+ let t = selection.select<SVGTextElement>("text")
106
+ if (!t.size()) {
107
+ t = selection.append("text")
108
+ }
109
+ t.attr("transform", `translate(${0},${0}) scale(${radius / textRadius})`)
110
+ const tspanUpdate = t.selectAll<SVGTSpanElement, Line>("tspan")
111
+ .data(lines)
112
+ const tspanEnter = tspanUpdate.enter()
113
+ .append<SVGTSpanElement>("tspan")
114
+ .attr("x", 0)
115
+ .merge(tspanUpdate as d3.Selection<SVGTSpanElement, Line, SVGTextElement, undefined>)
116
+ .attr("y", (d: Line, i: number) => (i - lines.length / 2 + 0.8) * lineHeight)
117
+ .text((d: Line) => d.text)
118
+ tspanUpdate.exit().remove()
119
+
120
+ // return selection.node()
121
+ return tspanUpdate.merge(tspanEnter)
122
+ }
123
+
124
+ return draw(selection, text)
125
+ }
126
+
127
+ // 圖軸上的多行tspan
128
+ export function renderTspansOnAxis (textSelection: d3.Selection<d3.BaseType, unknown, null, undefined>, {
129
+ textArr,
130
+ textSizePx,
131
+ groupAxisPosition
132
+ }: {
133
+ textArr: string[]
134
+ textSizePx: number
135
+ groupAxisPosition: 'top' | 'right' | 'bottom' | 'left'
136
+ }) {
137
+ // -- 將原本單行文字改為多行文字 --
138
+ textSelection.text(null) // 先清空原本的 text
139
+
140
+ const textX = Number(textSelection.attr('x'))
141
+ let textY = Number(textSelection.attr('y'))
142
+ if (groupAxisPosition === 'top') {
143
+ // 當文字在上方時,要往上偏移第一行的高度
144
+ textY -= (textArr.length - 1) * textSizePx
145
+ }
146
+
147
+ textSelection
148
+ .selectAll('tspan')
149
+ .data(textArr)
150
+ .join('tspan')
151
+ .attr('x', textX)
152
+ .attr('y', (_d, _i) => textY + _i * textSizePx)
153
+ .text(d => d)
154
+ }
155
+
156
+ // 四象限上的多行tspan
157
+ export function renderTspansOnQuadrant (textSelection: d3.Selection<d3.BaseType, unknown, null, undefined>, {
158
+ textArr,
159
+ textSizePx,
160
+ quadrant
161
+ }: {
162
+ textArr: string[]
163
+ textSizePx: number
164
+ quadrant: number
165
+ }) {
166
+ textSelection
167
+ .selectAll('tspan')
168
+ .data(textArr)
169
+ .join('tspan')
170
+ .attr('x', 0)
171
+ .attr('y', (_d, _i) => quadrant == 1 || quadrant == 2
172
+ ? - (textArr.length - 1 - _i) * textSizePx
173
+ : _i * textSizePx)
174
+ .text(d => d)
175
175
  }
@@ -1,73 +1,74 @@
1
- import * as d3 from 'd3'
2
-
3
- export function getSvgGElementSize (selection: d3.Selection<SVGGElement, any, any, any>): DOMRect {
4
- try {
5
- return selection.node()!.getBBox()
6
- } catch (e: any) {
7
- throw new Error(e)
8
- }
9
- }
10
-
11
- // 使用字串加入svg
12
- export function appendSvg (selection: d3.Selection<any, any, any, any>, svgString: string): void {
13
- function parseSvg (svgString: string) {
14
- const div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
15
- div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+ svgString +'</svg>';
16
- const frag = document.createDocumentFragment()
17
- while (frag && div?.firstChild?.firstChild)
18
- frag.appendChild(div.firstChild.firstChild);
19
- return frag;
20
- }
21
- // 刪除現有子節點
22
- const node = selection.node()
23
- while(node.hasChildNodes())
24
- {
25
- node.removeChild(node.firstChild);
26
- }
27
- // 加入dom
28
- selection.node().appendChild(parseSvg(svgString))
29
- }
30
-
31
- export function getD3TransitionEase (easeName: string) {
32
- if (easeName.substring(0, 4) !== 'ease') {
33
- return d3.easeCubic
34
- }
35
- return (d3 as any)[easeName] ?? d3.easeCubic
36
- }
37
-
38
- export function makeD3Arc ({ axisWidth, innerRadius, outerRadius, padAngle, cornerRadius }: {
39
- axisWidth: number
40
- innerRadius: number
41
- outerRadius: number
42
- padAngle: number
43
- cornerRadius: number
44
- }): d3.Arc<any, d3.DefaultArcObject> {
45
- const arcScale = d3.scaleLinear()
46
- .domain([0, 1])
47
- .range([0, axisWidth / 2])
48
-
49
- const _outerRadius = arcScale(outerRadius)!
50
-
51
- return d3.arc()
52
- .innerRadius(arcScale(innerRadius)!)
53
- .outerRadius(_outerRadius)
54
- .padAngle(padAngle)
55
- .padRadius(_outerRadius)
56
- .cornerRadius(cornerRadius)
57
- }
58
-
59
- export const parseTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
60
- if (tickFormat! instanceof Function == true) {
61
- return (tickFormat as ((text: d3.NumberValue) => string))(value)
62
- }
63
- return d3.format(tickFormat as string)!(value)
64
- }
65
-
66
- export const parseDateTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
67
- if (tickFormat! instanceof Function == true) {
68
- return (tickFormat as ((text: d3.NumberValue) => string))(value)
69
- }
70
- return d3.timeFormat(tickFormat as string)!(value)
71
- }
72
-
73
-
1
+ import * as d3 from 'd3'
2
+
3
+ export function getSvgGElementSize (selection: d3.Selection<SVGGElement, any, any, any>): DOMRect {
4
+ try {
5
+ return selection.node()!.getBBox()
6
+ } catch (e: any) {
7
+ throw new Error(e)
8
+ }
9
+ }
10
+
11
+ // 使用字串加入svg
12
+ export function appendSvg (selection: d3.Selection<any, any, any, any>, svgString: string): void {
13
+ function parseSvg (svgString: string) {
14
+ const div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
15
+ div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+ svgString +'</svg>';
16
+ const frag = document.createDocumentFragment()
17
+ while (frag && div?.firstChild?.firstChild)
18
+ frag.appendChild(div.firstChild.firstChild);
19
+ return frag;
20
+ }
21
+ // 刪除現有子節點
22
+ const node = selection.node()
23
+ while(node.hasChildNodes())
24
+ {
25
+ node.removeChild(node.firstChild);
26
+ }
27
+ // 加入dom
28
+ selection.node().appendChild(parseSvg(svgString))
29
+ }
30
+
31
+ export function getD3TransitionEase (easeName: string) {
32
+ if (easeName.substring(0, 4) !== 'ease') {
33
+ return d3.easeCubic
34
+ }
35
+ return (d3 as any)[easeName] ?? d3.easeCubic
36
+ }
37
+
38
+ export function makeD3Arc ({ axisWidth, innerRadius, outerRadius, padAngle, cornerRadius }: {
39
+ axisWidth: number
40
+ innerRadius: number
41
+ outerRadius: number
42
+ padAngle: number
43
+ cornerRadius: number
44
+ }): d3.Arc<any, d3.DefaultArcObject> {
45
+ const arcScale = d3.scaleLinear()
46
+ .domain([0, 1])
47
+ .range([0, axisWidth / 2])
48
+
49
+ const _outerRadius = arcScale(outerRadius)!
50
+
51
+ return d3.arc()
52
+ .innerRadius(arcScale(innerRadius)!)
53
+ .outerRadius(_outerRadius)
54
+ .padAngle(padAngle)
55
+ .padRadius(_outerRadius)
56
+ .cornerRadius(cornerRadius)
57
+ }
58
+
59
+ export const parseTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
60
+ if (tickFormat! instanceof Function == true) {
61
+ const v = (tickFormat as ((text: d3.NumberValue) => string))(value)
62
+ return String(v ?? '')
63
+ }
64
+ return d3.format(tickFormat as string)!(value)
65
+ }
66
+
67
+ export const parseDateTickFormatValue = (value: any, tickFormat: string | ((text: d3.NumberValue) => string)) => {
68
+ if (tickFormat! instanceof Function == true) {
69
+ return (tickFormat as ((text: d3.NumberValue) => string))(value)
70
+ }
71
+ return d3.timeFormat(tickFormat as string)!(value)
72
+ }
73
+
74
+