@orbcharts/core 3.0.0-beta.3 → 3.0.0-beta.4
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.
- package/LICENSE +200 -200
- package/dist/orbcharts-core.es.js +2623 -2338
- package/dist/orbcharts-core.umd.js +4 -4
- package/dist/src/utils/d3Scale.d.ts +28 -0
- package/dist/src/utils/gridObservables.d.ts +29 -19
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/multiGridObservables.d.ts +2 -2
- package/dist/src/utils/multiValueObservables.d.ts +73 -0
- package/dist/src/utils/orbchartsUtils.d.ts +19 -5
- package/dist/src/utils/seriesObservables.d.ts +4 -4
- package/dist/src/utils/treeObservables.d.ts +2 -5
- package/lib/core-types.ts +7 -7
- package/package.json +42 -42
- package/src/AbstractChart.ts +57 -57
- package/src/GridChart.ts +24 -24
- package/src/MultiGridChart.ts +24 -24
- package/src/MultiValueChart.ts +24 -24
- package/src/RelationshipChart.ts +24 -24
- package/src/SeriesChart.ts +24 -24
- package/src/TreeChart.ts +24 -24
- package/src/base/createBaseChart.ts +505 -505
- package/src/base/createBasePlugin.ts +153 -153
- package/src/base/validators/chartOptionsValidator.ts +23 -23
- package/src/base/validators/chartParamsValidator.ts +133 -133
- package/src/base/validators/elementValidator.ts +13 -13
- package/src/base/validators/pluginsValidator.ts +14 -14
- package/src/defaults.ts +235 -232
- package/src/defineGridPlugin.ts +3 -3
- package/src/defineMultiGridPlugin.ts +3 -3
- package/src/defineMultiValuePlugin.ts +3 -3
- package/src/defineNoneDataPlugin.ts +4 -4
- package/src/defineRelationshipPlugin.ts +3 -3
- package/src/defineSeriesPlugin.ts +3 -3
- package/src/defineTreePlugin.ts +3 -3
- package/src/grid/computedDataFn.ts +129 -129
- package/src/grid/contextObserverCallback.ts +176 -155
- package/src/grid/dataFormatterValidator.ts +101 -101
- package/src/grid/dataValidator.ts +12 -12
- package/src/index.ts +20 -20
- package/src/multiGrid/computedDataFn.ts +123 -123
- package/src/multiGrid/contextObserverCallback.ts +41 -41
- package/src/multiGrid/dataFormatterValidator.ts +115 -115
- package/src/multiGrid/dataValidator.ts +12 -12
- package/src/multiValue/computedDataFn.ts +110 -176
- package/src/multiValue/contextObserverCallback.ts +160 -12
- package/src/multiValue/dataFormatterValidator.ts +9 -9
- package/src/multiValue/dataValidator.ts +9 -9
- package/src/relationship/computedDataFn.ts +125 -125
- package/src/relationship/contextObserverCallback.ts +12 -12
- package/src/relationship/dataFormatterValidator.ts +9 -9
- package/src/relationship/dataValidator.ts +9 -9
- package/src/series/computedDataFn.ts +88 -88
- package/src/series/contextObserverCallback.ts +100 -100
- package/src/series/dataFormatterValidator.ts +41 -41
- package/src/series/dataValidator.ts +12 -12
- package/src/tree/computedDataFn.ts +129 -130
- package/src/tree/contextObserverCallback.ts +58 -61
- package/src/tree/dataFormatterValidator.ts +13 -13
- package/src/tree/dataValidator.ts +13 -13
- package/src/utils/commonUtils.ts +55 -55
- package/src/utils/d3Scale.ts +198 -0
- package/src/utils/errorMessage.ts +42 -42
- package/src/utils/gridObservables.ts +671 -614
- package/src/utils/index.ts +9 -9
- package/src/utils/multiGridObservables.ts +392 -366
- package/src/utils/multiValueObservables.ts +643 -0
- package/src/utils/observables.ts +219 -219
- package/src/utils/orbchartsUtils.ts +377 -352
- package/src/utils/seriesObservables.ts +175 -175
- package/src/utils/treeObservables.ts +105 -94
- package/src/utils/validator.ts +126 -125
- package/tsconfig.base.json +13 -13
- package/tsconfig.json +2 -2
- package/vite-env.d.ts +6 -6
- package/vite.config.js +22 -22
- package/dist/src/utils/d3Utils.d.ts +0 -19
- package/src/utils/d3Utils.ts +0 -108
package/src/utils/validator.ts
CHANGED
@@ -1,126 +1,127 @@
|
|
1
|
-
import type {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
import {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
//
|
17
|
-
//
|
18
|
-
//
|
19
|
-
//
|
20
|
-
//
|
21
|
-
//
|
22
|
-
//
|
23
|
-
//
|
24
|
-
//
|
25
|
-
//
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
'
|
36
|
-
'
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|| value === '
|
47
|
-
|| value === '
|
48
|
-
|| value === '
|
49
|
-
|| value === '
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
const
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
const
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
const
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
const
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
//
|
92
|
-
//
|
93
|
-
//
|
94
|
-
//
|
95
|
-
//
|
96
|
-
//
|
97
|
-
//
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
const
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
//
|
113
|
-
//
|
114
|
-
//
|
115
|
-
//
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
1
|
+
import type {
|
2
|
+
ColorType,
|
3
|
+
ValidatorResult,
|
4
|
+
ToBeTypes,
|
5
|
+
ToBeOption,
|
6
|
+
ValidatorRuleToBeTypes,
|
7
|
+
ValidatorRuleToBe,
|
8
|
+
ValidatorRuleToBeOption,
|
9
|
+
ValidatorRule
|
10
|
+
} from '../../lib/core-types'
|
11
|
+
import { isFunction, isPlainObject } from './commonUtils'
|
12
|
+
import { createValidatorErrorMessage } from './errorMessage'
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
// let test: ValidatorRule = {
|
17
|
+
// name: {
|
18
|
+
// toBeTypes: ['string']
|
19
|
+
// },
|
20
|
+
// labels: {
|
21
|
+
// toBe: 'string | "auto"',
|
22
|
+
// test: (value: any) => {
|
23
|
+
// return value === 'auto' || typeof value === 'string'
|
24
|
+
// }
|
25
|
+
// }
|
26
|
+
// }
|
27
|
+
|
28
|
+
function getInvalidColumn<T> (data: T, rules: Partial<ValidatorRule<T>>) {
|
29
|
+
// "toBeTypes" 的測試
|
30
|
+
const testType: {[key in ToBeTypes]: (value: any) => boolean} = {
|
31
|
+
string: (value: any) => typeof value === 'string',
|
32
|
+
number: (value: any) => typeof value === 'number',
|
33
|
+
boolean: (value: any) => typeof value === 'boolean',
|
34
|
+
object: (value: any) => isPlainObject(value), // 嚴格判斷是否為純物件
|
35
|
+
'object[]': (value: any) => Array.isArray(value) && value.every((v: any) => isPlainObject(v)),
|
36
|
+
'string[]': (value: any) => Array.isArray(value) && value.every((v: any) => typeof v === 'string'),
|
37
|
+
'number[]': (value: any) => Array.isArray(value) && value.every((v: any) => typeof v === 'number'),
|
38
|
+
Function: (value: any) => isFunction(value),
|
39
|
+
null: (value: any) => value === null,
|
40
|
+
undefined: (value: any) => value === undefined
|
41
|
+
}
|
42
|
+
// "toBeOption" 的測試
|
43
|
+
const testOption: {[key in ToBeOption]: (value: any) => boolean} = {
|
44
|
+
ColorType: (value: ColorType) => {
|
45
|
+
return value === 'none'
|
46
|
+
|| value === 'series'
|
47
|
+
|| value === 'primary'
|
48
|
+
|| value === 'secondary'
|
49
|
+
|| value === 'white'
|
50
|
+
|| value === 'background'
|
51
|
+
},
|
52
|
+
}
|
53
|
+
|
54
|
+
const failColumn = Object.keys(data).find((columnName: string) => {
|
55
|
+
// 有定義規則
|
56
|
+
if (rules[columnName as keyof T]) {
|
57
|
+
const rule: ValidatorRuleToBeTypes | ValidatorRuleToBe | ValidatorRuleToBeOption = rules[columnName as keyof T]
|
58
|
+
const value = data[columnName as keyof T]
|
59
|
+
// 測試 "toBeTypes"
|
60
|
+
if ((rule as ValidatorRuleToBeTypes).toBeTypes) {
|
61
|
+
const toBeTypes = (rule as ValidatorRuleToBeTypes).toBeTypes
|
62
|
+
const isCorrect = toBeTypes.some((toBeType) => testType[toBeType](value))
|
63
|
+
if (isCorrect === false) {
|
64
|
+
return true
|
65
|
+
}
|
66
|
+
}
|
67
|
+
// 測試 "toBe"
|
68
|
+
else if ((rule as ValidatorRuleToBe).toBe) {
|
69
|
+
const { toBe, test } = rule as ValidatorRuleToBe
|
70
|
+
const isCorrect = test(value)
|
71
|
+
if (isCorrect === false) {
|
72
|
+
return true
|
73
|
+
}
|
74
|
+
}
|
75
|
+
// 測試 "toBeOption"
|
76
|
+
else if ((rule as ValidatorRuleToBeOption).toBeOption) {
|
77
|
+
const toBeOption = (rule as ValidatorRuleToBeOption).toBeOption
|
78
|
+
const isCorrect = testOption[toBeOption](value)
|
79
|
+
if (isCorrect === false) {
|
80
|
+
return true
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
return false
|
85
|
+
})
|
86
|
+
|
87
|
+
return failColumn
|
88
|
+
}
|
89
|
+
|
90
|
+
export function validateColumns<T> (data: T, rules: Partial<ValidatorRule<T>>): ValidatorResult {
|
91
|
+
// if (data === undefined || data === null) {
|
92
|
+
// // orbcharts所有的options都是允許空值的
|
93
|
+
// return {
|
94
|
+
// status: 'success',
|
95
|
+
// columnName: '',
|
96
|
+
// expectToBe: '',
|
97
|
+
// }
|
98
|
+
// }
|
99
|
+
const invalidColumn = getInvalidColumn(data, rules)
|
100
|
+
if (invalidColumn) {
|
101
|
+
const rule = rules[invalidColumn as keyof T]
|
102
|
+
const expectToBe = (rule as ValidatorRuleToBeTypes).toBeTypes
|
103
|
+
? (rule as ValidatorRuleToBeTypes).toBeTypes.join(' | ')
|
104
|
+
: (rule as ValidatorRuleToBe).toBe
|
105
|
+
? (rule as ValidatorRuleToBe).toBe
|
106
|
+
: (rule as ValidatorRuleToBeOption).toBeOption
|
107
|
+
? (rule as ValidatorRuleToBeOption).toBeOption
|
108
|
+
: ''
|
109
|
+
|
110
|
+
return {
|
111
|
+
status: 'error',
|
112
|
+
// message: createValidatorErrorMessage({
|
113
|
+
// columnName: failColumn,
|
114
|
+
// expect,
|
115
|
+
// from
|
116
|
+
// })
|
117
|
+
columnName: invalidColumn as string,
|
118
|
+
expectToBe: expectToBe,
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
return {
|
122
|
+
status: 'success',
|
123
|
+
columnName: '',
|
124
|
+
expectToBe: '',
|
125
|
+
}
|
126
|
+
}
|
126
127
|
}
|
package/tsconfig.base.json
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
{
|
2
|
-
"compilerOptions": {
|
3
|
-
"outDir": "./dist/",
|
4
|
-
"sourceMap": true,
|
5
|
-
"noImplicitAny": true,
|
6
|
-
"module": "esnext",
|
7
|
-
"target": "es5",
|
8
|
-
"jsx": "react",
|
9
|
-
"allowJs": true,
|
10
|
-
"moduleResolution": "node",
|
11
|
-
"allowSyntheticDefaultImports" : true,
|
12
|
-
"esModuleInterop" : true
|
13
|
-
}
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"outDir": "./dist/",
|
4
|
+
"sourceMap": true,
|
5
|
+
"noImplicitAny": true,
|
6
|
+
"module": "esnext",
|
7
|
+
"target": "es5",
|
8
|
+
"jsx": "react",
|
9
|
+
"allowJs": true,
|
10
|
+
"moduleResolution": "node",
|
11
|
+
"allowSyntheticDefaultImports" : true,
|
12
|
+
"esModuleInterop" : true
|
13
|
+
}
|
14
14
|
}
|
package/tsconfig.json
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
{
|
2
|
-
"extends": "./tsconfig.base.json"
|
1
|
+
{
|
2
|
+
"extends": "./tsconfig.base.json"
|
3
3
|
}
|
package/vite-env.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
interface ImportMetaEnv {
|
2
|
-
readonly MODE: 'development' | 'production'
|
3
|
-
}
|
4
|
-
|
5
|
-
interface ImportMeta {
|
6
|
-
readonly env: ImportMetaEnv;
|
1
|
+
interface ImportMetaEnv {
|
2
|
+
readonly MODE: 'development' | 'production'
|
3
|
+
}
|
4
|
+
|
5
|
+
interface ImportMeta {
|
6
|
+
readonly env: ImportMetaEnv;
|
7
7
|
}
|
package/vite.config.js
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
import { defineConfig } from 'vite'
|
2
|
-
import dts from 'vite-plugin-dts'
|
3
|
-
|
4
|
-
export default defineConfig(({ command, mode }) => {
|
5
|
-
return {
|
6
|
-
plugins: [
|
7
|
-
dts({
|
8
|
-
insertTypesEntry: true
|
9
|
-
})
|
10
|
-
],
|
11
|
-
compilerOptions: {
|
12
|
-
composite: true
|
13
|
-
},
|
14
|
-
build: {
|
15
|
-
lib: {
|
16
|
-
entry: "src/index.ts",
|
17
|
-
name: 'orbcharts-core',
|
18
|
-
formats: ["es", "umd"],
|
19
|
-
fileName: format => `orbcharts-core.${format}.js`
|
20
|
-
},
|
21
|
-
}
|
22
|
-
}
|
1
|
+
import { defineConfig } from 'vite'
|
2
|
+
import dts from 'vite-plugin-dts'
|
3
|
+
|
4
|
+
export default defineConfig(({ command, mode }) => {
|
5
|
+
return {
|
6
|
+
plugins: [
|
7
|
+
dts({
|
8
|
+
insertTypesEntry: true
|
9
|
+
})
|
10
|
+
],
|
11
|
+
compilerOptions: {
|
12
|
+
composite: true
|
13
|
+
},
|
14
|
+
build: {
|
15
|
+
lib: {
|
16
|
+
entry: "src/index.ts",
|
17
|
+
name: 'orbcharts-core',
|
18
|
+
formats: ["es", "umd"],
|
19
|
+
fileName: format => `orbcharts-core.${format}.js`
|
20
|
+
},
|
21
|
+
}
|
22
|
+
}
|
23
23
|
})
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import * as d3 from 'd3';
|
2
|
-
export declare const createAxisLinearScale: ({ maxValue, minValue, axisWidth, scaleDomain, scaleRange, }: {
|
3
|
-
maxValue: number;
|
4
|
-
minValue: number;
|
5
|
-
axisWidth: number;
|
6
|
-
scaleDomain: [number | "min" | "auto", number | "max" | "auto"];
|
7
|
-
scaleRange: [number, number];
|
8
|
-
}) => d3.ScaleLinear<number, number, never>;
|
9
|
-
export declare const createAxisPointScale: ({ axisLabels, axisWidth, padding }: {
|
10
|
-
axisLabels: string[];
|
11
|
-
axisWidth: number;
|
12
|
-
padding?: number;
|
13
|
-
}) => d3.ScalePoint<string>;
|
14
|
-
export declare const createAxisQuantizeScale: ({ axisLabels, axisWidth, padding, reverse }: {
|
15
|
-
axisLabels: string[] | Date[];
|
16
|
-
axisWidth: number;
|
17
|
-
padding?: number;
|
18
|
-
reverse?: boolean;
|
19
|
-
}) => d3.ScaleQuantize<number, never>;
|
package/src/utils/d3Utils.ts
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
import * as d3 from 'd3'
|
2
|
-
import { DATA_FORMATTER_VALUE_AXIS_DEFAULT } from '../defaults'
|
3
|
-
|
4
|
-
// scaleLinear - 連續資料對應到比例尺座標上
|
5
|
-
export const createAxisLinearScale = ({
|
6
|
-
maxValue = 1,
|
7
|
-
minValue = 0,
|
8
|
-
axisWidth,
|
9
|
-
scaleDomain = DATA_FORMATTER_VALUE_AXIS_DEFAULT.scaleDomain,
|
10
|
-
scaleRange = DATA_FORMATTER_VALUE_AXIS_DEFAULT.scaleRange,
|
11
|
-
}: {
|
12
|
-
maxValue: number
|
13
|
-
minValue: number
|
14
|
-
axisWidth: number
|
15
|
-
scaleDomain: [number | 'min' | 'auto', number | 'max' | 'auto']
|
16
|
-
scaleRange: [number, number] // 0-1
|
17
|
-
}) => {
|
18
|
-
// -- 無值補上預設值 --
|
19
|
-
const domainMin: number | 'min' | 'auto' = scaleDomain[0] ?? DATA_FORMATTER_VALUE_AXIS_DEFAULT.scaleDomain[0]
|
20
|
-
const domainMax: number | 'max' | 'auto' = scaleDomain[1] ?? DATA_FORMATTER_VALUE_AXIS_DEFAULT.scaleDomain[1]
|
21
|
-
const rangeMin: number = scaleRange[0] ?? DATA_FORMATTER_VALUE_AXIS_DEFAULT.scaleRange[0]
|
22
|
-
const rangeMax: number = scaleRange[1] ?? DATA_FORMATTER_VALUE_AXIS_DEFAULT.scaleRange[1]
|
23
|
-
|
24
|
-
// -- 'auto' | 'max' | 'min' 替換成實際值 --
|
25
|
-
let domainMinValue: number = (() => {
|
26
|
-
if (domainMin === 'auto') {
|
27
|
-
return minValue < 0 ? minValue : 0
|
28
|
-
} else if (domainMin === 'min') {
|
29
|
-
return minValue
|
30
|
-
} else {
|
31
|
-
return domainMin
|
32
|
-
}
|
33
|
-
})()
|
34
|
-
|
35
|
-
let domainMaxValue: number = (() => {
|
36
|
-
if (domainMax === 'auto') {
|
37
|
-
return maxValue >= 0 ? maxValue : 0
|
38
|
-
} else if (domainMax === 'max') {
|
39
|
-
return maxValue
|
40
|
-
} else {
|
41
|
-
return domainMax
|
42
|
-
}
|
43
|
-
})()
|
44
|
-
// let rangeMinValue = axisWidth * rangeMin
|
45
|
-
// let rangeMaxValue = axisWidth * rangeMax
|
46
|
-
|
47
|
-
// -- 計算padding --
|
48
|
-
// if (padding > 0) {
|
49
|
-
// const stepAmount = maxValue - minValue + (padding * 2)
|
50
|
-
// const eachStepWidth = axisWidth / stepAmount
|
51
|
-
// const paddingWidth = eachStepWidth * padding
|
52
|
-
// rangeMinValue += paddingWidth
|
53
|
-
// rangeMaxValue -= paddingWidth
|
54
|
-
// }
|
55
|
-
|
56
|
-
// -- 依場景大小換算 --
|
57
|
-
const axisDomainMinValue = maxValue - (maxValue - domainMinValue) / (1 - rangeMin)
|
58
|
-
const axisDomainMaxValue = domainMaxValue / rangeMax
|
59
|
-
|
60
|
-
// return d3.scaleLinear()
|
61
|
-
// .domain([domainMinValue, domainMaxValue])
|
62
|
-
// .range([rangeMinValue, rangeMaxValue])
|
63
|
-
return d3.scaleLinear()
|
64
|
-
.domain([axisDomainMinValue, axisDomainMaxValue])
|
65
|
-
.range([0, axisWidth])
|
66
|
-
}
|
67
|
-
|
68
|
-
// scalePoint - 非連續資料對應到比例尺座標上
|
69
|
-
export const createAxisPointScale = ({ axisLabels, axisWidth, padding = 0.5 }: {
|
70
|
-
axisLabels: string[]
|
71
|
-
axisWidth: number
|
72
|
-
padding?: number
|
73
|
-
// reverse?: boolean
|
74
|
-
}) => {
|
75
|
-
let range: [d3.NumberValue, d3.NumberValue] = [0, axisWidth]
|
76
|
-
|
77
|
-
return d3.scalePoint()
|
78
|
-
.domain(axisLabels)
|
79
|
-
.range(range)
|
80
|
-
.padding(padding)
|
81
|
-
}
|
82
|
-
|
83
|
-
// scaleQuantize - 比例尺座標對應非連續資料索引
|
84
|
-
export const createAxisQuantizeScale = ({ axisLabels, axisWidth, padding = 0, reverse = false }:{
|
85
|
-
axisLabels: string[] | Date[],
|
86
|
-
axisWidth: number
|
87
|
-
padding?: number
|
88
|
-
reverse?: boolean
|
89
|
-
}) => {
|
90
|
-
|
91
|
-
let range: number[] = axisLabels.map((d: string | Date, i: number) => i)
|
92
|
-
if (reverse) {
|
93
|
-
range.reverse()
|
94
|
-
}
|
95
|
-
// if (reverse) {
|
96
|
-
// range = axisLabels.map((d: string | Date, i: number) => axisLabels.length - 1 - i)
|
97
|
-
// } else {
|
98
|
-
// range = axisLabels.map((d: string | Date, i: number) => i)
|
99
|
-
// }
|
100
|
-
const step = range.length - 1 + (padding * 2) // 圖軸刻度分段數量
|
101
|
-
const stepWidth = axisWidth / step
|
102
|
-
const rangePadding = stepWidth * padding - (stepWidth * 0.5) // 實際要計算的範圍是圖軸左右那邊增加0.5
|
103
|
-
|
104
|
-
// console.log('rangePadding', rangePadding)
|
105
|
-
return d3.scaleQuantize<number>()
|
106
|
-
.domain([rangePadding, axisWidth - rangePadding])
|
107
|
-
.range(range)
|
108
|
-
}
|