Skip to content

Commit

Permalink
feat: add band area chart (#157)
Browse files Browse the repository at this point in the history
This PR adds a `y0Accessors` prop for each `SeriesSpec`: this property can be used to describe a dataset with bands ( with a min and max value for each data point).
It's mainly used for with `AreaSeries` to describe a bounded area chart, bounded on the y axis. The  `y0` value, is usually a lower value than the `y1`, it will be rendered perpendicularly to the `y1`  point. On a standard area chart, the `y0` value usually correspond to `0` or to the previous value in the stack. In a band-area chart, the `y0` can be any value below the `y1` value.
It can also be applied to bar charts, with some limitations as described below. On a barchart, the `y0` value is the bottom edge of the bar.
On a stacked bar/area chart a series with a `y0Accessor` will be stacked on top of the below series stacking the below series `y1` value with the band series `y0` value. This means that if the below series at a point X has an height of `10`, and the bound series has the following values: `y0: 2, y1: 5` the resulting chart will push the bound series to the top starting using the following values: `y0:12, y1: 15`. The `IndexedGeometry` object is also refactored. To limit amount of redundant code/memory object we used the same `Geometry` elements used on the highlight/hover process.
The structure of `IndexedGeometry` is slightly changed, to avoid duplicate values and to simplify tooltip formatting when rendering either y1 and y0 values.  
I've currently removed from the `indexedGeometries` map all geometry with `null` values on `y1`. This leads to a minor problem: we are not showing any tooltip on that interval, the tooltip of the crosshair is never shown.

close #144
  • Loading branch information
markov00 authored Apr 11, 2019
1 parent 21316d1 commit a9307ef
Show file tree
Hide file tree
Showing 35 changed files with 7,493 additions and 850 deletions.
24 changes: 15 additions & 9 deletions src/components/highlighter.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject, observer } from 'mobx-react';
import React from 'react';
import { isPointGeometry } from '../lib/series/rendering';
import { ChartStore } from '../state/chart_state';

interface HighlighterProps {
Expand All @@ -21,26 +22,31 @@ class HighlighterComponent extends React.Component<HighlighterProps> {
return (
<svg className="elasticChartsHighlighter">
<g transform={`translate(${left}, ${top}) rotate(${chartRotation})`}>
{highlightedGeometries.map((highlightedGeometry, i) => {
const {
color,
geom: { x, y, width, height, isPoint },
} = highlightedGeometry;
if (isPoint) {
{highlightedGeometries.map((geom, i) => {
const { color, x, y } = geom;
if (isPointGeometry(geom)) {
return (
<circle
key={i}
cx={x}
cx={x + geom.transform.x}
cy={y}
r={width}
r={geom.radius}
stroke={color}
strokeWidth={4}
fill="transparent"
/>
);
}
return (
<rect key={i} x={x} y={y} width={width} height={height} fill="white" opacity={0.4} />
<rect
key={i}
x={x}
y={y}
width={geom.width}
height={geom.height}
fill="white"
opacity={0.4}
/>
);
})}
</g>
Expand Down
59 changes: 32 additions & 27 deletions src/components/react_canvas/area_geometries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class AreaGeometries extends React.PureComponent<
return (
<Group ref={this.barSeriesRef} key={'bar_series'}>
{area.visible && this.renderAreaGeoms()}
{line.visible && this.renderAreaLine()}
{line.visible && this.renderAreaLines()}
{point.visible && this.renderAreaPoints()}
</Group>
);
Expand Down Expand Up @@ -132,46 +132,51 @@ export class AreaGeometries extends React.PureComponent<
}
});
}
private renderAreaLine = (): JSX.Element[] => {
private renderAreaLines = (): JSX.Element[] => {
const { areas, sharedStyle } = this.props;
const { strokeWidth } = this.props.style.line;

return areas.map((glyph, i) => {
const { line, color, transform, geometryId } = glyph;
const linesToRender: JSX.Element[] = [];
areas.forEach((glyph, areaIndex) => {
const { lines, color, geometryId } = glyph;

const geometryStyle = getGeometryStyle(
geometryId,
this.props.highlightedLegendItem,
sharedStyle,
);

if (this.props.animated) {
return (
<Group key={`area-line-group-${i}`} x={transform.x}>
<Spring native from={{ line }} to={{ line }}>
{(props: { line: string }) => {
const lineProps = buildAreaLineProps({
index: i,
linePath: props.line,
color,
strokeWidth,
geometryStyle,
});
return <animated.Path {...lineProps} />;
}}
</Spring>
</Group>
);
} else {
lines.forEach((linePath, lineIndex) => {
const lineProps = buildAreaLineProps({
index: i,
linePath: line,
areaIndex,
lineIndex,
linePath,
color,
strokeWidth,
geometryStyle,
});
return <Path {...lineProps} />;
}
linesToRender.push(<Path {...lineProps} />);
});
});
return linesToRender;
// if (this.props.animated) {
// return (
// <Group key={`area-line-group-${i}`} x={transform.x}>
// <Spring native from={{ line }} to={{ line }}>
// {(props: { line: string }) => {
// const lineProps = buildAreaLineProps({
// index: i,
// linePath: props.line,
// color,
// strokeWidth,
// geometryStyle,
// });
// return <animated.Path {...lineProps} />;
// }}
// </Spring>
// </Group>
// );
// } else {

// }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ describe('[canvas] Area Geometries props', () => {
});
test('can build area line path props', () => {
const props = buildAreaLineProps({
index: 1,
areaIndex: 1,
lineIndex: 2,
linePath: 'M0,0L10,10Z',
color: 'red',
strokeWidth: 1,
Expand All @@ -89,7 +90,7 @@ describe('[canvas] Area Geometries props', () => {
},
});
expect(props).toEqual({
key: `area-line-1`,
key: `area-1-line-2`,
data: 'M0,0L10,10Z',
stroke: 'red',
strokeWidth: 1,
Expand Down
8 changes: 5 additions & 3 deletions src/components/react_canvas/utils/rendering_props_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,22 @@ export function buildAreaProps({
}

export function buildAreaLineProps({
index,
areaIndex,
lineIndex,
linePath,
color,
strokeWidth,
geometryStyle,
}: {
index: number;
areaIndex: number;
lineIndex: number;
linePath: string;
color: string;
strokeWidth: number;
geometryStyle: GeometryStyle;
}) {
return {
key: `area-line-${index}`,
key: `area-${areaIndex}-line-${lineIndex}`,
data: linePath,
stroke: color,
strokeWidth,
Expand Down
Loading

0 comments on commit a9307ef

Please sign in to comment.