Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added stats charts in xy-chart #75

Merged
merged 9 commits into from
Nov 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 270 additions & 0 deletions packages/demo/examples/01-xy-chart/StatsSeriesExample.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/* eslint react/prop-types: 0 */
import React from 'react';

import {
XAxis,
YAxis,
BoxPlotSeries,
ViolinPlotSeries,
PatternLines,
LinearGradient,
theme,
} from '@data-ui/xy-chart';

import ResponsiveXYChart from './ResponsiveXYChart';

import { statsData } from './data';

const { colors } = theme;

function renderViolinPlotTooltip({ datum, color }) {
const { x, y, binData } = datum;
const label = x || y;
return (
<div>
<div>
<strong style={{ color }}>{label}</strong>
</div>
<div>
<strong style={{ color }}>Bin Number </strong>
{binData.length}
</div>
</div>
);
}
function renderBoxPlotTooltip({ datum, color }) {
const {
x,
y,
min,
max,
median,
firstQuartile,
thirdQuartile,
outliers,
} = datum;

const label = x || y;
return (
<div>
<div>
<strong style={{ color }}>{label}</strong>
</div>
<div>
<strong style={{ color }}>Min </strong>
{min && min.toFixed ? min.toFixed(2) : min}
</div>
<div>
<strong style={{ color }}>Max </strong>
{max && max.toFixed ? max.toFixed(2) : max}
</div>
<div>
<strong style={{ color }}>Median </strong>
{median && median.toFixed ? median.toFixed(2) : median}
</div>
<div>
<strong style={{ color }}>First Quartile </strong>
{firstQuartile && firstQuartile.toFixed ? firstQuartile.toFixed(2) : firstQuartile}
</div>
<div>
<strong style={{ color }}>Third Quartile </strong>
{thirdQuartile && thirdQuartile.toFixed ? thirdQuartile.toFixed(2) : thirdQuartile}
</div>
<div>
<strong style={{ color }}>Outliers Number </strong>
{outliers.length}
</div>
</div>
);
}

export function SimpleBoxPlotSeriesExample() {
const boxPlotData = statsData.map(s => s.boxPlot);
const values = boxPlotData.reduce((r, e) => r.push(e.min, e.max, ...e.outliers) && r, []);
const minYValue = Math.min(...values);
const maxYValue = Math.max(...values);
const yDomain = [minYValue - (0.1 * Math.abs(minYValue)),
maxYValue + (0.1 * Math.abs(minYValue))];
return (
<ResponsiveXYChart
theme={{}}
ariaLabel="Required label"
xScale={{
type: 'band',
paddingInner: 0.15,
paddingOuter: 0.3,
}}
yScale={{ type: 'linear',
domain: yDomain,
}}
renderTooltip={renderBoxPlotTooltip}
showYGrid
>
<LinearGradient
id="aqua_lightaqua_gradient"
from="#99e9f2"
to="#c5f6fa"
/>
<YAxis numTicks={4} />
<BoxPlotSeries
data={boxPlotData}
fill="url(#aqua_lightaqua_gradient)"
stroke="#22b8cf"
strokeWidth={1.5}
/>
<XAxis />
</ResponsiveXYChart>
);
}

export function SingleBoxPlotSeriesExample() {
const singleStats = [statsData[0]];
const boxPlotData = singleStats.map((s) => {
const { boxPlot } = s;
const { x, ...rest } = boxPlot;
return {
y: x,
...rest,
};
});
const values = boxPlotData.reduce((r, e) => r.push(e.min, e.max, ...e.outliers) && r, []);
const minXValue = Math.min(...values);
const maxXValue = Math.max(...values);
const xDomain = [minXValue - (0.1 * Math.abs(minXValue)),
maxXValue + (0.1 * Math.abs(maxXValue))];
return (
<ResponsiveXYChart
theme={{}}
ariaLabel="Required label"
yScale={{
type: 'band',
paddingInner: 0.15,
paddingOuter: 0.3,
}}
xScale={{ type: 'linear',
domain: xDomain,
}}
renderTooltip={renderBoxPlotTooltip}
showYGrid
>
<LinearGradient
id="aqua_lightaqua_gradient"
from="#99e9f2"
to="#c5f6fa"
/>
<BoxPlotSeries
data={boxPlotData}
fill="url(#aqua_lightaqua_gradient)"
stroke="#22b8cf"
strokeWidth={1.5}
horizontal
/>
<XAxis />
</ResponsiveXYChart>
);
}

export function HorizontalBoxPlotViolinPlotSeriesExample() {
const boxPlotData = statsData.map((s) => {
const { boxPlot } = s;
const { x, ...rest } = boxPlot;
return {
y: x,
...rest,
};
});
const violinData = statsData.map(s => ({ y: s.boxPlot.x, binData: s.binData }));
const values = boxPlotData.reduce((r, e) => r.push(e.min, e.max, ...e.outliers) && r, []);
const minXValue = Math.min(...values);
const maxXValue = Math.max(...values);
const xDomain = [minXValue - (0.1 * Math.abs(minXValue)),
maxXValue + (0.1 * Math.abs(maxXValue))];
return (
<ResponsiveXYChart
theme={{}}
ariaLabel="Required label"
yScale={{
type: 'band',
paddingInner: 0.15,
paddingOuter: 0.3,
}}
xScale={{ type: 'linear',
domain: xDomain,
}}
renderTooltip={renderBoxPlotTooltip}
showYGrid
>
<PatternLines
id="vViolinLines"
height={3}
width={3}
stroke="#ced4da"
strokeWidth={1}
fill="rgba(0,0,0,0.3)"
/>
<YAxis numTicks={4} />
<ViolinPlotSeries
data={violinData}
fill="url(#vViolinLines)"
stroke="#22b8cf"
strokeWidth={0.5}
horizontal
disableMouseEvents
/>
<BoxPlotSeries
data={boxPlotData}
fill={colors.categories[0]}
stroke={colors.categories[0]}
widthRatio={0.5}
fillOpacity={0.2}
strokeWidth={1}
horizontal
/>
<XAxis />
</ResponsiveXYChart>
);
}

export function ViolinPlotSeriesExample() {
const boxPlotData = statsData.map(s => s.boxPlot);
const violinData = statsData.map(s => ({ x: s.boxPlot.x, binData: s.binData }));
const values = boxPlotData.reduce((r, e) => r.push(e.min, e.max, ...e.outliers) && r, []);
const minYValue = Math.min(...values);
const maxYValue = Math.max(...values);
const yDomain = [minYValue - (0.1 * Math.abs(minYValue)),
maxYValue + (0.1 * Math.abs(minYValue))];
return (
<ResponsiveXYChart
theme={{}}
ariaLabel="Required label"
xScale={{
type: 'band',
paddingInner: 0.15,
paddingOuter: 0.3,
}}
yScale={{ type: 'linear',
domain: yDomain,
}}
renderTooltip={renderViolinPlotTooltip}
showYGrid
>
<PatternLines
id="hViolinLines"
height={3}
width={3}
stroke="#ced4da"
strokeWidth={1}
fill="rgba(0,0,0,0.3)"
orientation={['horizontal']}
/>
<YAxis numTicks={4} />
<ViolinPlotSeries
data={violinData}
fill="url(#hViolinLines)"
stroke="#22b8cf"
strokeWidth={0.5}
/>
<XAxis />
</ResponsiveXYChart>
);
}
4 changes: 3 additions & 1 deletion packages/demo/examples/01-xy-chart/data.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cityTemperature, appleStock, genRandomNormalPoints, letterFrequency } from '@vx/mock-data';
import { cityTemperature, appleStock, genRandomNormalPoints, letterFrequency, genStats } from '@vx/mock-data';
import { theme } from '@data-ui/xy-chart';

export const timeSeriesData = appleStock.filter((d, i) => i % 120 === 0).map(d => ({
Expand Down Expand Up @@ -123,3 +123,5 @@ export const circlePackData = Array(400).fill(null).map((_, i) => ({
fillOpacity: Math.max(0.4, Math.random()),
fill: theme.colors.categories[i % 2 === 0 ? 1 : 3],
}));

export const statsData = genStats(5);
36 changes: 36 additions & 0 deletions packages/demo/examples/01-xy-chart/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
LineSeries,
PointSeries,
StackedBarSeries,
BoxPlotSeries,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this file is getting so big I think it'd be good to start moving the examples into their own files. I did this with <StackedAreaSeries />, could we do that here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good! I moved them out as a separate file

ViolinPlotSeries,

HorizontalReferenceLine,
PatternLines,
Expand All @@ -30,6 +32,12 @@ import RectPointComponent from './RectPointComponent';
import ResponsiveXYChart, { dateFormatter } from './ResponsiveXYChart';
import StackedAreaExample from './StackedAreaExample';
import ScatterWithHistogram from './ScatterWithHistograms';
import {
SimpleBoxPlotSeriesExample,
SingleBoxPlotSeriesExample,
HorizontalBoxPlotViolinPlotSeriesExample,
ViolinPlotSeriesExample,
} from './StatsSeriesExample';

import {
circlePackData,
Expand Down Expand Up @@ -488,6 +496,34 @@ export default {
</ResponsiveXYChart>
),
},
{
description: 'Box Plot Example',
components: [BoxPlotSeries],
example: () => (
<SimpleBoxPlotSeriesExample />
),
},
{
description: 'Single Horizontal Box Plot Example',
components: [BoxPlotSeries],
example: () => (
<SingleBoxPlotSeriesExample />
),
},
{
description: 'Horizontal BoxPlot With ViolinPlot Example',
components: [BoxPlotSeries, ViolinPlotSeries],
example: () => (
<HorizontalBoxPlotViolinPlotSeriesExample />
),
},
{
description: 'ViolinPlot Example',
components: [ViolinPlotSeries],
example: () => (
<ViolinPlotSeriesExample />
),
},
{
description: 'XAxis, YAxis -- orientation',
components: [XAxis, YAxis],
Expand Down
2 changes: 1 addition & 1 deletion packages/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@storybook/addon-options": "^3.1.6",
"@storybook/react": "3.2.12",
"@vx/legend": "0.0.140",
"@vx/mock-data": "0.0.136",
"@vx/mock-data": "0.0.147",
"@vx/responsive": "0.0.140",
"@vx/scale": "0.0.140",
"aphrodite": "^1.2.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/xy-chart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ Series | supported x scale type | supported y scale types | data shape | voronoi
`<GroupedBarSeries/>` | band | linear | `{ x, y }` (colors controlled with groupFills & groupKeys) | no
`<CirclePackSeries/>` | time, linear | y is computed | `{ x [, size] }` | no
`<IntervalSeries/>` | time, linear | linear | `{ x0, x1 [, fill, stroke] }` | no
`<BoxPlotSeries/>` | linear, band | band, linear | `{ x (or y), min, max, median, firstQuartile, thirdQuartile, outliers [, fill, stroke] }` | no
`<ViolinPlotSeries/>` | linear, band | band, linear | `{ x (or y), binData [, fill, stroke] }` | no


\* The y boundaries of the `<AreaSeries/>` may be specified by either
- defined `y0` and `y1` values or
Expand Down
1 change: 1 addition & 0 deletions packages/xy-chart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@vx/responsive": "0.0.140",
"@vx/scale": "0.0.140",
"@vx/shape": "0.0.145",
"@vx/stats": "0.0.147",
"@vx/tooltip": "0.0.140",
"@vx/voronoi": "0.0.140",
"d3-array": "^1.2.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/xy-chart/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export { default as LineSeries } from './series/LineSeries';
export { default as PointSeries, pointComponentPropTypes } from './series/PointSeries';
export { default as StackedAreaSeries } from './series/StackedAreaSeries';
export { default as StackedBarSeries } from './series/StackedBarSeries';
export { default as BoxPlotSeries } from './series/BoxPlotSeries';
export { default as ViolinPlotSeries } from './series/ViolinPlotSeries';
export { computeStats } from '@vx/stats';

export { default as HorizontalReferenceLine } from './annotation/HorizontalReferenceLine';
export { default as CrossHair } from './chart/CrossHair';
Expand Down
Loading