Skip to content

Commit c780d98

Browse files
feat: allow individual series styling (#170)
1 parent c53dc4d commit c780d98

File tree

11 files changed

+794
-115
lines changed

11 files changed

+794
-115
lines changed

src/components/react_canvas/area_geometries.tsx

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
buildAreaLineProps,
1010
buildAreaPointProps,
1111
buildAreaProps,
12+
buildPointStyleProps,
1213
} from './utils/rendering_props_utils';
1314

1415
interface AreaGeometriesDataProps {
@@ -24,7 +25,7 @@ interface AreaGeometriesDataState {
2425
export class AreaGeometries extends React.PureComponent<
2526
AreaGeometriesDataProps,
2627
AreaGeometriesDataState
27-
> {
28+
> {
2829
static defaultProps: Partial<AreaGeometriesDataProps> = {
2930
animated: false,
3031
};
@@ -41,29 +42,47 @@ export class AreaGeometries extends React.PureComponent<
4142

4243
return (
4344
<Group ref={this.barSeriesRef} key={'bar_series'}>
44-
{area.visible && this.renderAreaGeoms()}
45-
{line.visible && this.renderAreaLines()}
46-
{point.visible && this.renderAreaPoints()}
45+
{this.renderAreaGeoms(area.visible)}
46+
{this.renderAreaLines(line.visible)}
47+
{this.renderAreaPoints(point.visible)}
4748
</Group>
4849
);
4950
}
50-
private renderAreaPoints = (): JSX.Element[] => {
51+
private renderAreaPoints = (themeIsVisible: boolean): JSX.Element[] => {
5152
const { areas } = this.props;
5253
return areas.reduce(
5354
(acc, glyph, i) => {
54-
const { points } = glyph;
55-
return [...acc, ...this.renderPoints(points, i)];
55+
const { points, seriesPointStyle } = glyph;
56+
57+
const isVisible = seriesPointStyle ? seriesPointStyle.visible : themeIsVisible;
58+
if (!isVisible) {
59+
return acc;
60+
}
61+
62+
const { radius, strokeWidth, opacity } = this.props.style.point;
63+
const pointStyleProps = buildPointStyleProps({
64+
radius,
65+
strokeWidth,
66+
opacity,
67+
seriesPointStyle,
68+
});
69+
70+
return [...acc, ...this.renderPoints(points, i, pointStyleProps)];
5671
},
5772
[] as JSX.Element[],
5873
);
5974
}
60-
private renderPoints = (areaPoints: PointGeometry[], areaIndex: number): JSX.Element[] => {
61-
const { radius, strokeWidth, opacity } = this.props.style.point;
62-
63-
return areaPoints.map((areaPoint, pointIndex) => {
75+
private renderPoints = (
76+
areaPoints: PointGeometry[],
77+
areaIndex: number,
78+
pointStyleProps: any,
79+
): JSX.Element[] => {
80+
const areaPointElements: JSX.Element[] = [];
81+
areaPoints.forEach((areaPoint, pointIndex) => {
6482
const { x, y, color, transform } = areaPoint;
83+
6584
if (this.props.animated) {
66-
return (
85+
areaPointElements.push(
6786
<Group key={`area-point-group-${areaIndex}-${pointIndex}`} x={transform.x}>
6887
<Spring native from={{ y }} to={{ y }}>
6988
{(props: { y: number }) => {
@@ -72,41 +91,42 @@ export class AreaGeometries extends React.PureComponent<
7291
pointIndex,
7392
x,
7493
y,
75-
radius,
76-
strokeWidth,
7794
color,
78-
opacity,
95+
pointStyleProps,
7996
});
8097
return <animated.Circle {...pointProps} />;
8198
}}
8299
</Spring>
83-
</Group>
84-
);
100+
</Group>);
85101
} else {
86102
const pointProps = buildAreaPointProps({
87103
areaIndex,
88104
pointIndex,
89105
x: transform.x + x,
90106
y,
91-
radius,
92-
strokeWidth,
93107
color,
94-
opacity,
108+
pointStyleProps,
95109
});
96-
return <Circle {...pointProps} />;
110+
areaPointElements.push(<Circle {...pointProps} />);
97111
}
98112
});
113+
return areaPointElements;
99114
}
100115

101-
private renderAreaGeoms = (): JSX.Element[] => {
116+
private renderAreaGeoms = (themeIsVisible: boolean): JSX.Element[] => {
102117
const { areas } = this.props;
103118
const { opacity } = this.props.style.area;
119+
const areasToRender: JSX.Element[] = [];
104120

105-
return areas.map((glyph, i) => {
106-
const { area, color, transform } = glyph;
121+
areas.forEach((glyph, i) => {
122+
const { area, color, transform, seriesAreaStyle } = glyph;
123+
const isVisible = seriesAreaStyle ? seriesAreaStyle.visible : themeIsVisible;
124+
if (!isVisible) {
125+
return;
126+
}
107127

108128
if (this.props.animated) {
109-
return (
129+
areasToRender.push(
110130
<Group key={`area-group-${i}`} x={transform.x}>
111131
<Spring native from={{ area }} to={{ area }}>
112132
{(props: { area: string }) => {
@@ -115,34 +135,43 @@ export class AreaGeometries extends React.PureComponent<
115135
areaPath: props.area,
116136
color,
117137
opacity,
138+
seriesAreaStyle,
118139
});
119140
return <animated.Path {...areaProps} />;
120141
}}
121142
</Spring>
122-
</Group>
123-
);
143+
</Group>);
124144
} else {
125145
const areaProps = buildAreaProps({
126146
index: i,
127147
areaPath: area,
128148
color,
129149
opacity,
150+
seriesAreaStyle,
130151
});
131-
return <Path {...areaProps} />;
152+
areasToRender.push(<Path {...areaProps} />);
132153
}
133154
});
155+
return areasToRender;
134156
}
135-
private renderAreaLines = (): JSX.Element[] => {
157+
private renderAreaLines = (themeIsVisible: boolean): JSX.Element[] => {
136158
const { areas, sharedStyle } = this.props;
137159
const { strokeWidth } = this.props.style.line;
138160
const linesToRender: JSX.Element[] = [];
139161
areas.forEach((glyph, areaIndex) => {
140-
const { lines, color, geometryId } = glyph;
162+
const { lines, color, geometryId, seriesAreaLineStyle } = glyph;
163+
const isVisible = seriesAreaLineStyle ? seriesAreaLineStyle.visible : themeIsVisible;
164+
if (!isVisible) {
165+
return;
166+
}
167+
168+
const customOpacity = seriesAreaLineStyle ? seriesAreaLineStyle.opacity : undefined;
141169

142170
const geometryStyle = getGeometryStyle(
143171
geometryId,
144172
this.props.highlightedLegendItem,
145173
sharedStyle,
174+
customOpacity,
146175
);
147176

148177
lines.forEach((linePath, lineIndex) => {
@@ -153,6 +182,7 @@ export class AreaGeometries extends React.PureComponent<
153182
color,
154183
strokeWidth,
155184
geometryStyle,
185+
seriesAreaLineStyle,
156186
});
157187
linesToRender.push(<Path {...lineProps} />);
158188
});

src/components/react_canvas/bar_geometries.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface BarGeometriesDataState {
2020
export class BarGeometries extends React.PureComponent<
2121
BarGeometriesDataProps,
2222
BarGeometriesDataState
23-
> {
23+
> {
2424
static defaultProps: Partial<BarGeometriesDataProps> = {
2525
animated: false,
2626
};
@@ -44,11 +44,13 @@ export class BarGeometries extends React.PureComponent<
4444
private renderBarGeoms = (bars: BarGeometry[]): JSX.Element[] => {
4545
const { overBar } = this.state;
4646
const {
47-
style: { border },
47+
style,
4848
sharedStyle,
4949
} = this.props;
5050
return bars.map((bar, index) => {
51-
const { x, y, width, height, color } = bar;
51+
const { x, y, width, height, color, seriesStyle } = bar;
52+
const border = seriesStyle ? seriesStyle.border : style.border;
53+
const customOpacity = seriesStyle ? seriesStyle.opacity : undefined;
5254

5355
// Properties to determine if we need to highlight individual bars depending on hover state
5456
const hasGeometryHover = overBar != null;
@@ -62,6 +64,7 @@ export class BarGeometries extends React.PureComponent<
6264
bar.geometryId,
6365
this.props.highlightedLegendItem,
6466
sharedStyle,
67+
customOpacity,
6568
individualHighlight,
6669
);
6770

0 commit comments

Comments
 (0)