@semcore/d3-chart 1.0.0-8 → 1.2.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.
Files changed (154) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/lib/cjs/Area.js +71 -49
  3. package/lib/cjs/Area.js.map +1 -1
  4. package/lib/cjs/Axis.js +148 -142
  5. package/lib/cjs/Axis.js.map +1 -1
  6. package/lib/cjs/Bar.js +101 -54
  7. package/lib/cjs/Bar.js.map +1 -1
  8. package/lib/cjs/ClipPath.js +110 -0
  9. package/lib/cjs/ClipPath.js.map +1 -0
  10. package/lib/cjs/Donut.js +169 -68
  11. package/lib/cjs/Donut.js.map +1 -1
  12. package/lib/cjs/Dots.js +55 -21
  13. package/lib/cjs/Dots.js.map +1 -1
  14. package/lib/cjs/GroupBar.js +7 -6
  15. package/lib/cjs/GroupBar.js.map +1 -1
  16. package/lib/cjs/HorizontalBar.js +72 -45
  17. package/lib/cjs/HorizontalBar.js.map +1 -1
  18. package/lib/cjs/Hover.js +46 -47
  19. package/lib/cjs/Hover.js.map +1 -1
  20. package/lib/cjs/Line.js +63 -41
  21. package/lib/cjs/Line.js.map +1 -1
  22. package/lib/cjs/Plot.js +16 -29
  23. package/lib/cjs/Plot.js.map +1 -1
  24. package/lib/cjs/ResponsiveContainer.js +13 -9
  25. package/lib/cjs/ResponsiveContainer.js.map +1 -1
  26. package/lib/cjs/StackBar.js +6 -6
  27. package/lib/cjs/StackBar.js.map +1 -1
  28. package/lib/cjs/StackedArea.js +8 -9
  29. package/lib/cjs/StackedArea.js.map +1 -1
  30. package/lib/cjs/Tooltip.js +49 -75
  31. package/lib/cjs/Tooltip.js.map +1 -1
  32. package/lib/cjs/Venn.js +235 -0
  33. package/lib/cjs/Venn.js.map +1 -0
  34. package/lib/cjs/index.js +8 -0
  35. package/lib/cjs/index.js.map +1 -1
  36. package/lib/cjs/style/area.shadow.css +11 -10
  37. package/lib/cjs/style/bar.shadow.css +4 -0
  38. package/lib/cjs/style/donut.shadow.css +1 -0
  39. package/lib/cjs/style/dot.shadow.css +19 -0
  40. package/lib/cjs/style/line.shadow.css +4 -15
  41. package/lib/cjs/style/tooltip.shadow.css +1 -0
  42. package/lib/cjs/style/venn.shadow.css +23 -0
  43. package/lib/cjs/utils.js +8 -1
  44. package/lib/cjs/utils.js.map +1 -1
  45. package/lib/es6/Area.js +72 -50
  46. package/lib/es6/Area.js.map +1 -1
  47. package/lib/es6/Axis.js +149 -143
  48. package/lib/es6/Axis.js.map +1 -1
  49. package/lib/es6/Bar.js +100 -54
  50. package/lib/es6/Bar.js.map +1 -1
  51. package/lib/es6/ClipPath.js +91 -0
  52. package/lib/es6/ClipPath.js.map +1 -0
  53. package/lib/es6/Donut.js +167 -67
  54. package/lib/es6/Donut.js.map +1 -1
  55. package/lib/es6/Dots.js +51 -20
  56. package/lib/es6/Dots.js.map +1 -1
  57. package/lib/es6/GroupBar.js +7 -6
  58. package/lib/es6/GroupBar.js.map +1 -1
  59. package/lib/es6/HorizontalBar.js +72 -45
  60. package/lib/es6/HorizontalBar.js.map +1 -1
  61. package/lib/es6/Hover.js +47 -48
  62. package/lib/es6/Hover.js.map +1 -1
  63. package/lib/es6/Line.js +65 -43
  64. package/lib/es6/Line.js.map +1 -1
  65. package/lib/es6/Plot.js +17 -29
  66. package/lib/es6/Plot.js.map +1 -1
  67. package/lib/es6/ResponsiveContainer.js +13 -7
  68. package/lib/es6/ResponsiveContainer.js.map +1 -1
  69. package/lib/es6/StackBar.js +6 -6
  70. package/lib/es6/StackBar.js.map +1 -1
  71. package/lib/es6/StackedArea.js +8 -9
  72. package/lib/es6/StackedArea.js.map +1 -1
  73. package/lib/es6/Tooltip.js +52 -76
  74. package/lib/es6/Tooltip.js.map +1 -1
  75. package/lib/es6/Venn.js +217 -0
  76. package/lib/es6/Venn.js.map +1 -0
  77. package/lib/es6/index.js +1 -0
  78. package/lib/es6/index.js.map +1 -1
  79. package/lib/es6/style/area.shadow.css +11 -10
  80. package/lib/es6/style/bar.shadow.css +4 -0
  81. package/lib/es6/style/donut.shadow.css +1 -0
  82. package/lib/es6/style/dot.shadow.css +19 -0
  83. package/lib/es6/style/line.shadow.css +4 -15
  84. package/lib/es6/style/tooltip.shadow.css +1 -0
  85. package/lib/es6/style/venn.shadow.css +23 -0
  86. package/lib/es6/utils.js +6 -1
  87. package/lib/es6/utils.js.map +1 -1
  88. package/lib/types/Area.d.ts +7 -8
  89. package/lib/types/Axis.d.ts +6 -6
  90. package/lib/types/Bar.d.ts +7 -3
  91. package/lib/types/ClipPath.d.ts +26 -0
  92. package/lib/types/Donut.d.ts +12 -2
  93. package/lib/types/GroupBar.d.ts +2 -2
  94. package/lib/types/HorizontalBar.d.ts +7 -3
  95. package/lib/types/Hover.d.ts +2 -2
  96. package/lib/types/Line.d.ts +9 -4
  97. package/{src/types/Plot.ts → lib/types/Plot.d.ts} +2 -2
  98. package/lib/types/ResponsiveContainer.d.ts +1 -1
  99. package/lib/types/StackBar.d.ts +3 -11
  100. package/lib/types/StackedArea.d.ts +7 -6
  101. package/lib/types/Tooltip.d.ts +4 -4
  102. package/lib/types/Venn.d.ts +45 -0
  103. package/lib/types/context.d.ts +1 -1
  104. package/lib/types/index.d.ts +6 -0
  105. package/package.json +10 -5
  106. package/src/Area.js +43 -14
  107. package/src/Axis.js +24 -22
  108. package/src/Bar.js +69 -24
  109. package/src/ClipPath.js +36 -0
  110. package/src/Donut.js +84 -12
  111. package/src/Dots.js +36 -20
  112. package/src/GroupBar.js +1 -0
  113. package/src/HorizontalBar.js +49 -22
  114. package/src/Hover.js +3 -3
  115. package/src/Line.js +41 -13
  116. package/src/Plot.js +3 -7
  117. package/src/ResponsiveContainer.js +3 -3
  118. package/src/StackBar.js +1 -1
  119. package/src/StackedArea.js +3 -2
  120. package/src/Tooltip.js +11 -12
  121. package/src/Venn.js +112 -0
  122. package/src/index.js +1 -0
  123. package/src/style/area.shadow.css +11 -10
  124. package/src/style/bar.shadow.css +4 -0
  125. package/src/style/donut.shadow.css +1 -0
  126. package/src/style/dot.shadow.css +19 -0
  127. package/src/style/line.shadow.css +4 -15
  128. package/src/style/tooltip.shadow.css +1 -0
  129. package/src/style/venn.shadow.css +23 -0
  130. package/src/types/Area.d.ts +7 -8
  131. package/src/types/Axis.d.ts +6 -6
  132. package/src/types/Bar.d.ts +7 -3
  133. package/src/types/ClipPath.d.ts +26 -0
  134. package/src/types/Donut.d.ts +12 -2
  135. package/src/types/GroupBar.d.ts +2 -2
  136. package/src/types/HorizontalBar.d.ts +7 -3
  137. package/src/types/Hover.d.ts +2 -2
  138. package/src/types/Line.d.ts +9 -4
  139. package/src/types/Plot.d.ts +16 -0
  140. package/src/types/ResponsiveContainer.d.ts +1 -1
  141. package/src/types/StackBar.d.ts +3 -11
  142. package/src/types/StackedArea.d.ts +7 -6
  143. package/src/types/Tooltip.d.ts +4 -4
  144. package/src/types/Venn.d.ts +45 -0
  145. package/src/types/context.d.ts +1 -1
  146. package/src/types/index.d.ts +6 -0
  147. package/src/utils.js +7 -1
  148. package/lib/cjs/style/chart.shadow.css +0 -4
  149. package/lib/cjs/types/Plot.js +0 -2
  150. package/lib/cjs/types/Plot.js.map +0 -1
  151. package/lib/es6/style/chart.shadow.css +0 -4
  152. package/lib/es6/types/Plot.js +0 -2
  153. package/lib/es6/types/Plot.js.map +0 -1
  154. package/src/style/chart.shadow.css +0 -4
@@ -1,22 +1,27 @@
1
1
  import { CProps, ReturnEl } from '@semcore/core';
2
2
  import IContext from './context';
3
3
  import { CurveFactory } from 'd3-shape';
4
+ import { IFadeInOutProps } from '@semcore/animation';
4
5
 
5
6
  export interface ILineProps extends IContext {
6
- /** Field from data for Axis x */
7
+ /** Field from data for XAxis */
7
8
  x?: string;
8
- /** Field from data for Axis y */
9
+ /** Field from data for YAxis */
9
10
  y?: string;
10
- /** Color line
11
+ /** Line color
11
12
  * @default '#50aef4'*/
12
13
  color?: string;
13
14
  /** Element hide property */
14
15
  hide?: boolean;
15
16
  /** Curve method */
16
17
  curve?: CurveFactory;
18
+ /** Animation duration in ms
19
+ * @default 500
20
+ */
21
+ duration?: number;
17
22
  }
18
23
 
19
- export interface ILineDotsProps extends IContext {
24
+ export interface ILineDotsProps extends IContext, IFadeInOutProps {
20
25
  /** Show all Dot */
21
26
  display?: boolean;
22
27
  /** Hide property */
@@ -3,10 +3,10 @@ import { CProps, ReturnEl } from '@semcore/core';
3
3
  import IContext from './context';
4
4
 
5
5
  export interface IPlotProps extends IContext, IBoxProps {
6
- /** Width svg element
6
+ /** Width of the svg element
7
7
  * @default 0*/
8
8
  width?: number;
9
- /** Height svg element
9
+ /** Height of the svg element
10
10
  * @default 0*/
11
11
  height?: number;
12
12
  }
@@ -4,7 +4,7 @@ import { CProps, ReturnEl } from '@semcore/core';
4
4
  export interface IResponsiveContainerProps extends IBoxProps {
5
5
  /** Relation between height and width dimensions block */
6
6
  aspect?: number;
7
- /** Callback which will called after change size block */
7
+ /** Callback which will be called after changing the block size */
8
8
  onResize?: (size: [number, number], entries: ResizeObserverEntry[]) => void;
9
9
  }
10
10
 
@@ -4,21 +4,13 @@ import { IBarContext, IBarProps } from './Bar';
4
4
  import { IHorizontalBarProps } from './HorizontalBar';
5
5
 
6
6
  export interface IStackBarProps extends IContext {
7
- /** Data for graphic */
8
- data?: any[];
9
- /** Field from data for Axis x */
7
+ /** Field from data for XAxis */
10
8
  x?: string;
11
- /** Field from data for Axis y */
9
+ /** Field from data for YAxis */
12
10
  y?: string;
13
11
  /** Stack generators
14
12
  * @default d3.stack() */
15
- stack?: Stack<
16
- any,
17
- {
18
- [key: string]: number;
19
- },
20
- string
21
- >;
13
+ stack?: any;
22
14
  }
23
15
 
24
16
  export interface IStackBarContext {
@@ -1,14 +1,15 @@
1
1
  import { CProps, ReturnEl } from '@semcore/core';
2
2
  import IContext from './context';
3
- import { IAreaProps } from './Area';
3
+ import Area from './Area';
4
4
 
5
5
  export interface IStackedAreaProps extends IContext {
6
- /** Data for graphic */
7
- data?: any[];
8
- /** Field from data for Axis x */
6
+ /** Field from data for XAxis */
9
7
  x?: string;
10
- /** Field from data for Axis y */
8
+ /** Field from data for YAxis */
11
9
  y?: string;
10
+ /** Stack generators
11
+ * @default d3.stack() */
12
+ stack?: any;
12
13
  }
13
14
 
14
15
  export interface IStackedAreaContext {
@@ -19,7 +20,7 @@ export interface IStackedAreaContext {
19
20
  declare const StackedArea: (<T>(
20
21
  props: CProps<IStackedAreaProps & T, IStackedAreaContext>,
21
22
  ) => ReturnEl) & {
22
- Area: <T>(props: CProps<IAreaProps & T>) => ReturnEl;
23
+ Area: typeof Area;
23
24
  };
24
25
 
25
26
  export default StackedArea;
@@ -1,13 +1,13 @@
1
- import { IPopperProps, IPopperTriggerProps } from '@semcore/popper';
1
+ import { ComponentProps } from 'react';
2
+ import Popper, { IPopperProps, IPopperTriggerProps } from '@semcore/popper';
2
3
  import { CProps, PropGetterFn, ReturnEl } from '@semcore/core';
3
- import Popper from '@semcore/popper/lib/types/Popper';
4
4
  import { IBoxProps } from '@semcore/flex-box';
5
5
  import IContext from './context';
6
6
 
7
7
  export interface ITooltipProps extends IPopperProps, IPopperTriggerProps, IContext {
8
- /** Field from data for Axis x */
8
+ /** Field from data for XAxis */
9
9
  x?: string;
10
- /** Field from data for Axis y */
10
+ /** Field from data for YAxis */
11
11
  y?: string;
12
12
  }
13
13
 
@@ -0,0 +1,45 @@
1
+ import { CProps, ReturnEl } from '@semcore/core';
2
+ import IContext from './context';
3
+ import { IFadeInOutProps } from '@semcore/animation';
4
+
5
+ export interface IVennProps extends IContext, IFadeInOutProps {
6
+ /**
7
+ * Rotate sets in the chart
8
+ * @default Math.PI / 2
9
+ */
10
+ orientation?: number;
11
+ /**
12
+ * The function for sorting sets inside the chart
13
+ * @default (circle1, circle2) => circle2.radius - circle1.radius
14
+ */
15
+ orientationOrder?: (c1: number, c2: number) => number;
16
+ }
17
+
18
+ export interface ICircleProps extends IContext {
19
+ /**
20
+ * Name of the field in the data
21
+ * */
22
+ dataKey: string;
23
+ /** Color circle
24
+ @default #3AB011
25
+ **/
26
+ color?: string;
27
+ /** Animation duration in ms
28
+ * @default 500
29
+ */
30
+ duration?: number;
31
+ }
32
+
33
+ export interface IIntersectionProps extends IContext, IFadeInOutProps {
34
+ /**
35
+ * Name of the field in the data
36
+ * */
37
+ dataKey: string;
38
+ }
39
+
40
+ declare const Venn: (<T>(props: CProps<IVennProps & T>) => ReturnEl) & {
41
+ Circle: <T>(props: CProps<ICircleProps & T>) => ReturnEl;
42
+ Intersection: <T>(props: CProps<IIntersectionProps & T>) => ReturnEl;
43
+ };
44
+
45
+ export default Venn;
@@ -1,6 +1,6 @@
1
1
  export default interface IContext {
2
2
  /** Data for graphic */
3
- data?: any[];
3
+ data?: any;
4
4
  /** Scale for svg element */
5
5
  scale?: any[];
6
6
  }
@@ -28,6 +28,12 @@ export * from './GroupBar';
28
28
  export { default as StackBar } from './StackBar';
29
29
  export * from './StackBar';
30
30
 
31
+ export { default as Area } from './Area';
32
+ export * from './Area';
33
+
34
+ export { default as StackedArea } from './StackedArea';
35
+ export * from './StackedArea';
36
+
31
37
  export { default as Donut } from './Donut';
32
38
  export * from './Donut';
33
39
 
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@semcore/d3-chart",
3
3
  "description": "SEMRush D3 Chart Component",
4
- "version": "1.0.0-8",
4
+ "version": "1.2.0",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/es6/index.js",
7
7
  "typings": "lib/types/index.d.ts",
8
+ "sideEffects": false,
8
9
  "author": "Roman Lysov <r.lysov@semrush.com>",
9
10
  "license": "MIT",
10
11
  "scripts": {
@@ -15,13 +16,17 @@
15
16
  "@semcore/flex-box": "^4",
16
17
  "@semcore/popper": "^4.9",
17
18
  "@semcore/utils": "^3.15",
18
- "d3-array": "^2.8",
19
- "d3-shape": "^2.0",
19
+ "@semcore/animation": "^1",
20
+ "@upsetjs/venn.js": "^1.4.1",
21
+ "d3-array": "^3",
22
+ "d3-shape": "^3",
20
23
  "resize-observer-polyfill": "^1.5"
21
24
  },
22
25
  "peerDependencies": {
23
- "@semcore/core": "^1.10",
24
- "react": "16.8 - 17"
26
+ "@semcore/core": "^1.11",
27
+ "react": "16.8 - 17",
28
+ "d3-interpolate": "^2.0.1",
29
+ "d3-transition": "^1.3.2"
25
30
  },
26
31
  "jest": {
27
32
  "preset": "jest-preset-ui"
package/src/Area.js CHANGED
@@ -1,15 +1,18 @@
1
1
  import React from 'react';
2
2
  import { area, curveLinear, line } from 'd3-shape';
3
3
  import Dots from './Dots';
4
- import { Component, styled } from '@semcore/core';
4
+ import { Component, sstyled } from '@semcore/core';
5
5
  import createElement from './createElement';
6
- import { definedData, scaleOfBandwidth, getNullData } from './utils';
6
+ import { definedData, scaleOfBandwidth, getNullData, definedNullData } from './utils';
7
+ import ClipPath from './ClipPath';
8
+ import uniqueIDEnhancement from '@semcore/utils/lib/uniqueID';
7
9
 
8
10
  import style from './style/area.shadow.css';
9
11
 
10
12
  class AreaRoot extends Component {
11
13
  static displayName = 'Area';
12
14
  static style = style;
15
+ static enhance = [uniqueIDEnhancement()];
13
16
 
14
17
  static defaultProps = ({ x, y, y0, $rootProps, curve = curveLinear }) => {
15
18
  const [xScale, yScale] = $rootProps.scale;
@@ -28,7 +31,7 @@ class AreaRoot extends Component {
28
31
  .x((p) => scaleOfBandwidth(xScale, p[x]))
29
32
  .y((p) => scaleOfBandwidth(yScale, p[y])),
30
33
  color: '#50aef4',
31
- fill: '#50aef450',
34
+ duration: 500,
32
35
  };
33
36
  };
34
37
 
@@ -40,34 +43,60 @@ class AreaRoot extends Component {
40
43
  y,
41
44
  data,
42
45
  d3: d3Line,
43
- fill: color,
46
+ color,
44
47
  };
45
48
  }
46
49
 
47
50
  getNullProps() {
48
- const { y, color, data, d3Line } = this.asProps;
51
+ const { x, y, color, data, d3Line } = this.asProps;
49
52
  return {
50
- d3Line,
51
- data: getNullData(data, d3Line.defined(), y),
52
- fill: color,
53
+ data: getNullData(data, definedNullData(x, y), y),
54
+ d3: d3Line,
55
+ color,
53
56
  };
54
57
  }
55
58
 
56
59
  render() {
57
60
  const SArea = this.Element;
58
- const { styles, hide, d3, d3Line, data, fill, color } = this.asProps;
59
- return styled(styles)(
61
+ const SAreaLine = 'path';
62
+ const { styles, hide, d3, d3Line, data, color, uid, size, duration } = this.asProps;
63
+ return sstyled(styles)(
60
64
  <>
61
- <SArea render="path" hide={hide} fill={fill} d={d3(data)} />
62
- <path stroke={color} strokeWidth="3" fill="transparent" d={d3Line(data)} />
65
+ <SAreaLine
66
+ clipPath={`url(#${uid})`}
67
+ d={d3Line(data)}
68
+ color={color}
69
+ use:duration={`${duration}ms`}
70
+ />
71
+ <SArea
72
+ clipPath={`url(#${uid})`}
73
+ render="path"
74
+ d={d3(data)}
75
+ hide={hide}
76
+ color={color}
77
+ use:duration={`${duration}ms`}
78
+ />
79
+ {duration && (
80
+ <ClipPath
81
+ setAttributeTag={(rect) => {
82
+ rect.setAttribute('width', size[0]);
83
+ }}
84
+ id={uid}
85
+ x="0"
86
+ y="0"
87
+ width={0}
88
+ height={size[1]}
89
+ transition={`width ${duration}ms ease-in-out`}
90
+ />
91
+ )}
63
92
  </>,
64
93
  );
65
94
  }
66
95
  }
67
96
 
68
97
  function Null(props) {
69
- const { Element: SNull, styles, d3Line, data, hide } = props;
70
- return styled(styles)(<SNull render="path" d={d3Line(data)} hide={hide} />);
98
+ const { Element: SNull, styles, d3, data, hide, color } = props;
99
+ return sstyled(styles)(<SNull render="path" d={d3(data)} hide={hide} color={color} />);
71
100
  }
72
101
 
73
102
  export default createElement(AreaRoot, {
package/src/Axis.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Component, styled } from '@semcore/core';
2
+ import { Component, sstyled } from '@semcore/core';
3
3
  import createElement from './createElement';
4
4
  import { scaleOfBandwidth } from './utils';
5
5
 
@@ -194,17 +194,10 @@ class AxisRoot extends Component {
194
194
 
195
195
  static style = style;
196
196
 
197
- static defaultProps = {
198
- ticks: [],
199
- };
200
-
201
- getTicksProps() {
202
- const { ticks, position, indexScale } = this.asProps;
203
- return {
204
- ticks,
205
- indexScale,
206
- position,
207
- };
197
+ get ticks() {
198
+ const { ticks, indexScale, scale } = this.asProps;
199
+ const scl = scale[indexScale];
200
+ return ticks || (scl.ticks && scl.ticks()) || (scl.domain && scl.domain()) || [];
208
201
  }
209
202
 
210
203
  getTitleProps() {
@@ -214,10 +207,19 @@ class AxisRoot extends Component {
214
207
  };
215
208
  }
216
209
 
210
+ getTicksProps() {
211
+ const { position, indexScale } = this.asProps;
212
+ return {
213
+ ticks: this.ticks,
214
+ indexScale,
215
+ position,
216
+ };
217
+ }
218
+
217
219
  getGridProps() {
218
- const { ticks, indexScale } = this.asProps;
220
+ const { indexScale } = this.asProps;
219
221
  return {
220
- ticks,
222
+ ticks: this.ticks,
221
223
  indexScale,
222
224
  };
223
225
  }
@@ -227,27 +229,27 @@ class AxisRoot extends Component {
227
229
  const { styles, position, scale, hide, indexScale } = this.asProps;
228
230
 
229
231
  const pos =
230
- MAP_POSITION_AXIS[position] || MAP_POSITION_AXIS[MAP_INDEX_SCALE_SYMBOL[indexScale]];
232
+ MAP_POSITION_AXIS[position] ?? MAP_POSITION_AXIS[MAP_INDEX_SCALE_SYMBOL[indexScale]];
231
233
 
232
- return styled(styles)(<SAxis render="line" hide={hide} {...pos(scale, position)} />);
234
+ return sstyled(styles)(<SAxis render="line" hide={hide} {...pos(scale, position)} />);
233
235
  }
234
236
  }
235
237
 
236
238
  function Ticks(props) {
237
239
  const { Element: STick, styles, scale, ticks, position, hide, indexScale } = props;
238
240
 
239
- const pos = MAP_POSITION_TICK[position] || MAP_POSITION_TICK[MAP_INDEX_SCALE_SYMBOL[indexScale]];
241
+ const pos = MAP_POSITION_TICK[position] ?? MAP_POSITION_TICK[MAP_INDEX_SCALE_SYMBOL[indexScale]];
240
242
  const positionClass = MAP_POSITION_TICK[position] ? position : 'custom_' + indexScale;
241
243
 
242
244
  return ticks.map((value, i) => {
243
- return styled(styles)(
245
+ return sstyled(styles)(
244
246
  <STick
245
247
  key={i}
248
+ render="text"
249
+ childrenPosition="inside"
246
250
  __excludeProps={['data', 'scale', 'format', 'value']}
247
251
  value={value}
248
252
  index={i}
249
- childrenPosition="inside"
250
- render="text"
251
253
  position={positionClass}
252
254
  hide={hide}
253
255
  {...pos(scale, value, position)}
@@ -262,7 +264,7 @@ function Grid(props) {
262
264
  const { Element: SGrid, styles, scale, ticks, indexScale } = props;
263
265
 
264
266
  return ticks.map((value, i) => {
265
- return styled(styles)(
267
+ return sstyled(styles)(
266
268
  <SGrid key={i} render="line" {...MAP_POSITION_GRID[indexScale](scale, value)} />,
267
269
  );
268
270
  });
@@ -271,7 +273,7 @@ function Grid(props) {
271
273
  function Title(props) {
272
274
  const { Element: STitle, styles, scale, position } = props;
273
275
 
274
- return styled(styles)(
276
+ return sstyled(styles)(
275
277
  <STitle
276
278
  render="text"
277
279
  childrenPosition="inside"
package/src/Bar.js CHANGED
@@ -1,17 +1,21 @@
1
1
  import React from 'react';
2
- import { Component, styled } from '@semcore/core';
2
+ import { Component, sstyled } from '@semcore/core';
3
3
  import createElement from './createElement';
4
+ import ClipPath from './ClipPath';
5
+ import uniqueIDEnhancement from '@semcore/utils/lib/uniqueID';
6
+ import { transition } from 'd3-transition';
4
7
 
5
8
  import style from './style/bar.shadow.css';
6
9
 
7
10
  class BarRoot extends Component {
8
11
  static displayName = 'Bar';
9
-
10
12
  static style = style;
13
+ static enhance = [uniqueIDEnhancement()];
11
14
 
12
15
  static defaultProps = {
13
16
  color: '#50aef4',
14
17
  offset: [0, 0],
18
+ duration: 500,
15
19
  };
16
20
 
17
21
  getBackgroundProps(props, index) {
@@ -21,31 +25,72 @@ class BarRoot extends Component {
21
25
  };
22
26
  }
23
27
 
24
- render() {
28
+ animationBar() {
29
+ const { duration, uid } = this.asProps;
30
+ const selectRect = transition()
31
+ .selection()
32
+ .selectAll(`#${uid} rect`);
33
+ const selectRectNode = selectRect.node();
34
+
35
+ if (duration > 0 && selectRectNode && selectRectNode.getAttribute('y') !== '0') {
36
+ selectRect
37
+ .transition()
38
+ .duration(duration)
39
+ .attr('y', 0);
40
+ }
41
+ }
42
+
43
+ componentDidUpdate() {
44
+ this.animationBar();
45
+ }
46
+
47
+ componentDidMount() {
48
+ this.animationBar();
49
+ }
50
+
51
+ renderBar(d, i) {
25
52
  const SBar = this.Element;
26
- const { styles, color, x, y, y0, data, scale, hide, offset } = this.asProps;
53
+ const { styles, color, x, y, y0, scale, hide, offset, duration, uid } = this.asProps;
27
54
 
28
55
  const [xScale, yScale] = scale;
29
56
 
30
- return data.map((d, i) => {
31
- return styled(styles)(
32
- <SBar
33
- key={i}
34
- __excludeProps={['data', 'scale', 'value']}
35
- value={d}
36
- index={i}
37
- render="rect"
38
- childrenPosition="above"
39
- hide={hide}
40
- fill={color}
41
- // TODO: https://github.com/airbnb/visx/blob/2fa674e7d7fdc9cffea13e8bf644d46dd6f0db5b/packages/visx-shape/src/util/getBandwidth.ts#L3
42
- width={xScale.bandwidth()}
43
- height={Math.abs(yScale(d[y]) - Math.min(yScale(yScale.domain()[0]), yScale(d[y0] ?? 0)))}
44
- x={xScale(d[x]) + offset[0]}
45
- y={yScale(Math.max(d[y0] ?? 0, d[y])) + offset[1]}
46
- />,
47
- );
48
- });
57
+ return sstyled(styles)(
58
+ <SBar
59
+ key={`bar-${i}`}
60
+ render="rect"
61
+ clipPath={`url(#${uid})`}
62
+ __excludeProps={['data', 'scale', 'value']}
63
+ childrenPosition="above"
64
+ value={d}
65
+ index={i}
66
+ hide={hide}
67
+ color={color}
68
+ // TODO: https://github.com/airbnb/visx/blob/2fa674e7d7fdc9cffea13e8bf644d46dd6f0db5b/packages/visx-shape/src/util/getBandwidth.ts#L3
69
+ width={xScale.bandwidth()}
70
+ height={Math.abs(yScale(d[y]) - Math.min(yScale(yScale.domain()[0]), yScale(d[y0] ?? 0)))}
71
+ x={xScale(d[x]) + offset[0]}
72
+ y={yScale(Math.max(d[y0] ?? 0, d[y])) + offset[1]}
73
+ use:duration={`${duration}ms`}
74
+ />,
75
+ );
76
+ }
77
+ render() {
78
+ const { data, uid, size, duration } = this.asProps;
79
+ return (
80
+ <>
81
+ {data.map(this.renderBar.bind(this))}
82
+ {duration && (
83
+ <ClipPath
84
+ key={`${uid}-animation`}
85
+ id={uid}
86
+ x="0"
87
+ y={size[1]}
88
+ width={size[0]}
89
+ height={`${size[1]}px`}
90
+ />
91
+ )}
92
+ </>
93
+ );
49
94
  }
50
95
  }
51
96
 
@@ -55,7 +100,7 @@ function Background(props) {
55
100
  const [xScale, yScale] = scale;
56
101
  const yRange = yScale.range();
57
102
 
58
- return styled(styles)(
103
+ return sstyled(styles)(
59
104
  <SBackground
60
105
  render="rect"
61
106
  childrenPosition="above"
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import createComponent, { Component } from '@semcore/core';
3
+ import propsForElement from '@semcore/utils/lib/propsForElement';
4
+
5
+ class ClipPath extends Component {
6
+ static defaultProps = {
7
+ tag: 'rect',
8
+ id: '',
9
+ transition: '',
10
+ setAttributeTag: null,
11
+ };
12
+
13
+ refClipPath = React.createRef();
14
+
15
+ componentDidMount() {
16
+ const { id, tag, setAttributeTag } = this.asProps;
17
+ if (!document || !document.querySelector(`#${id}`)) return;
18
+ const svg = document.querySelector(`#${id}`).closest('svg');
19
+ Array.from(svg.querySelectorAll(`[clip-path="url(#${id})"]`)).forEach((node) => {
20
+ node && node.getTotalLength && node.getTotalLength();
21
+ });
22
+ setAttributeTag &&
23
+ Array.from(document.querySelectorAll(`#${id} ${tag}`)).forEach(setAttributeTag);
24
+ }
25
+
26
+ render() {
27
+ const { id, transition, tag: Tag, style, className, ...other } = this.asProps;
28
+ return (
29
+ <clipPath ref={this.refClipPath} id={id}>
30
+ <Tag style={{ ...style, transition }} {...propsForElement(other, Tag)} />
31
+ </clipPath>
32
+ );
33
+ }
34
+ }
35
+
36
+ export default createComponent(ClipPath);