@orbcharts/core 3.0.5 → 3.0.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 (68) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-core.es.js +2217 -2164
  3. package/dist/orbcharts-core.umd.js +5 -5
  4. package/lib/core-types.ts +7 -7
  5. package/package.json +46 -46
  6. package/src/AbstractChart.ts +57 -57
  7. package/src/GridChart.ts +24 -24
  8. package/src/MultiGridChart.ts +24 -24
  9. package/src/MultiValueChart.ts +24 -24
  10. package/src/RelationshipChart.ts +24 -24
  11. package/src/SeriesChart.ts +24 -24
  12. package/src/TreeChart.ts +24 -24
  13. package/src/base/createBaseChart.ts +524 -524
  14. package/src/base/createBasePlugin.ts +154 -154
  15. package/src/base/validators/chartOptionsValidator.ts +23 -23
  16. package/src/base/validators/chartParamsValidator.ts +133 -133
  17. package/src/base/validators/elementValidator.ts +13 -13
  18. package/src/base/validators/pluginsValidator.ts +14 -14
  19. package/src/defaults.ts +284 -284
  20. package/src/defineGridPlugin.ts +3 -3
  21. package/src/defineMultiGridPlugin.ts +3 -3
  22. package/src/defineMultiValuePlugin.ts +3 -3
  23. package/src/defineNoneDataPlugin.ts +4 -4
  24. package/src/defineRelationshipPlugin.ts +3 -3
  25. package/src/defineSeriesPlugin.ts +3 -3
  26. package/src/defineTreePlugin.ts +3 -3
  27. package/src/grid/computedDataFn.ts +129 -129
  28. package/src/grid/contextObserverCallback.ts +209 -201
  29. package/src/grid/dataFormatterValidator.ts +125 -125
  30. package/src/grid/dataValidator.ts +12 -12
  31. package/src/grid/gridObservables.ts +698 -694
  32. package/src/index.ts +20 -20
  33. package/src/multiGrid/computedDataFn.ts +123 -123
  34. package/src/multiGrid/contextObserverCallback.ts +109 -75
  35. package/src/multiGrid/dataFormatterValidator.ts +120 -120
  36. package/src/multiGrid/dataValidator.ts +12 -12
  37. package/src/multiGrid/multiGridObservables.ts +366 -357
  38. package/src/multiValue/computedDataFn.ts +113 -113
  39. package/src/multiValue/contextObserverCallback.ts +328 -328
  40. package/src/multiValue/dataFormatterValidator.ts +94 -94
  41. package/src/multiValue/dataValidator.ts +12 -12
  42. package/src/multiValue/multiValueObservables.ts +865 -865
  43. package/src/relationship/computedDataFn.ts +159 -159
  44. package/src/relationship/contextObserverCallback.ts +80 -80
  45. package/src/relationship/dataFormatterValidator.ts +13 -13
  46. package/src/relationship/dataValidator.ts +13 -13
  47. package/src/relationship/relationshipObservables.ts +84 -84
  48. package/src/series/computedDataFn.ts +88 -88
  49. package/src/series/contextObserverCallback.ts +132 -132
  50. package/src/series/dataFormatterValidator.ts +46 -46
  51. package/src/series/dataValidator.ts +12 -12
  52. package/src/series/seriesObservables.ts +209 -209
  53. package/src/tree/computedDataFn.ts +129 -129
  54. package/src/tree/contextObserverCallback.ts +58 -58
  55. package/src/tree/dataFormatterValidator.ts +13 -13
  56. package/src/tree/dataValidator.ts +13 -13
  57. package/src/tree/treeObservables.ts +105 -105
  58. package/src/utils/commonUtils.ts +55 -55
  59. package/src/utils/d3Scale.ts +198 -198
  60. package/src/utils/errorMessage.ts +40 -40
  61. package/src/utils/index.ts +3 -3
  62. package/src/utils/observables.ts +308 -308
  63. package/src/utils/orbchartsUtils.ts +396 -396
  64. package/src/utils/validator.ts +126 -126
  65. package/tsconfig.base.json +13 -13
  66. package/tsconfig.json +2 -2
  67. package/vite-env.d.ts +6 -6
  68. package/vite.config.js +22 -22
@@ -1,55 +1,55 @@
1
-
2
- // 是否為原始物件
3
- export function isPlainObject(variable: any) {
4
- return Object.prototype.toString.call(variable) === "[object Object]";
5
- }
6
-
7
- // 是否為function
8
- export function isFunction(fn: any) {
9
- // return !!fn && !fn.nodename && fn.constructor != String && fn.constructor != RegExp && fn.constructor != Array && /function/i.test(fn + "");
10
- return Object.prototype.toString.call(fn) === '[object Function]'
11
- }
12
-
13
- // 是否為dom
14
- export function isDom(obj: any) {
15
- return !!(obj && obj.nodeType);
16
- }
17
-
18
- // 將可選的參數和預設值合併
19
- export function mergeOptionsWithDefault<Options extends { [key: string]: any; }> (options: {[key: string]: any}, defaultOptions: Options): Options {
20
- if (isPlainObject(options) === false || isPlainObject(defaultOptions) === false) {
21
- return Object.assign({}, defaultOptions)
22
- }
23
- const mergeObjColumns = (_options: {[key: string]: any}, _defaultOptions: {[key: string]: any}) => {
24
- const obj: Options = (Object.assign({}, _defaultOptions) as any)
25
- for (let key of Object.keys(_options)) {
26
- if ((key in _defaultOptions) == false) {
27
- continue
28
- }
29
- let objValue: any = undefined
30
- // 下一層的plain object
31
- if (isPlainObject(_options[key]) && isPlainObject(_defaultOptions[key])) {
32
- objValue = mergeObjColumns(_options[key], _defaultOptions[key])
33
- obj[key as keyof Options] = objValue
34
- }
35
- // 不是plain object直接賦值
36
- else {
37
- obj[key as keyof Options] = _options[key]
38
- }
39
- }
40
- return obj
41
- }
42
-
43
- return mergeObjColumns(options, defaultOptions)
44
- }
45
-
46
- // 加上千分位 ,
47
- export function formatCommaNumber (num = 0): string {
48
- try {
49
- let parts = num.toString().split('.');
50
- parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
51
- return parts.join('.');
52
- } catch (e: any) {
53
- console.error(e)
54
- }
55
- }
1
+
2
+ // 是否為原始物件
3
+ export function isPlainObject(variable: any) {
4
+ return Object.prototype.toString.call(variable) === "[object Object]";
5
+ }
6
+
7
+ // 是否為function
8
+ export function isFunction(fn: any) {
9
+ // return !!fn && !fn.nodename && fn.constructor != String && fn.constructor != RegExp && fn.constructor != Array && /function/i.test(fn + "");
10
+ return Object.prototype.toString.call(fn) === '[object Function]'
11
+ }
12
+
13
+ // 是否為dom
14
+ export function isDom(obj: any) {
15
+ return !!(obj && obj.nodeType);
16
+ }
17
+
18
+ // 將可選的參數和預設值合併
19
+ export function mergeOptionsWithDefault<Options extends { [key: string]: any; }> (options: {[key: string]: any}, defaultOptions: Options): Options {
20
+ if (isPlainObject(options) === false || isPlainObject(defaultOptions) === false) {
21
+ return Object.assign({}, defaultOptions)
22
+ }
23
+ const mergeObjColumns = (_options: {[key: string]: any}, _defaultOptions: {[key: string]: any}) => {
24
+ const obj: Options = (Object.assign({}, _defaultOptions) as any)
25
+ for (let key of Object.keys(_options)) {
26
+ if ((key in _defaultOptions) == false) {
27
+ continue
28
+ }
29
+ let objValue: any = undefined
30
+ // 下一層的plain object
31
+ if (isPlainObject(_options[key]) && isPlainObject(_defaultOptions[key])) {
32
+ objValue = mergeObjColumns(_options[key], _defaultOptions[key])
33
+ obj[key as keyof Options] = objValue
34
+ }
35
+ // 不是plain object直接賦值
36
+ else {
37
+ obj[key as keyof Options] = _options[key]
38
+ }
39
+ }
40
+ return obj
41
+ }
42
+
43
+ return mergeObjColumns(options, defaultOptions)
44
+ }
45
+
46
+ // 加上千分位 ,
47
+ export function formatCommaNumber (num = 0): string {
48
+ try {
49
+ let parts = num.toString().split('.');
50
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
51
+ return parts.join('.');
52
+ } catch (e: any) {
53
+ console.error(e)
54
+ }
55
+ }
@@ -1,198 +1,198 @@
1
- import * as d3 from 'd3'
2
- import { DEFAULT_DATA_FORMATTER_VALUE_AXIS } from '../defaults'
3
-
4
- // scaleLinear - 連續資料 -> 座標
5
- export const createValueToAxisScale = ({
6
- maxValue = 1,
7
- minValue = 0,
8
- axisWidth,
9
- scaleDomain = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain,
10
- scaleRange = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange,
11
- reverse = false
12
- }: {
13
- maxValue: number
14
- minValue: number
15
- axisWidth: number
16
- scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
17
- scaleRange: [number, number] // 0-1
18
- reverse?: boolean
19
- }) => {
20
- // if (minValue === maxValue) {
21
- // maxValue += 1 // 避免最大及最小值相同造成無法計算scale
22
- // minValue -= 1
23
- // }
24
-
25
- // -- 無值補上預設值 --
26
- const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[0]
27
- const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[1]
28
- const rangeMin: number = scaleRange[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[0]
29
- const rangeMax: number = scaleRange[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[1]
30
-
31
- // -- 'auto' | 'max' | 'min' 替換成實際值 --
32
- let domainMinValue: number = (() => {
33
- if (domainMin === 'auto') {
34
- return minValue < 0 ? minValue : 0
35
- } else if (domainMin === 'min') {
36
- return minValue
37
- } else {
38
- return domainMin
39
- }
40
- })()
41
-
42
- let domainMaxValue: number = (() => {
43
- if (domainMax === 'auto') {
44
- return maxValue >= 0 ? maxValue : 0
45
- } else if (domainMax === 'max') {
46
- return maxValue
47
- } else {
48
- return domainMax
49
- }
50
- })()
51
- // let rangeMinValue = axisWidth * rangeMin
52
- // let rangeMaxValue = axisWidth * rangeMax
53
-
54
- // -- 計算padding --
55
- // if (padding > 0) {
56
- // const stepAmount = maxValue - minValue + (padding * 2)
57
- // const eachStepWidth = axisWidth / stepAmount
58
- // const paddingWidth = eachStepWidth * padding
59
- // rangeMinValue += paddingWidth
60
- // rangeMaxValue -= paddingWidth
61
- // }
62
-
63
- // -- 依場景大小換算 --
64
- const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
65
- const axisDomainMaxValue = domainMaxValue / rangeMax
66
-
67
- // return d3.scaleLinear()
68
- // .domain([domainMinValue, domainMaxValue])
69
- // .range([rangeMinValue, rangeMaxValue])
70
- if (reverse) {
71
- return d3.scaleLinear()
72
- .domain([axisDomainMinValue, axisDomainMaxValue])
73
- .range([axisWidth, 0])
74
- } else {
75
- // console.log('domain', [axisDomainMinValue, axisDomainMaxValue])
76
- return d3.scaleLinear()
77
- .domain([axisDomainMinValue, axisDomainMaxValue])
78
- .range([0, axisWidth])
79
- }
80
- }
81
-
82
- // scaleLinear - 座標 -> 連續資料
83
- export const createAxisToValueScale = ({
84
- maxValue = 1,
85
- minValue = 0,
86
- axisWidth,
87
- scaleDomain = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain,
88
- scaleRange = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange,
89
- reverse = false
90
- }: {
91
- maxValue: number
92
- minValue: number
93
- axisWidth: number
94
- scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
95
- scaleRange: [number, number] // 0-1
96
- reverse?: boolean
97
- }) => {
98
- if (minValue === maxValue) {
99
- maxValue += 1 // 避免最大及最小值相同造成無法計算scale
100
- minValue -= 1
101
- }
102
-
103
- // -- 無值補上預設值 --
104
- const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[0]
105
- const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[1]
106
- const rangeMin: number = scaleRange[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[0]
107
- const rangeMax: number = scaleRange[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[1]
108
-
109
- // -- 'auto' | 'max' | 'min' 替換成實際值 --
110
- let domainMinValue: number = (() => {
111
- if (domainMin === 'auto') {
112
- return minValue < 0 ? minValue : 0
113
- } else if (domainMin === 'min') {
114
- return minValue
115
- } else {
116
- return domainMin
117
- }
118
- })()
119
-
120
- let domainMaxValue: number = (() => {
121
- if (domainMax === 'auto') {
122
- return maxValue >= 0 ? maxValue : 0
123
- } else if (domainMax === 'max') {
124
- return maxValue
125
- } else {
126
- return domainMax
127
- }
128
- })()
129
- // let rangeMinValue = axisWidth * rangeMin
130
- // let rangeMaxValue = axisWidth * rangeMax
131
-
132
- // -- 計算padding --
133
- // if (padding > 0) {
134
- // const stepAmount = maxValue - minValue + (padding * 2)
135
- // const eachStepWidth = axisWidth / stepAmount
136
- // const paddingWidth = eachStepWidth * padding
137
- // rangeMinValue += paddingWidth
138
- // rangeMaxValue -= paddingWidth
139
- // }
140
-
141
- // -- 依場景大小換算 --
142
- const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
143
- const axisDomainMaxValue = domainMaxValue / rangeMax
144
-
145
- // return d3.scaleLinear()
146
- // .domain([domainMinValue, domainMaxValue])
147
- // .range([rangeMinValue, rangeMaxValue])
148
- if (reverse) {
149
- return d3.scaleLinear()
150
- .domain([axisWidth, 0])
151
- .range([axisDomainMinValue, axisDomainMaxValue])
152
- } else {
153
- return d3.scaleLinear()
154
- .domain([0, axisWidth])
155
- .range([axisDomainMinValue, axisDomainMaxValue])
156
- }
157
- }
158
-
159
- // scalePoint - 非連續資料 -> 座標
160
- export const createLabelToAxisScale = ({ axisLabels, axisWidth, padding = 0.5 }: {
161
- axisLabels: string[]
162
- axisWidth: number
163
- padding?: number
164
- // reverse?: boolean
165
- }) => {
166
- let range: [d3.NumberValue, d3.NumberValue] = [0, axisWidth]
167
-
168
- return d3.scalePoint()
169
- .domain(axisLabels)
170
- .range(range)
171
- .padding(padding)
172
- }
173
-
174
- // scaleQuantize - 座標 -> 非連續資料索引
175
- export const createAxisToLabelIndexScale = ({ axisLabels, axisWidth, padding = 0, reverse = false }:{
176
- axisLabels: string[] | Date[],
177
- axisWidth: number
178
- padding?: number
179
- reverse?: boolean
180
- }) => {
181
-
182
- let range: number[] = axisLabels.map((d: string | Date, i: number) => i)
183
- if (reverse) {
184
- range.reverse()
185
- }
186
- if (!range.length) {
187
- // 至少要有一個值否則scale會出錯
188
- range = [0]
189
- }
190
-
191
- const step = range.length - 1 + (padding * 2) // 圖軸刻度分段數量
192
- const stepWidth = axisWidth / step
193
- const rangePadding = stepWidth * padding - (stepWidth * 0.5) // 實際要計算的範圍是圖軸左右那邊增加0.5
194
-
195
- return d3.scaleQuantize<number>()
196
- .domain([rangePadding, axisWidth - rangePadding])
197
- .range(range)
198
- }
1
+ import * as d3 from 'd3'
2
+ import { DEFAULT_DATA_FORMATTER_VALUE_AXIS } from '../defaults'
3
+
4
+ // scaleLinear - 連續資料 -> 座標
5
+ export const createValueToAxisScale = ({
6
+ maxValue = 1,
7
+ minValue = 0,
8
+ axisWidth,
9
+ scaleDomain = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain,
10
+ scaleRange = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange,
11
+ reverse = false
12
+ }: {
13
+ maxValue: number
14
+ minValue: number
15
+ axisWidth: number
16
+ scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
17
+ scaleRange: [number, number] // 0-1
18
+ reverse?: boolean
19
+ }) => {
20
+ // if (minValue === maxValue) {
21
+ // maxValue += 1 // 避免最大及最小值相同造成無法計算scale
22
+ // minValue -= 1
23
+ // }
24
+
25
+ // -- 無值補上預設值 --
26
+ const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[0]
27
+ const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[1]
28
+ const rangeMin: number = scaleRange[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[0]
29
+ const rangeMax: number = scaleRange[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[1]
30
+
31
+ // -- 'auto' | 'max' | 'min' 替換成實際值 --
32
+ let domainMinValue: number = (() => {
33
+ if (domainMin === 'auto') {
34
+ return minValue < 0 ? minValue : 0
35
+ } else if (domainMin === 'min') {
36
+ return minValue
37
+ } else {
38
+ return domainMin
39
+ }
40
+ })()
41
+
42
+ let domainMaxValue: number = (() => {
43
+ if (domainMax === 'auto') {
44
+ return maxValue >= 0 ? maxValue : 0
45
+ } else if (domainMax === 'max') {
46
+ return maxValue
47
+ } else {
48
+ return domainMax
49
+ }
50
+ })()
51
+ // let rangeMinValue = axisWidth * rangeMin
52
+ // let rangeMaxValue = axisWidth * rangeMax
53
+
54
+ // -- 計算padding --
55
+ // if (padding > 0) {
56
+ // const stepAmount = maxValue - minValue + (padding * 2)
57
+ // const eachStepWidth = axisWidth / stepAmount
58
+ // const paddingWidth = eachStepWidth * padding
59
+ // rangeMinValue += paddingWidth
60
+ // rangeMaxValue -= paddingWidth
61
+ // }
62
+
63
+ // -- 依場景大小換算 --
64
+ const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
65
+ const axisDomainMaxValue = domainMaxValue / rangeMax
66
+
67
+ // return d3.scaleLinear()
68
+ // .domain([domainMinValue, domainMaxValue])
69
+ // .range([rangeMinValue, rangeMaxValue])
70
+ if (reverse) {
71
+ return d3.scaleLinear()
72
+ .domain([axisDomainMinValue, axisDomainMaxValue])
73
+ .range([axisWidth, 0])
74
+ } else {
75
+ // console.log('domain', [axisDomainMinValue, axisDomainMaxValue])
76
+ return d3.scaleLinear()
77
+ .domain([axisDomainMinValue, axisDomainMaxValue])
78
+ .range([0, axisWidth])
79
+ }
80
+ }
81
+
82
+ // scaleLinear - 座標 -> 連續資料
83
+ export const createAxisToValueScale = ({
84
+ maxValue = 1,
85
+ minValue = 0,
86
+ axisWidth,
87
+ scaleDomain = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain,
88
+ scaleRange = DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange,
89
+ reverse = false
90
+ }: {
91
+ maxValue: number
92
+ minValue: number
93
+ axisWidth: number
94
+ scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
95
+ scaleRange: [number, number] // 0-1
96
+ reverse?: boolean
97
+ }) => {
98
+ if (minValue === maxValue) {
99
+ maxValue += 1 // 避免最大及最小值相同造成無法計算scale
100
+ minValue -= 1
101
+ }
102
+
103
+ // -- 無值補上預設值 --
104
+ const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[0]
105
+ const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleDomain[1]
106
+ const rangeMin: number = scaleRange[0] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[0]
107
+ const rangeMax: number = scaleRange[1] ?? DEFAULT_DATA_FORMATTER_VALUE_AXIS.scaleRange[1]
108
+
109
+ // -- 'auto' | 'max' | 'min' 替換成實際值 --
110
+ let domainMinValue: number = (() => {
111
+ if (domainMin === 'auto') {
112
+ return minValue < 0 ? minValue : 0
113
+ } else if (domainMin === 'min') {
114
+ return minValue
115
+ } else {
116
+ return domainMin
117
+ }
118
+ })()
119
+
120
+ let domainMaxValue: number = (() => {
121
+ if (domainMax === 'auto') {
122
+ return maxValue >= 0 ? maxValue : 0
123
+ } else if (domainMax === 'max') {
124
+ return maxValue
125
+ } else {
126
+ return domainMax
127
+ }
128
+ })()
129
+ // let rangeMinValue = axisWidth * rangeMin
130
+ // let rangeMaxValue = axisWidth * rangeMax
131
+
132
+ // -- 計算padding --
133
+ // if (padding > 0) {
134
+ // const stepAmount = maxValue - minValue + (padding * 2)
135
+ // const eachStepWidth = axisWidth / stepAmount
136
+ // const paddingWidth = eachStepWidth * padding
137
+ // rangeMinValue += paddingWidth
138
+ // rangeMaxValue -= paddingWidth
139
+ // }
140
+
141
+ // -- 依場景大小換算 --
142
+ const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
143
+ const axisDomainMaxValue = domainMaxValue / rangeMax
144
+
145
+ // return d3.scaleLinear()
146
+ // .domain([domainMinValue, domainMaxValue])
147
+ // .range([rangeMinValue, rangeMaxValue])
148
+ if (reverse) {
149
+ return d3.scaleLinear()
150
+ .domain([axisWidth, 0])
151
+ .range([axisDomainMinValue, axisDomainMaxValue])
152
+ } else {
153
+ return d3.scaleLinear()
154
+ .domain([0, axisWidth])
155
+ .range([axisDomainMinValue, axisDomainMaxValue])
156
+ }
157
+ }
158
+
159
+ // scalePoint - 非連續資料 -> 座標
160
+ export const createLabelToAxisScale = ({ axisLabels, axisWidth, padding = 0.5 }: {
161
+ axisLabels: string[]
162
+ axisWidth: number
163
+ padding?: number
164
+ // reverse?: boolean
165
+ }) => {
166
+ let range: [d3.NumberValue, d3.NumberValue] = [0, axisWidth]
167
+
168
+ return d3.scalePoint()
169
+ .domain(axisLabels)
170
+ .range(range)
171
+ .padding(padding)
172
+ }
173
+
174
+ // scaleQuantize - 座標 -> 非連續資料索引
175
+ export const createAxisToLabelIndexScale = ({ axisLabels, axisWidth, padding = 0, reverse = false }:{
176
+ axisLabels: string[] | Date[],
177
+ axisWidth: number
178
+ padding?: number
179
+ reverse?: boolean
180
+ }) => {
181
+
182
+ let range: number[] = axisLabels.map((d: string | Date, i: number) => i)
183
+ if (reverse) {
184
+ range.reverse()
185
+ }
186
+ if (!range.length) {
187
+ // 至少要有一個值否則scale會出錯
188
+ range = [0]
189
+ }
190
+
191
+ const step = range.length - 1 + (padding * 2) // 圖軸刻度分段數量
192
+ const stepWidth = axisWidth / step
193
+ const rangePadding = stepWidth * padding - (stepWidth * 0.5) // 實際要計算的範圍是圖軸左右那邊增加0.5
194
+
195
+ return d3.scaleQuantize<number>()
196
+ .domain([rangePadding, axisWidth - rangePadding])
197
+ .range(range)
198
+ }
@@ -1,41 +1,41 @@
1
- // message的prefix - error: 有中斷,warning: 無中斷
2
- export function createMessagePrefix (status: 'warning' | 'error'): string {
3
- return `[OrbCharts ${status}]:`
4
- }
5
-
6
- // throw到最外層的錯誤訊息
7
- export function createOrbChartsErrorMessage (e: Error): string {
8
- return `${createMessagePrefix('error')} ${e.message}`
9
- }
10
-
11
-
12
- // 未預期的錯誤
13
- export function createUnexpectedErrorMessage ({ from, systemMessage }: {
14
- from: string //
15
- systemMessage: string // catch 給的的原生錯誤訊息
16
- }): string {
17
- return `unexpected error from '${from}':
18
- ${systemMessage}`
19
- }
20
-
21
- // validator 的 error 訊息
22
- export function createValidatorErrorMessage ({ columnName, expectToBe, from }: {
23
- columnName: string // e.g. 'seriesLabels'
24
- expectToBe: string // e.g. 'string[]'
25
- from: string // e.g. Chart.chartParams$, Pie.params$
26
- }): string {
27
- return `Invalid value: '${columnName}' must be '${expectToBe}'
28
-
29
- ----> find in '${from}'`
30
- }
31
-
32
- // validator 的 warning 訊息
33
- export function createValidatorWarningMessage ({ columnName, expectToBe, from }: {
34
- columnName: string // e.g. 'seriesLabels'
35
- expectToBe: string // e.g. 'string[]'
36
- from: string // e.g. Chart.chartParams$, Pie.params$
37
- }): string {
38
- return `${createMessagePrefix('warning')} Value is not correct: '${columnName}' suppose to be '${expectToBe}', it may cause unexpected errors.'
39
-
40
- ----> find in '${from}'`
1
+ // message的prefix - error: 有中斷,warning: 無中斷
2
+ export function createMessagePrefix (status: 'warning' | 'error'): string {
3
+ return `[OrbCharts ${status}]:`
4
+ }
5
+
6
+ // throw到最外層的錯誤訊息
7
+ export function createOrbChartsErrorMessage (e: Error): string {
8
+ return `${createMessagePrefix('error')} ${e.message}`
9
+ }
10
+
11
+
12
+ // 未預期的錯誤
13
+ export function createUnexpectedErrorMessage ({ from, systemMessage }: {
14
+ from: string //
15
+ systemMessage: string // catch 給的的原生錯誤訊息
16
+ }): string {
17
+ return `unexpected error from '${from}':
18
+ ${systemMessage}`
19
+ }
20
+
21
+ // validator 的 error 訊息
22
+ export function createValidatorErrorMessage ({ columnName, expectToBe, from }: {
23
+ columnName: string // e.g. 'seriesLabels'
24
+ expectToBe: string // e.g. 'string[]'
25
+ from: string // e.g. Chart.chartParams$, Pie.params$
26
+ }): string {
27
+ return `Invalid value: '${columnName}' must be '${expectToBe}'
28
+
29
+ ----> find in '${from}'`
30
+ }
31
+
32
+ // validator 的 warning 訊息
33
+ export function createValidatorWarningMessage ({ columnName, expectToBe, from }: {
34
+ columnName: string // e.g. 'seriesLabels'
35
+ expectToBe: string // e.g. 'string[]'
36
+ from: string // e.g. Chart.chartParams$, Pie.params$
37
+ }): string {
38
+ return `${createMessagePrefix('warning')} Value is not correct: '${columnName}' suppose to be '${expectToBe}', it may cause unexpected errors.'
39
+
40
+ ----> find in '${from}'`
41
41
  }
@@ -1,4 +1,4 @@
1
- export * from './commonUtils'
2
- export * from './d3Scale'
3
- export * from './observables'
1
+ export * from './commonUtils'
2
+ export * from './d3Scale'
3
+ export * from './observables'
4
4
  export * from './orbchartsUtils'