Skip to content

Commit

Permalink
Fix stacking together different series types (#1037) (#1145)
Browse files Browse the repository at this point in the history
* Fix stacking together different series types (#1037)

* fix test issue

* Adding stacked labels example to showcase

* Fix showcase graph nits
  • Loading branch information
talc23 authored and mcnuttandrew committed Apr 14, 2019
1 parent e05efad commit 67c86e2
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 3 deletions.
2 changes: 2 additions & 0 deletions showcase/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import BarChart from './plot/bar-chart';
import BigBaseBarChart from './plot/big-base-bar-chart';
import DifferenceChart from './plot/difference-chart';
import StackedVerticalBarChart from './plot/stacked-vertical-bar-chart';
import LabeledStackedVerticalBarChart from './plot/labeled-stacked-vertical-bar-chart';
import StackedHorizontalBarChart from './plot/stacked-horizontal-bar-chart';
import ClusteredStackedVerticalBarChart from './plot/clustered-stacked-bar-chart';
import StackedHistogram from './plot/stacked-histogram';
Expand Down Expand Up @@ -175,6 +176,7 @@ const mainShowCase = {
BigBaseBarChart,
DifferenceChart,
StackedVerticalBarChart,
LabeledStackedVerticalBarChart,
MixedStackedChart,
StackedHorizontalBarChart,
ClusteredStackedVerticalBarChart,
Expand Down
67 changes: 67 additions & 0 deletions showcase/plot/labeled-stacked-vertical-bar-chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2016 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import React from 'react';
import ShowcaseButton from '../showcase-components/showcase-button';
import {
XYPlot,
XAxis,
YAxis,
VerticalGridLines,
HorizontalGridLines,
VerticalBarSeries,
VerticalBarSeriesCanvas,
LabelSeries
} from 'index';

export default class Example extends React.Component {
state = {
useCanvas: false
};
render() {
const {useCanvas} = this.state;
const BarSeries = useCanvas ? VerticalBarSeriesCanvas : VerticalBarSeries;
const content = useCanvas ? 'TOGGLE TO SVG' : 'TOGGLE TO CANVAS';
const data = [[{x: 1, y: 8}, {x: 3, y: 5}, {x: 4, y: 15}],
[{x: 3, y: 9}, {x: 4, y: 2}, {x: 5, y: 7}],
[{x: 2, y: 11}, {x: 3, y: 7}, {x: 4, y: 9}]];
const labelsData = data.map(value => value.map(tuple => ({x: tuple.x, y: tuple.y, label: tuple.y.toString()})))

const bars = data.map((value, index) => <BarSeries data={value} key={index} />)
const labels = labelsData.map((value, index) => <LabelSeries data={value} key={index} labelAnchorY='hanging' style={{fill: '#ff8c00'}}/>)

return (
<div>
<ShowcaseButton
onClick={() => this.setState({useCanvas: !useCanvas})}
buttonContent={content}
/>
<XYPlot width={300} height={300} stackBy='y'>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis />
<YAxis />
{bars}
{labels}
</XYPlot>
</div>
);
}
}
6 changes: 6 additions & 0 deletions showcase/showcase-sections/plots-showcase.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const {
LineMarkChart,
MixedStackedChart,
StackedVerticalBarChart,
LabeledStackedVerticalBarChart,
StackedHorizontalBarChart,
StackedHistogram,
ScatterplotChart,
Expand Down Expand Up @@ -148,6 +149,11 @@ const PLOTS = [
component: StackedVerticalBarChart,
componentName: 'StackedVerticalBarChart'
},
{
name: 'Labeled Stacked Vertical Bar Series',
component: LabeledStackedVerticalBarChart,
componentName: 'LabeledStackedVerticalBarChart'
},
{
name: 'Mixed Stacked Series',
component: MixedStackedChart
Expand Down
10 changes: 7 additions & 3 deletions src/utils/series-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export function getStackedData(children, attr) {
accumulator.push(null);
return accumulator;
}
const seriesType = series.type.displayName;

const {data, cluster = 'default', stack} = series.props;
const preppedData = prepareData(data, attr);
Expand All @@ -143,11 +144,14 @@ export function getStackedData(children, attr) {
if (!latestAttrPositions[cluster]) {
latestAttrPositions[cluster] = {};
}
if (!latestAttrPositions[cluster][seriesType]){
latestAttrPositions[cluster][seriesType] = {};
}

const prevD = latestAttrPositions[cluster][d[baseAttr]];
const prevD = latestAttrPositions[cluster][seriesType][d[baseAttr]];
// It is the first segment of a bar.
if (!prevD) {
latestAttrPositions[cluster][d[baseAttr]] = {
latestAttrPositions[cluster][seriesType][d[baseAttr]] = {
[attr0]: d[attr0],
[attr]: d[attr]
};
Expand All @@ -162,7 +166,7 @@ export function getStackedData(children, attr) {
[attr]: prevD[attr] + d[attr] - (d[attr0] || 0)
};

latestAttrPositions[cluster][d[baseAttr]] = {
latestAttrPositions[cluster][seriesType][d[baseAttr]] = {
[attr0]: nextD[attr0],
[attr]: nextD[attr]
};
Expand Down
11 changes: 11 additions & 0 deletions tests/components/label-series-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {mount} from 'enzyme';
import LabelSeries from 'plot/series/label-series';
import {testRenderWithProps, GENERIC_XYPLOT_SERIES_PROPS} from '../test-utils';
import LabelSeriesExample from '../../showcase/misc/label-series-example';
import LabeledStackedVerticalBarChart from '../../showcase/plot/labeled-stacked-vertical-bar-chart';

testRenderWithProps(LabelSeries, GENERIC_XYPLOT_SERIES_PROPS);

Expand Down Expand Up @@ -34,3 +35,13 @@ test('LabelSeries: Showcase Example - LabelSeriesExample', t => {
);
t.end();
});

test('BarSeries: Showcase Example - LabeledStackedVerticalBarChart', t => {
const $ = mount(<LabeledStackedVerticalBarChart />);
t.equal(
$.find('.rv-xy-plot__series--label text').length,
9,
'should find the right number of labels'
);
t.end();
});
19 changes: 19 additions & 0 deletions tests/utils/series-utils-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import LineSeries from 'plot/series/line-series';
import XAxis from 'plot/axis/x-axis';
import HorizontalBarSeries from 'plot/series/horizontal-rect-series';
import VerticalBarSeries from 'plot/series/vertical-rect-series';
import LabelSeries from 'plot/series/label-series';

test('series-utils #isSeriesChild', t => {
const series = <LineSeries data={[]} />;
Expand Down Expand Up @@ -279,5 +280,23 @@ test('series-utils #getStackedData', t => {
'should find the correct results for stacking bar clusters by y with a non stacked line'
);

children = [
<VerticalBarSeries data={xData[0]} />,
<VerticalBarSeries data={xData[1]} />,
<LabelSeries data={xData[0]} />,
<LabelSeries data={xData[1]} />
];
results = getStackedData(children, 'y');
expectedResults = [
...stackByYExpected.slice(0, 2),
...stackByYExpected.slice(0, 2),
];

t.deepEqual(
results,
expectedResults,
'should find the correct results for stacking by x, where different series types are calculated separately'
);

t.end();
});

0 comments on commit 67c86e2

Please sign in to comment.