@@ -310,12 +314,54 @@ export default class Gallery extends React.Component {
-
-
-
- More on the way!
-
-
+
+
+ this.nodes.add(d)}>
+
+
+
+
+
+
+
+
+
+ this.nodes.add(d)}>
+
+
+
+
+
+
+
+
+
+
+
+ More on the way!
+
diff --git a/packages/vx-scale/src/scales/band.js b/packages/vx-scale/src/scales/band.js
index eddb2d5ea..97409f41b 100644
--- a/packages/vx-scale/src/scales/band.js
+++ b/packages/vx-scale/src/scales/band.js
@@ -8,6 +8,7 @@ export default ({
paddingInner,
paddingOuter,
align,
+ tickFormat,
}) => {
const scale = scaleBand();
@@ -18,6 +19,7 @@ export default ({
if (paddingInner) scale.paddingInner(paddingInner);
if (paddingOuter) scale.paddingOuter(paddingOuter);
if (align) scale.align(align);
+ if (tickFormat) scale.tickFormat = tickFormat;
return scale;
}
diff --git a/packages/vx-shape/build/index.js b/packages/vx-shape/build/index.js
index 2ea0e1b04..d8fe3d23e 100644
--- a/packages/vx-shape/build/index.js
+++ b/packages/vx-shape/build/index.js
@@ -49,4 +49,31 @@ Object.defineProperty(exports, 'Bar', {
}
});
+var _BarGroup = require('./shapes/BarGroup');
+
+Object.defineProperty(exports, 'BarGroup', {
+ enumerable: true,
+ get: function get() {
+ return _interopRequireDefault(_BarGroup).default;
+ }
+});
+
+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', {
+ enumerable: true,
+ get: function get() {
+ return _interopRequireDefault(_callOrValue).default;
+ }
+});
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
\ No newline at end of file
diff --git a/packages/vx-shape/package.json b/packages/vx-shape/package.json
index e0a726e29..ce107661f 100644
--- a/packages/vx-shape/package.json
+++ b/packages/vx-shape/package.json
@@ -23,9 +23,11 @@
"license": "MIT",
"dependencies": {
"@vx/curve": "0.0.112",
+ "@vx/group": "0.0.113",
"@vx/point": "0.0.112",
"classnames": "^2.2.5",
"d3-shape": "^1.0.6",
+ "prop-types": "^15.5.10",
"react": "^15.4.2"
},
"devDependencies": {
diff --git a/packages/vx-shape/src/index.js b/packages/vx-shape/src/index.js
index a7564a0d3..f8a30dc56 100644
--- a/packages/vx-shape/src/index.js
+++ b/packages/vx-shape/src/index.js
@@ -3,3 +3,6 @@ export { default as LinePath } from './shapes/LinePath';
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';
diff --git a/packages/vx-shape/src/shapes/AreaStack.js b/packages/vx-shape/src/shapes/AreaStack.js
index f18a5705b..e97474b08 100644
--- a/packages/vx-shape/src/shapes/AreaStack.js
+++ b/packages/vx-shape/src/shapes/AreaStack.js
@@ -1,15 +1,8 @@
import React from 'react';
import cx from 'classnames';
+import callOrValue from '../util/callOrValue';
import { area, stack as d3stack } from 'd3-shape';
-function callOrValue(maybeFn, d, i) {
- if (typeof maybeFn === 'function') {
- return maybeFn(d,i);
- }
- return maybeFn;
-}
-
-
export default ({
className,
top = 0,
diff --git a/packages/vx-shape/src/shapes/Bar.js b/packages/vx-shape/src/shapes/Bar.js
index 27d93edd0..34ab7a75b 100644
--- a/packages/vx-shape/src/shapes/Bar.js
+++ b/packages/vx-shape/src/shapes/Bar.js
@@ -1,8 +1,10 @@
import React from 'react';
import cx from 'classnames';
+import callOrValue from '../util/callOrValue';
export default ({
className,
+ data,
x = 0,
y = 0,
width,
@@ -18,6 +20,7 @@ export default ({
strokeLinejoin,
strokeMiterlimit,
strokeOpacity,
+ ...restProps,
}) => {
return (
{
+ ret[cur] = callOrValue(restProps[cur], data);
+ return ret;
+ }, {})}
/>
);
}
diff --git a/packages/vx-shape/src/shapes/BarGroup.js b/packages/vx-shape/src/shapes/BarGroup.js
new file mode 100644
index 000000000..9c48d3d5f
--- /dev/null
+++ b/packages/vx-shape/src/shapes/BarGroup.js
@@ -0,0 +1,70 @@
+import React from 'react';
+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,
+ x0Scale,
+ x1Scale,
+ yScale,
+ zScale,
+ keys,
+ height,
+ ...restProps
+}) {
+ return (
+
+ {data && data.map((d, i) => {
+ return (
+
+ {keys && keys.map((key, i) => {
+ const value = d[key];
+ return (
+ {
+ ret[cur] = callOrValue(restProps[cur], data);
+ return ret;
+ }, {})}
+ />
+ );
+ })}
+
+ );
+ })}
+
+ );
+}
+
+BarGroup.propTypes = {
+ data: PropTypes.array.isRequired,
+ x0: PropTypes.func.isRequired,
+ x0Scale: PropTypes.func.isRequired,
+ x1Scale: PropTypes.func.isRequired,
+ yScale: PropTypes.func.isRequired,
+ zScale: PropTypes.func.isRequired,
+ keys: PropTypes.array.isRequired,
+ height: PropTypes.number.isRequired,
+ className: PropTypes.string,
+ top: PropTypes.number,
+ left: PropTypes.number,
+};
diff --git a/packages/vx-shape/src/shapes/BarStack.js b/packages/vx-shape/src/shapes/BarStack.js
new file mode 100644
index 000000000..ab9400326
--- /dev/null
+++ b/packages/vx-shape/src/shapes/BarStack.js
@@ -0,0 +1,65 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import cx from 'classnames';
+import { Group } from '@vx/group';
+import Bar from './Bar';
+import { stack as d3stack } from 'd3-shape';
+import callOrValue from '../util/callOrValue';
+
+export default function BarStack({
+ data,
+ className,
+ top,
+ left,
+ x,
+ xScale,
+ yScale,
+ zScale,
+ keys,
+ height,
+ ...restProps
+}) {
+ const series = d3stack().keys(keys)(data);
+ return (
+
+ {series && series.map((s, i) => {
+ return (
+
+ {s.map((d, ii) => {
+ return (
+ {
+ ret[cur] = callOrValue(restProps[cur], data);
+ return ret;
+ }, {})}
+ />
+ );
+ })}
+
+ );
+ })}
+
+ );
+}
+
+BarStack.propTypes = {
+ data: PropTypes.array.isRequired,
+ x: PropTypes.func.isRequired,
+ xScale: PropTypes.func.isRequired,
+ yScale: PropTypes.func.isRequired,
+ zScale: PropTypes.func.isRequired,
+ keys: PropTypes.array.isRequired,
+ className: PropTypes.string,
+ top: PropTypes.number,
+ left: PropTypes.number,
+};
diff --git a/packages/vx-shape/src/util/callOrValue.js b/packages/vx-shape/src/util/callOrValue.js
new file mode 100644
index 000000000..b72965089
--- /dev/null
+++ b/packages/vx-shape/src/util/callOrValue.js
@@ -0,0 +1,6 @@
+export default function callOrValue(maybeFn, d, i) {
+ if (typeof maybeFn === 'function') {
+ return maybeFn(d,i);
+ }
+ return maybeFn;
+}
diff --git a/packages/vx-shape/test/BarGroup.test.js b/packages/vx-shape/test/BarGroup.test.js
new file mode 100644
index 000000000..3666abb22
--- /dev/null
+++ b/packages/vx-shape/test/BarGroup.test.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import { BarGroup } from '../src';
+import { shallow, mount } from 'enzyme';
+
+describe('', () => {
+ beforeEach(() => {
+ global.console.error = jest.fn()
+ })
+
+ test('it should be defined', () => {
+ expect(BarGroup).toBeDefined()
+ })
+
+ test('it should have className .vx-bar-group', () => {
+ const wrapper = shallow()
+ expect(wrapper.prop('className')).toEqual('vx-bar-group')
+ })
+
+ test('it should set className prop', () => {
+ const wrapper = shallow()
+ expect(wrapper.prop('className')).toEqual('vx-bar-group test')
+ })
+
+ test('it should require a data prop', () => {
+ const wrapper = shallow();
+ expect(console.error).toBeCalled()
+ expect(console.error.mock.calls[0][0]).toEqual("Warning: Failed prop type: The prop `data` is marked as required in `BarGroup`, but its value is `undefined`.\n in BarGroup")
+ })
+
+ test('it should set top & left props', () => {
+ const wrapper = shallow()
+ expect(wrapper.prop('top')).toEqual(2)
+ expect(wrapper.prop('left')).toEqual(3)
+ })
+})
diff --git a/packages/vx-shape/test/BarStack.test.js b/packages/vx-shape/test/BarStack.test.js
new file mode 100644
index 000000000..c8662efad
--- /dev/null
+++ b/packages/vx-shape/test/BarStack.test.js
@@ -0,0 +1,60 @@
+import React from 'react';
+import { BarStack } from '../src';
+import { shallow } from 'enzyme';
+
+describe('', () => {
+ test('it should be defined', () => {
+ expect(BarStack).toBeDefined()
+ })
+
+ test('it should have className .vx-bar-stack', () => {
+ const wrapper = shallow(
+ d}
+ xScale={d => d}
+ yScale={d => d}
+ zScale={d => d}
+ keys={[]}
+ />
+ )
+ expect(wrapper.prop('className')).toEqual('vx-bar-stack')
+ })
+
+ test('it should set className prop', () => {
+ const wrapper = shallow(
+ d}
+ xScale={d => d}
+ yScale={d => d}
+ zScale={d => d}
+ keys={[]}
+ />
+ )
+ expect(wrapper.prop('className')).toEqual('vx-bar-stack test')
+ })
+
+ test('it should set top & left props', () => {
+ const wrapper = shallow(
+ d}
+ xScale={d => d}
+ yScale={d => d}
+ zScale={d => d}
+ keys={[]}
+ />
+ )
+ expect(wrapper.prop('top')).toEqual(2)
+ expect(wrapper.prop('left')).toEqual(3)
+ })
+})
\ No newline at end of file