Skip to content

Commit

Permalink
[shape] add BarStack
Browse files Browse the repository at this point in the history
  • Loading branch information
hshoff committed May 22, 2017
1 parent 6d250ea commit 447f479
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/vx-demo/components/tiles/bargroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ export default ({
keys={keys}
height={yMax}
x0={x0}
y={y}
x0Scale={x0Scale}
x1Scale={x1Scale}
yScale={yScale}
zScale={zScale}
rx={4}
/>
<AxisBottom
scale={x0Scale}
Expand Down
95 changes: 95 additions & 0 deletions packages/vx-demo/components/tiles/barstack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from 'react';
import { BarStack } from '@vx/shape';
import { Group } from '@vx/group';
import { AxisBottom } from '@vx/axis';
import { cityTemperature } from '@vx/mock-data';
import { scaleBand, scaleLinear, scaleOrdinal } from '@vx/scale';
import { timeParse, timeFormat } from 'd3-time-format';
import { extent, max } from 'd3-array';

const data = cityTemperature.slice(0, 12);
const keys = Object.keys(data[0]).filter(d => d !== 'date');
const parseDate = timeParse("%Y%m%d");
const format = timeFormat("%b %d");
const formatDate = (date) => format(parseDate(date));

// accessors
const x = d => d.date;
const y = d => d.value;

const totals = data.reduce((ret, cur) => {
const t = keys.reduce((dailyTotal, k) => {
dailyTotal += +cur[k]
return dailyTotal;
}, 0)
ret.push(t)
return ret;
}, [])

export default ({
width,
height,
margin = {
top: 40
}
}) => {
if (width < 10) return null;

// bounds
const xMax = width;
const yMax = height - margin.top - 100;

// // scales
const xScale = scaleBand({
rangeRound: [0, xMax],
domain: data.map(x),
padding: 0.2,
tickFormat: () => (val) => formatDate(val)
});
const yScale = scaleLinear({
rangeRound: [yMax, 0],
nice: true,
domain: [0, max(totals)],
});
const zScale = scaleOrdinal({
domain: keys,
range: ['#6c5efb', '#c998ff', '#a44afe']
})

return (
<svg width={width} height={height}>
<rect
x={0}
y={0}
width={width}
height={height}
fill={`#eaedff`}
rx={14}
/>
<BarStack
top={margin.top}
data={data}
keys={keys}
height={yMax}
x={x}
xScale={xScale}
yScale={yScale}
zScale={zScale}

/>
<AxisBottom
scale={xScale}
top={yMax + margin.top}
stroke='#a44afe'
tickStroke='#a44afe'
tickLabelComponent={(
<text
fill='#a44afe'
fontSize={11}
textAnchor="middle"
/>
)}
/>
</svg>
);
}
105 changes: 105 additions & 0 deletions packages/vx-demo/pages/barstack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react';
import Show from '../components/show';
import BarStack from '../components/tiles/barstack';

export default () => {
return (
<Show margin={{top: 80}} component={BarStack} title="Bar Stack">
{`import React from 'react';
import { BarStack } from '@vx/shape';
import { Group } from '@vx/group';
import { AxisBottom } from '@vx/axis';
import { cityTemperature } from '@vx/mock-data';
import { scaleBand, scaleLinear, scaleOrdinal } from '@vx/scale';
import { timeParse, timeFormat } from 'd3-time-format';
import { extent, max } from 'd3-array';
const data = cityTemperature.slice(0, 12);
const keys = Object.keys(data[0]).filter(d => d !== 'date');
const parseDate = timeParse("%Y%m%d");
const format = timeFormat("%b %d");
const formatDate = (date) => format(parseDate(date));
// accessors
const x = d => d.date;
const y = d => d.value;
const totals = data.reduce((ret, cur) => {
const t = keys.reduce((dailyTotal, k) => {
dailyTotal += +cur[k]
return dailyTotal;
}, 0)
ret.push(t)
return ret;
}, [])
export default ({
width,
height,
margin = {
top: 40
}
}) => {
if (width < 10) return null;
// bounds
const xMax = width;
const yMax = height - margin.top - 100;
// // scales
const xScale = scaleBand({
rangeRound: [0, xMax],
domain: data.map(x),
padding: 0.2,
tickFormat: () => (val) => formatDate(val)
});
const yScale = scaleLinear({
rangeRound: [yMax, 0],
nice: true,
domain: [0, max(totals)],
});
const zScale = scaleOrdinal({
domain: keys,
range: ['#6c5efb', '#c998ff', '#a44afe']
})
return (
<svg width={width} height={height}>
<rect
x={0}
y={0}
width={width}
height={height}
fill='#eaedff'
rx={14}
/>
<BarStack
top={margin.top}
data={data}
keys={keys}
height={yMax}
x={x}
xScale={xScale}
yScale={yScale}
zScale={zScale}
/>
<AxisBottom
scale={xScale}
top={yMax + margin.top}
stroke='#a44afe'
tickStroke='#a44afe'
tickLabelComponent={(
<text
fill='#a44afe'
fontSize={11}
textAnchor="middle"
/>
)}
/>
</svg>
);
}`}
</Show>
);
}
23 changes: 23 additions & 0 deletions packages/vx-demo/pages/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Stacked from '../components/tiles/stacked';
import MultiLine from '../components/tiles/multiline';
import Axis from '../components/tiles/axis';
import BarGroup from '../components/tiles/bargroup';
import BarStack from '../components/tiles/barstack';

const items = [
"#242424",
Expand Down Expand Up @@ -71,6 +72,7 @@ export default class Gallery extends React.Component {
const t8 = this.state.dimensions[7] || [8, 300];
const t9 = this.state.dimensions[8] || [8, 300];
const t10 = this.state.dimensions[9] || [8, 300];
const t11 = this.state.dimensions[10] || [8, 300];

return (
<Page title="gallery">
Expand Down Expand Up @@ -333,6 +335,27 @@ export default class Gallery extends React.Component {
</div>
</Link>
</Tilt>
<Tilt
className="tilt"
options={{ max: 8, scale: 1 }}
>
<Link prefetch href="/barstack">
<div className="gallery-item" style={{ background: '#eaedff' }} ref={d => this.nodes.add(d)}>
<div className="image">
<BarStack
width={t11[0]}
height={t11[1]}
/>
</div>
<div className="details" style={{ color: '#a44afe'}}>
<div className="title">Bar Stack</div>
<div className="description">
<pre>{`<Shape.BarStack />`}</pre>
</div>
</div>
</div>
</Link>
</Tilt>
</div>

<div>
Expand Down
9 changes: 9 additions & 0 deletions packages/vx-shape/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ Object.defineProperty(exports, 'BarGroup', {
}
});

var _BarStack = require('./shapes/BarStack');

Object.defineProperty(exports, 'BarStack', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_BarStack).default;
}
});

var _callOrValue = require('./util/callOrValue');

Object.defineProperty(exports, 'callOrValue', {
Expand Down
1 change: 1 addition & 0 deletions packages/vx-shape/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export { default as AreaClosed } from './shapes/AreaClosed';
export { default as AreaStack } from './shapes/AreaStack';
export { default as Bar } from './shapes/Bar';
export { default as BarGroup } from './shapes/BarGroup';
export { default as BarStack } from './shapes/BarStack';
export { default as callOrValue } from './util/callOrValue';
19 changes: 11 additions & 8 deletions packages/vx-shape/src/shapes/BarGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ import PropTypes from 'prop-types';
import cx from 'classnames';
import { Group } from '@vx/group';
import Bar from './Bar';
import callOrValue from '../util/callOrValue';

export default function BarGroup({
data,
className,
top,
left,
x0,
y,
z,
x0Scale,
x1Scale,
yScale,
zScale,
keys,
height,
...restProps
}) {
return (
<Group
Expand All @@ -41,6 +41,10 @@ export default function BarGroup({
width={x1Scale.bandwidth()}
height={height - yScale(value)}
fill={zScale(key)}
{...Object.keys(restProps).reduce((ret, cur) => {
ret[cur] = callOrValue(restProps[cur], data);
return ret;
}, {})}
/>
);
})}
Expand All @@ -53,15 +57,14 @@ export default function BarGroup({

BarGroup.propTypes = {
data: PropTypes.array.isRequired,
className: PropTypes.string,
top: PropTypes.number,
left: PropTypes.number,
x0: PropTypes.func.isRequired,
y: PropTypes.func.isRequired,
x0Scale: PropTypes.func.isRequired,
x1Scale: PropTypes.func.isRequired,
yScale: PropTypes.func.isRequired,
z: PropTypes.func,
zScale: PropTypes.func,
zScale: PropTypes.func.isRequired,
keys: PropTypes.array.isRequired,
height: PropTypes.number.isRequired,
className: PropTypes.string,
top: PropTypes.number,
left: PropTypes.number,
};
Loading

0 comments on commit 447f479

Please sign in to comment.