@semcore/d3-chart 1.7.0 → 1.9.0
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/CHANGELOG.md +18 -0
- package/lib/cjs/Axis.js +33 -21
- package/lib/cjs/Axis.js.map +1 -1
- package/lib/cjs/Bar.js +3 -3
- package/lib/cjs/Bar.js.map +1 -1
- package/lib/cjs/Bubble.js +3 -24
- package/lib/cjs/Bubble.js.map +1 -1
- package/lib/cjs/ClipPath.js +2 -1
- package/lib/cjs/ClipPath.js.map +1 -1
- package/lib/cjs/Donut.js +1 -1
- package/lib/cjs/Donut.js.map +1 -1
- package/lib/cjs/Dots.js +1 -1
- package/lib/cjs/Dots.js.map +1 -1
- package/lib/cjs/GroupBar.js +8 -8
- package/lib/cjs/GroupBar.js.map +1 -1
- package/lib/cjs/HorizontalBar.js +3 -3
- package/lib/cjs/HorizontalBar.js.map +1 -1
- package/lib/cjs/Plot.js +16 -2
- package/lib/cjs/Plot.js.map +1 -1
- package/lib/cjs/RadialTree.js +691 -0
- package/lib/cjs/RadialTree.js.map +1 -0
- package/lib/cjs/ResponsiveContainer.js +2 -2
- package/lib/cjs/ResponsiveContainer.js.map +1 -1
- package/lib/cjs/StackBar.js +8 -8
- package/lib/cjs/StackBar.js.map +1 -1
- package/lib/cjs/StackedArea.js +8 -8
- package/lib/cjs/StackedArea.js.map +1 -1
- package/lib/cjs/Tooltip.js +6 -10
- package/lib/cjs/Tooltip.js.map +1 -1
- package/lib/cjs/Venn.js +2 -2
- package/lib/cjs/Venn.js.map +1 -1
- package/lib/cjs/createElement.js +3 -2
- package/lib/cjs/createElement.js.map +1 -1
- package/lib/cjs/index.js +8 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/style/axis.shadow.css +2 -4
- package/lib/cjs/style/plot.shadow.css +6 -0
- package/lib/cjs/style/radial-tree.shadow.css +23 -0
- package/lib/cjs/types/Area.d.ts +47 -0
- package/lib/cjs/types/Axis.d.ts +64 -0
- package/lib/cjs/types/Bar.d.ts +48 -0
- package/lib/cjs/types/Bubble.d.ts +27 -0
- package/lib/cjs/types/ClipPath.d.ts +26 -0
- package/lib/cjs/types/Donut.d.ts +42 -0
- package/lib/cjs/types/GroupBar.d.ts +20 -0
- package/lib/cjs/types/HorizontalBar.d.ts +29 -0
- package/lib/cjs/types/Hover.d.ts +15 -0
- package/lib/cjs/types/Line.d.ts +50 -0
- package/lib/cjs/types/Plot.d.ts +16 -0
- package/lib/cjs/types/ResponsiveContainer.d.ts +20 -0
- package/lib/cjs/types/ScatterPlot.d.ts +27 -0
- package/lib/cjs/types/StackBar.d.ts +26 -0
- package/lib/cjs/types/StackedArea.d.ts +26 -0
- package/lib/cjs/types/Tooltip.d.ts +31 -0
- package/lib/cjs/types/Venn.d.ts +45 -0
- package/lib/cjs/types/context.d.ts +6 -0
- package/lib/cjs/types/index.d.ts +53 -0
- package/lib/cjs/utils.js +120 -55
- package/lib/cjs/utils.js.map +1 -1
- package/lib/es6/Axis.js +33 -21
- package/lib/es6/Axis.js.map +1 -1
- package/lib/es6/Bar.js +3 -3
- package/lib/es6/Bar.js.map +1 -1
- package/lib/es6/Bubble.js +3 -24
- package/lib/es6/Bubble.js.map +1 -1
- package/lib/es6/ClipPath.js +2 -1
- package/lib/es6/ClipPath.js.map +1 -1
- package/lib/es6/Donut.js +1 -1
- package/lib/es6/Donut.js.map +1 -1
- package/lib/es6/Dots.js +1 -1
- package/lib/es6/Dots.js.map +1 -1
- package/lib/es6/GroupBar.js +8 -8
- package/lib/es6/GroupBar.js.map +1 -1
- package/lib/es6/HorizontalBar.js +3 -3
- package/lib/es6/HorizontalBar.js.map +1 -1
- package/lib/es6/Plot.js +18 -2
- package/lib/es6/Plot.js.map +1 -1
- package/lib/es6/RadialTree.js +679 -0
- package/lib/es6/RadialTree.js.map +1 -0
- package/lib/es6/ResponsiveContainer.js +2 -2
- package/lib/es6/ResponsiveContainer.js.map +1 -1
- package/lib/es6/StackBar.js +8 -8
- package/lib/es6/StackBar.js.map +1 -1
- package/lib/es6/StackedArea.js +8 -8
- package/lib/es6/StackedArea.js.map +1 -1
- package/lib/es6/Tooltip.js +6 -10
- package/lib/es6/Tooltip.js.map +1 -1
- package/lib/es6/Venn.js +2 -2
- package/lib/es6/Venn.js.map +1 -1
- package/lib/es6/createElement.js +3 -2
- package/lib/es6/createElement.js.map +1 -1
- package/lib/es6/index.js +1 -0
- package/lib/es6/index.js.map +1 -1
- package/lib/es6/style/axis.shadow.css +2 -4
- package/lib/es6/style/plot.shadow.css +6 -0
- package/lib/es6/style/radial-tree.shadow.css +23 -0
- package/lib/es6/types/Area.d.ts +47 -0
- package/lib/es6/types/Axis.d.ts +64 -0
- package/lib/es6/types/Bar.d.ts +48 -0
- package/lib/es6/types/Bubble.d.ts +27 -0
- package/lib/es6/types/ClipPath.d.ts +26 -0
- package/lib/es6/types/Donut.d.ts +42 -0
- package/lib/es6/types/GroupBar.d.ts +20 -0
- package/lib/es6/types/HorizontalBar.d.ts +29 -0
- package/lib/es6/types/Hover.d.ts +15 -0
- package/lib/es6/types/Line.d.ts +50 -0
- package/lib/es6/types/Plot.d.ts +16 -0
- package/lib/es6/types/ResponsiveContainer.d.ts +20 -0
- package/lib/es6/types/ScatterPlot.d.ts +27 -0
- package/lib/es6/types/StackBar.d.ts +26 -0
- package/lib/es6/types/StackedArea.d.ts +26 -0
- package/lib/es6/types/Tooltip.d.ts +31 -0
- package/lib/es6/types/Venn.d.ts +45 -0
- package/lib/es6/types/context.d.ts +6 -0
- package/lib/es6/types/index.d.ts +53 -0
- package/lib/es6/utils.js +95 -44
- package/lib/es6/utils.js.map +1 -1
- package/lib/types/RadialTree.d.ts +202 -0
- package/lib/types/index.d.ts +6 -0
- package/lib/types/utils.d.ts +27 -0
- package/package.json +17 -10
- package/src/Axis.jsx +11 -1
- package/src/Bubble.jsx +1 -21
- package/src/ClipPath.jsx +1 -0
- package/src/Donut.jsx +7 -9
- package/src/Plot.jsx +2 -0
- package/src/RadialTree.tsx +768 -0
- package/src/createElement.jsx +3 -1
- package/src/index.js +1 -0
- package/src/style/axis.shadow.css +2 -4
- package/src/style/plot.shadow.css +6 -0
- package/src/style/radial-tree.shadow.css +23 -0
- package/src/types/index.d.ts +6 -0
- package/src/utils.ts +227 -0
- package/src/utils.js +0 -147
package/src/createElement.jsx
CHANGED
|
@@ -9,11 +9,13 @@ import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
|
9
9
|
|
|
10
10
|
function createElementRender() {
|
|
11
11
|
const Element = React.forwardRef(function (
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
12
13
|
{ render, tag, childrenPosition = 'below', x: xS, y: yS, ...source },
|
|
13
14
|
ref,
|
|
14
15
|
) {
|
|
15
16
|
const {
|
|
16
17
|
forwardRef = null,
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
19
|
children: _children,
|
|
18
20
|
Children,
|
|
19
21
|
x = xS,
|
|
@@ -50,7 +52,7 @@ function createElementRender() {
|
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
if (!Tag) {
|
|
53
|
-
throw new Error('
|
|
55
|
+
throw new Error('Element expected render prop to be passed');
|
|
54
56
|
}
|
|
55
57
|
return [
|
|
56
58
|
<React.Fragment key="child-above">
|
package/src/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { default as Area } from './Area';
|
|
|
12
12
|
export { default as StackedArea } from './StackedArea';
|
|
13
13
|
export { default as ScatterPlot } from './ScatterPlot';
|
|
14
14
|
export { default as Bubble } from './Bubble';
|
|
15
|
+
export { default as RadialTree } from './RadialTree';
|
|
15
16
|
export { default as Donut } from './Donut';
|
|
16
17
|
export { default as Venn } from './Venn';
|
|
17
18
|
|
|
@@ -25,7 +25,7 @@ SGrid {
|
|
|
25
25
|
STitle {
|
|
26
26
|
font-size: 12px;
|
|
27
27
|
fill: var(--gray60);
|
|
28
|
-
transform-origin:
|
|
28
|
+
transform-origin: var(--transform-origin);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
STitle[position='top'] {
|
|
@@ -41,14 +41,12 @@ STitle[position='bottom'] {
|
|
|
41
41
|
|
|
42
42
|
STitle[position='right'] {
|
|
43
43
|
transform: rotate(-90deg);
|
|
44
|
-
transform-box: fill-box;
|
|
45
44
|
alignment-baseline: middle;
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
STitle[position='left'] {
|
|
49
48
|
transform: rotate(-90deg);
|
|
50
|
-
text-anchor:
|
|
51
|
-
transform-box: fill-box;
|
|
49
|
+
text-anchor: middle;
|
|
52
50
|
alignment-baseline: middle;
|
|
53
51
|
}
|
|
54
52
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@import '@semcore/utils/style/var.css';
|
|
2
|
+
@import '@semcore/d3-chart/src/style/var.css';
|
|
3
|
+
|
|
4
|
+
SRadian {
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
}
|
|
7
|
+
SCap {
|
|
8
|
+
transition: r 0.1s;
|
|
9
|
+
}
|
|
10
|
+
SLabel {
|
|
11
|
+
fill: var(--color);
|
|
12
|
+
cursor: var(--text-cursor);
|
|
13
|
+
transform-origin: var(--transform-origin);
|
|
14
|
+
}
|
|
15
|
+
SRadian:hover SLabel {
|
|
16
|
+
fill: var(--color-hovered);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@media (prefers-reduced-motion) {
|
|
20
|
+
SLineCap {
|
|
21
|
+
transition: none;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/types/index.d.ts
CHANGED
|
@@ -34,6 +34,12 @@ export * from './Area';
|
|
|
34
34
|
export { default as StackedArea } from './StackedArea';
|
|
35
35
|
export * from './StackedArea';
|
|
36
36
|
|
|
37
|
+
/** It becomes resolvable after building and moving file to lib dir */
|
|
38
|
+
// eslint-disable-next-line import/no-unresolved
|
|
39
|
+
export { default as RadialTree } from './RadialTree';
|
|
40
|
+
// eslint-disable-next-line import/no-unresolved
|
|
41
|
+
export * from './RadialTree';
|
|
42
|
+
|
|
37
43
|
export { default as Donut } from './Donut';
|
|
38
44
|
export * from './Donut';
|
|
39
45
|
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { extent, bisector, Numeric } from 'd3-array';
|
|
2
|
+
import {
|
|
3
|
+
scaleQuantize,
|
|
4
|
+
ScaleIdentity,
|
|
5
|
+
ScaleTime,
|
|
6
|
+
ScaleContinuousNumeric,
|
|
7
|
+
ScaleBand,
|
|
8
|
+
ScalePoint,
|
|
9
|
+
NumberValue,
|
|
10
|
+
} from 'd3-scale';
|
|
11
|
+
import React from 'react';
|
|
12
|
+
|
|
13
|
+
const CONSTANT = {
|
|
14
|
+
VIRTUAL_ELEMENT: Symbol('VIRTUAL_ELEMENT'),
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
export { CONSTANT };
|
|
18
|
+
|
|
19
|
+
export const eventToPoint = (event: React.MouseEvent<HTMLElement>, svgRoot: SVGElement) => {
|
|
20
|
+
const node = (event.currentTarget || event.target) as HTMLElement;
|
|
21
|
+
const rect = svgRoot.getBoundingClientRect();
|
|
22
|
+
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type InvertableScale =
|
|
26
|
+
| ScaleIdentity
|
|
27
|
+
| ScaleTime<unknown, unknown>
|
|
28
|
+
| ScaleContinuousNumeric<unknown, unknown>;
|
|
29
|
+
export const invert = <Scale extends InvertableScale = InvertableScale>(
|
|
30
|
+
scale: Scale,
|
|
31
|
+
value: number,
|
|
32
|
+
) => {
|
|
33
|
+
if (scale.invert) return scale.invert(value);
|
|
34
|
+
|
|
35
|
+
const range = scale.range() as number[];
|
|
36
|
+
const domain = scale.domain();
|
|
37
|
+
|
|
38
|
+
return scaleQuantize()
|
|
39
|
+
.domain((range[0] <= range[1] ? range : range.slice().reverse()) as NumberValue[])
|
|
40
|
+
.range((range[0] <= range[1] ? domain : domain.slice().reverse()) as number[])(value);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const definedNullData = (x: number, y: number) => (plot: { [xOrY: number]: unknown }) =>
|
|
44
|
+
plot[x] !== null && plot[y] !== null;
|
|
45
|
+
|
|
46
|
+
export const definedData = (x: number, y: number) => (plot: { [xOrY: number]: unknown }) =>
|
|
47
|
+
plot[x] !== null && plot[x] !== undefined && plot[y] !== null && plot[y] !== undefined;
|
|
48
|
+
|
|
49
|
+
export const scaleOfBandwidth = <Scale extends ScaleBand<{}>>(scale: Scale, value: number) =>
|
|
50
|
+
scale.bandwidth ? scale(value)! + scale.bandwidth() / 2 : scale(value);
|
|
51
|
+
|
|
52
|
+
export const minMax = <
|
|
53
|
+
Key extends string = string,
|
|
54
|
+
Data extends Iterable<{ [key in Key]: Numeric | null | undefined }> = Iterable<{
|
|
55
|
+
[key in Key]: Numeric | null | undefined;
|
|
56
|
+
}>,
|
|
57
|
+
>(
|
|
58
|
+
data: Data,
|
|
59
|
+
key: Key,
|
|
60
|
+
) => {
|
|
61
|
+
if (typeof key === 'string') {
|
|
62
|
+
return extent(data, (d) => d[key]);
|
|
63
|
+
}
|
|
64
|
+
return extent(data, key);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const getNullData = <
|
|
68
|
+
Name extends string = string,
|
|
69
|
+
Data extends { [name in Name]?: unknown | null } = {},
|
|
70
|
+
>(
|
|
71
|
+
data: Data[],
|
|
72
|
+
defined: (data: Data) => boolean,
|
|
73
|
+
name: Name,
|
|
74
|
+
) =>
|
|
75
|
+
data.reduce((acc, d, i, data) => {
|
|
76
|
+
if (defined(d)) {
|
|
77
|
+
acc.push({
|
|
78
|
+
[name]: null,
|
|
79
|
+
} as Data);
|
|
80
|
+
} else {
|
|
81
|
+
const prev = data[i - 1];
|
|
82
|
+
const next = data[i + 1];
|
|
83
|
+
|
|
84
|
+
if (i === 0) {
|
|
85
|
+
const defNext = data.find(defined);
|
|
86
|
+
acc.push({
|
|
87
|
+
...d,
|
|
88
|
+
[name]: defNext ? defNext[name] : null,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// prev
|
|
93
|
+
if (prev && defined(prev)) {
|
|
94
|
+
acc.push(prev);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// next
|
|
98
|
+
if (next && defined(next)) {
|
|
99
|
+
acc.push(next);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (data.length - 1 === i) {
|
|
103
|
+
const defPrev = data.slice().reverse().find(defined);
|
|
104
|
+
acc.push({
|
|
105
|
+
...d,
|
|
106
|
+
[name]: defPrev ? defPrev[name] : null,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return acc;
|
|
111
|
+
}, [] as Data[]);
|
|
112
|
+
|
|
113
|
+
type IndexFromDataScale =
|
|
114
|
+
| ScaleIdentity
|
|
115
|
+
| ScaleTime<unknown, unknown>
|
|
116
|
+
| ScaleContinuousNumeric<unknown, unknown>
|
|
117
|
+
| ScaleBand<{}>
|
|
118
|
+
| ScalePoint<{}>;
|
|
119
|
+
export const getIndexFromData = <
|
|
120
|
+
Data extends {
|
|
121
|
+
[key: string]: number;
|
|
122
|
+
} = {},
|
|
123
|
+
Scale extends IndexFromDataScale = IndexFromDataScale,
|
|
124
|
+
>(
|
|
125
|
+
data: Data[],
|
|
126
|
+
scale: Scale,
|
|
127
|
+
key: string,
|
|
128
|
+
value: number,
|
|
129
|
+
) => {
|
|
130
|
+
// detect line chart
|
|
131
|
+
if ('invert' in scale && typeof scale.invert === 'function') {
|
|
132
|
+
const bisect = bisector((d: { [key: string]: number }) => d[key]).center;
|
|
133
|
+
return bisect(data, value);
|
|
134
|
+
}
|
|
135
|
+
// detect bar chart
|
|
136
|
+
else if ('step' in scale && typeof scale.step !== 'undefined') {
|
|
137
|
+
const index = data.findIndex((d) => d[key] === value);
|
|
138
|
+
return index >= 0 ? index : null;
|
|
139
|
+
} else {
|
|
140
|
+
// eslint-disable-next-line no-console
|
|
141
|
+
console.warn('[d3-chart/utils/getIndexFromData] encountered incompatible scale type');
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export const roundedPath = (
|
|
147
|
+
x: number,
|
|
148
|
+
y: number,
|
|
149
|
+
w: number,
|
|
150
|
+
h: number,
|
|
151
|
+
r: number,
|
|
152
|
+
tl = false,
|
|
153
|
+
tr = false,
|
|
154
|
+
bl = false,
|
|
155
|
+
br = false,
|
|
156
|
+
) => {
|
|
157
|
+
let result = 'M' + (x + r) + ',' + y;
|
|
158
|
+
result += 'h' + (w - 2 * r);
|
|
159
|
+
if (tr) {
|
|
160
|
+
result += 'a' + r + ',' + r + ' 0 0 1 ' + r + ',' + r;
|
|
161
|
+
} else {
|
|
162
|
+
result += 'h' + r;
|
|
163
|
+
result += 'v' + r;
|
|
164
|
+
}
|
|
165
|
+
result += 'v' + (h - 2 * r);
|
|
166
|
+
if (br) {
|
|
167
|
+
result += 'a' + r + ',' + r + ' 0 0 1 ' + -r + ',' + r;
|
|
168
|
+
} else {
|
|
169
|
+
result += 'v' + r;
|
|
170
|
+
result += 'h' + -r;
|
|
171
|
+
}
|
|
172
|
+
result += 'h' + (2 * r - w);
|
|
173
|
+
if (bl) {
|
|
174
|
+
result += 'a' + r + ',' + r + ' 0 0 1 ' + -r + ',' + -r;
|
|
175
|
+
} else {
|
|
176
|
+
result += 'h' + -r;
|
|
177
|
+
result += 'v' + -r;
|
|
178
|
+
}
|
|
179
|
+
result += 'v' + (2 * r - h);
|
|
180
|
+
if (tl) {
|
|
181
|
+
result += 'a' + r + ',' + r + ' 0 0 1 ' + r + ',' + -r;
|
|
182
|
+
} else {
|
|
183
|
+
result += 'v' + -r;
|
|
184
|
+
result += 'h' + r;
|
|
185
|
+
}
|
|
186
|
+
result += 'z';
|
|
187
|
+
return result;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export const getBandwidth = <Scale extends ScaleBand<{}>>(scale: Scale) => {
|
|
191
|
+
if ('bandwidth' in scale) {
|
|
192
|
+
return scale.bandwidth();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const range = scale.range();
|
|
196
|
+
const domain = scale.domain();
|
|
197
|
+
return Math.abs(range[range.length - 1] - range[0]) / domain.length;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export const memoize = <Func extends (...args: any[]) => any>(func: Func): Func => {
|
|
201
|
+
const results: { [cacheKey: string]: any } = {};
|
|
202
|
+
return ((...args: any[]) => {
|
|
203
|
+
const argsKey = args.join(',');
|
|
204
|
+
if (!results[argsKey]) {
|
|
205
|
+
results[argsKey] = func(...args);
|
|
206
|
+
}
|
|
207
|
+
return results[argsKey];
|
|
208
|
+
}) as Func;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export const measureText = memoize((text: string, fontSize?: number) => {
|
|
212
|
+
if (!text) return 0;
|
|
213
|
+
|
|
214
|
+
const span = document.createElement('span');
|
|
215
|
+
if (fontSize) {
|
|
216
|
+
span.style.fontSize = `${fontSize}px`;
|
|
217
|
+
}
|
|
218
|
+
for (const line of text.split('\n')) {
|
|
219
|
+
span.append(document.createTextNode(line));
|
|
220
|
+
span.append(document.createElement('br'));
|
|
221
|
+
}
|
|
222
|
+
span.style.display = 'inline-block';
|
|
223
|
+
document.body.append(span);
|
|
224
|
+
const textWidth = span.offsetWidth;
|
|
225
|
+
span.remove();
|
|
226
|
+
return textWidth;
|
|
227
|
+
});
|
package/src/utils.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { extent, bisector } from 'd3-array';
|
|
2
|
-
import { scaleQuantize } from 'd3-scale';
|
|
3
|
-
|
|
4
|
-
const CONSTANT = {
|
|
5
|
-
VIRTUAL_ELEMENT: Symbol('VIRTUAL_ELEMENT'),
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export { CONSTANT };
|
|
9
|
-
|
|
10
|
-
export function eventToPoint(event, svgRoot) {
|
|
11
|
-
const node = event.currentTarget || event.target;
|
|
12
|
-
const rect = svgRoot.getBoundingClientRect();
|
|
13
|
-
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function invert(scale, value) {
|
|
17
|
-
if (scale.invert) return scale.invert(value);
|
|
18
|
-
|
|
19
|
-
const range = scale.range();
|
|
20
|
-
const domain = scale.domain();
|
|
21
|
-
|
|
22
|
-
return scaleQuantize()
|
|
23
|
-
.domain(range[0] <= range[1] ? range : range.slice().reverse())
|
|
24
|
-
.range(range[0] <= range[1] ? domain : domain.slice().reverse())(value);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function definedNullData(x, y) {
|
|
28
|
-
return (p) => p[x] !== null && p[y] !== null;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function definedData(x, y) {
|
|
32
|
-
return (p) => {
|
|
33
|
-
return p[x] !== null && p[x] !== undefined && p[y] !== null && p[y] !== undefined;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function scaleOfBandwidth(scale, value) {
|
|
38
|
-
return scale.bandwidth ? scale(value) + scale.bandwidth() / 2 : scale(value);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function minMax(data, key) {
|
|
42
|
-
if (typeof key === 'string') {
|
|
43
|
-
return extent(data, (d) => d[key]);
|
|
44
|
-
}
|
|
45
|
-
return extent(data, key);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function getNullData(data, defined, name) {
|
|
49
|
-
return data.reduce((acc, d, i, data) => {
|
|
50
|
-
if (defined(d)) {
|
|
51
|
-
acc.push({
|
|
52
|
-
[name]: null,
|
|
53
|
-
});
|
|
54
|
-
} else {
|
|
55
|
-
const prev = data[i - 1];
|
|
56
|
-
const next = data[i + 1];
|
|
57
|
-
|
|
58
|
-
if (i === 0) {
|
|
59
|
-
const defNext = data.find(defined);
|
|
60
|
-
acc.push({
|
|
61
|
-
...d,
|
|
62
|
-
[name]: defNext ? defNext[name] : null,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// prev
|
|
67
|
-
if (prev && defined(prev)) {
|
|
68
|
-
acc.push(prev);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// next
|
|
72
|
-
if (next && defined(next)) {
|
|
73
|
-
acc.push(next);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (data.length - 1 === i) {
|
|
77
|
-
const defPrev = data.slice().reverse().find(defined);
|
|
78
|
-
acc.push({
|
|
79
|
-
...d,
|
|
80
|
-
[name]: defPrev ? defPrev[name] : null,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return acc;
|
|
85
|
-
}, []);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function getIndexFromData(data, scale, key, value) {
|
|
89
|
-
// detect line chart
|
|
90
|
-
if ('invert' in scale && typeof scale.invert === 'function') {
|
|
91
|
-
const bisect = bisector((d) => d[key]).center;
|
|
92
|
-
return bisect(data, value);
|
|
93
|
-
}
|
|
94
|
-
// detect bar chart
|
|
95
|
-
else if ('step' in scale && typeof scale.step !== 'undefined') {
|
|
96
|
-
const index = data.findIndex((d) => d[key] === value);
|
|
97
|
-
return index >= 0 ? index : null;
|
|
98
|
-
} else {
|
|
99
|
-
console.warn('[d3-chart/utils/getIndexFromData] encountered incompatible scale type');
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function roundedPath(x, y, w, h, r, tl = false, tr = false, bl = false, br = false) {
|
|
105
|
-
let retval;
|
|
106
|
-
retval = 'M' + (x + r) + ',' + y;
|
|
107
|
-
retval += 'h' + (w - 2 * r);
|
|
108
|
-
if (tr) {
|
|
109
|
-
retval += 'a' + r + ',' + r + ' 0 0 1 ' + r + ',' + r;
|
|
110
|
-
} else {
|
|
111
|
-
retval += 'h' + r;
|
|
112
|
-
retval += 'v' + r;
|
|
113
|
-
}
|
|
114
|
-
retval += 'v' + (h - 2 * r);
|
|
115
|
-
if (br) {
|
|
116
|
-
retval += 'a' + r + ',' + r + ' 0 0 1 ' + -r + ',' + r;
|
|
117
|
-
} else {
|
|
118
|
-
retval += 'v' + r;
|
|
119
|
-
retval += 'h' + -r;
|
|
120
|
-
}
|
|
121
|
-
retval += 'h' + (2 * r - w);
|
|
122
|
-
if (bl) {
|
|
123
|
-
retval += 'a' + r + ',' + r + ' 0 0 1 ' + -r + ',' + -r;
|
|
124
|
-
} else {
|
|
125
|
-
retval += 'h' + -r;
|
|
126
|
-
retval += 'v' + -r;
|
|
127
|
-
}
|
|
128
|
-
retval += 'v' + (2 * r - h);
|
|
129
|
-
if (tl) {
|
|
130
|
-
retval += 'a' + r + ',' + r + ' 0 0 1 ' + r + ',' + -r;
|
|
131
|
-
} else {
|
|
132
|
-
retval += 'v' + -r;
|
|
133
|
-
retval += 'h' + r;
|
|
134
|
-
}
|
|
135
|
-
retval += 'z';
|
|
136
|
-
return retval;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function getBandwidth(scale) {
|
|
140
|
-
if ('bandwidth' in scale) {
|
|
141
|
-
return scale.bandwidth();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const range = scale.range();
|
|
145
|
-
const domain = scale.domain();
|
|
146
|
-
return Math.abs(range[range.length - 1] - range[0]) / domain.length;
|
|
147
|
-
}
|