@orbcharts/core 3.0.3 → 3.0.5

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 (70) hide show
  1. package/LICENSE +200 -200
  2. package/dist/orbcharts-core.es.js +1896 -1847
  3. package/dist/orbcharts-core.umd.js +5 -5
  4. package/dist/src/series/seriesObservables.d.ts +18 -7
  5. package/dist/src/utils/errorMessage.d.ts +1 -4
  6. package/lib/core-types.ts +7 -7
  7. package/package.json +46 -46
  8. package/src/AbstractChart.ts +57 -57
  9. package/src/GridChart.ts +24 -24
  10. package/src/MultiGridChart.ts +24 -24
  11. package/src/MultiValueChart.ts +24 -24
  12. package/src/RelationshipChart.ts +24 -24
  13. package/src/SeriesChart.ts +24 -24
  14. package/src/TreeChart.ts +24 -24
  15. package/src/base/createBaseChart.ts +524 -526
  16. package/src/base/createBasePlugin.ts +154 -154
  17. package/src/base/validators/chartOptionsValidator.ts +23 -23
  18. package/src/base/validators/chartParamsValidator.ts +133 -133
  19. package/src/base/validators/elementValidator.ts +13 -13
  20. package/src/base/validators/pluginsValidator.ts +14 -14
  21. package/src/defaults.ts +284 -283
  22. package/src/defineGridPlugin.ts +3 -3
  23. package/src/defineMultiGridPlugin.ts +3 -3
  24. package/src/defineMultiValuePlugin.ts +3 -3
  25. package/src/defineNoneDataPlugin.ts +4 -4
  26. package/src/defineRelationshipPlugin.ts +3 -3
  27. package/src/defineSeriesPlugin.ts +3 -3
  28. package/src/defineTreePlugin.ts +3 -3
  29. package/src/grid/computedDataFn.ts +129 -129
  30. package/src/grid/contextObserverCallback.ts +201 -201
  31. package/src/grid/dataFormatterValidator.ts +125 -125
  32. package/src/grid/dataValidator.ts +12 -12
  33. package/src/grid/gridObservables.ts +694 -718
  34. package/src/index.ts +20 -20
  35. package/src/multiGrid/computedDataFn.ts +123 -123
  36. package/src/multiGrid/contextObserverCallback.ts +75 -75
  37. package/src/multiGrid/dataFormatterValidator.ts +120 -120
  38. package/src/multiGrid/dataValidator.ts +12 -12
  39. package/src/multiGrid/multiGridObservables.ts +357 -401
  40. package/src/multiValue/computedDataFn.ts +113 -113
  41. package/src/multiValue/contextObserverCallback.ts +328 -328
  42. package/src/multiValue/dataFormatterValidator.ts +94 -94
  43. package/src/multiValue/dataValidator.ts +12 -12
  44. package/src/multiValue/multiValueObservables.ts +865 -1219
  45. package/src/relationship/computedDataFn.ts +159 -159
  46. package/src/relationship/contextObserverCallback.ts +80 -80
  47. package/src/relationship/dataFormatterValidator.ts +13 -13
  48. package/src/relationship/dataValidator.ts +13 -13
  49. package/src/relationship/relationshipObservables.ts +84 -84
  50. package/src/series/computedDataFn.ts +88 -88
  51. package/src/series/contextObserverCallback.ts +132 -107
  52. package/src/series/dataFormatterValidator.ts +46 -46
  53. package/src/series/dataValidator.ts +12 -12
  54. package/src/series/seriesObservables.ts +209 -175
  55. package/src/tree/computedDataFn.ts +129 -129
  56. package/src/tree/contextObserverCallback.ts +58 -58
  57. package/src/tree/dataFormatterValidator.ts +13 -13
  58. package/src/tree/dataValidator.ts +13 -13
  59. package/src/tree/treeObservables.ts +105 -105
  60. package/src/utils/commonUtils.ts +55 -55
  61. package/src/utils/d3Scale.ts +198 -198
  62. package/src/utils/errorMessage.ts +40 -43
  63. package/src/utils/index.ts +3 -3
  64. package/src/utils/observables.ts +308 -293
  65. package/src/utils/orbchartsUtils.ts +396 -396
  66. package/src/utils/validator.ts +126 -126
  67. package/tsconfig.base.json +13 -13
  68. package/tsconfig.json +2 -2
  69. package/vite-env.d.ts +6 -6
  70. 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,44 +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: {
8
- message: string // e.message
9
- stack: string // e.stack
10
- }): string {
11
- return `${createMessagePrefix('error')} ${e.message}`
12
- }
13
-
14
-
15
- // 未預期的錯誤
16
- export function createUnexpectedErrorMessage ({ from, systemMessage }: {
17
- from: string //
18
- systemMessage: string // catch 給的的原生錯誤訊息
19
- }): string {
20
- return `unexpected error from '${from}':
21
- ${systemMessage}`
22
- }
23
-
24
- // validator error 訊息
25
- export function createValidatorErrorMessage ({ columnName, expectToBe, from }: {
26
- columnName: string // e.g. 'seriesLabels'
27
- expectToBe: string // e.g. 'string[]'
28
- from: string // e.g. Chart.chartParams$, Pie.params$
29
- }): string {
30
- return `Invalid value: '${columnName}' must be '${expectToBe}'
31
-
32
- ----> find in '${from}'`
33
- }
34
-
35
- // validator warning 訊息
36
- export function createValidatorWarningMessage ({ columnName, expectToBe, from }: {
37
- columnName: string // e.g. 'seriesLabels'
38
- expectToBe: string // e.g. 'string[]'
39
- from: string // e.g. Chart.chartParams$, Pie.params$
40
- }): string {
41
- return `${createMessagePrefix('warning')} Value is not correct: '${columnName}' suppose to be '${expectToBe}', it may cause unexpected errors.'
42
-
43
- ----> 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}'`
44
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'