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

[chord][demo] add @vx/chord. fixes #189 #308

Merged
merged 2 commits into from
Jun 13, 2018
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
35 changes: 35 additions & 0 deletions packages/vx-chord/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"presets": [
"stage-0",
"react",
[
"env",
{
"modules": false,
"targets": {
"android": 30,
"chrome": 35,
"edge": 14,
"explorer": 9,
"firefox": 52,
"safari": 8,
"ucandroid": 1
}
}
]
],
"env": {
"test": {
"presets": [
"stage-0",
"react",
[
"env",
{
"modules": "commonjs"
}
]
]
}
}
}
1 change: 1 addition & 0 deletions packages/vx-chord/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
5 changes: 5 additions & 0 deletions packages/vx-chord/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# @vx/chord

```
npm install --save @vx/chord
```
77 changes: 77 additions & 0 deletions packages/vx-chord/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"name": "@vx/chord",
"version": "0.0.1",
"description": "vx group",
"sideEffects": false,
"main": "dist/vx-chord.umd.js",
"module": "dist/vx-chord.es.js",
"scripts": {
"build": "npm run build:babel && npm run build:dist",
"build:dist": "rm -rf dist && mkdir dist && rollup -c",
"build:babel": "rm -rf build && mkdir build && babel src --out-dir build --ignore node_modules/ --presets stage-0,react,env",
"prepublish": "npm run build",
"test": "jest"
},
"files": [
"dist",
"build"
],
"repository": {
"type": "git",
"url": "git+https://github.com/hshoff/vx.git"
},
"keywords": [
"vx",
"react",
"d3",
"visualizations",
"charts",
"svg"
],
"author": "@hshoff",
"license": "MIT",
"bugs": {
"url": "https://github.com/hshoff/vx/issues"
},
"homepage": "https://github.com/hshoff/vx#readme",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-jest": "^21.2.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.2",
"jest": "^21.2.1",
"jest-cli": "^21.2.1",
"raf": "^3.4.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-test-renderer": "^16.0.0",
"rollup": "^0.59.4",
"rollup-plugin-babel": "^3.0.4",
"rollup-plugin-commonjs": "^9.1.3",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^4.0.0"
},
"peerDependencies": {
"react": "^15.0.0-0 || ^16.0.0-0"
},
"dependencies": {
"classnames": "^2.2.6",
"d3-chord": "^1.0.4",
"prop-types": "^15.6.1"
},
"publishConfig": {
"access": "public"
},
"jest": {
"setupFiles": [
"raf/polyfill",
"<rootDir>/test/enzyme-setup.js"
]
}
}
72 changes: 72 additions & 0 deletions packages/vx-chord/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const pkg = require('./package.json');
const resolve = require('rollup-plugin-node-resolve');
const babel = require('rollup-plugin-babel');
const replace = require('rollup-plugin-replace');
const uglify = require('rollup-plugin-uglify').uglify;

const deps = Object.keys({
...pkg.dependencies,
...pkg.peerDependencies
});

const globals = deps.reduce((o, name) => {
if (name.includes('@vx/')) {
o[name] = 'vx';
}
if (name.includes('d3-')) {
o[name] = 'd3';
}
if (name === 'react') {
o[name] = 'React';
}
if (name === 'react-dom') {
o[name] = 'ReactDOM';
}
if (name === 'prop-types') {
o[name] = 'PropTypes';
}
if (name === 'classnames') {
o[name] = 'classNames';
}
return o;
}, {});

export default [
{
input: 'src/index',
external: deps,
plugins: [
resolve(),
babel({
exclude: 'node_modules/**',
plugins: ['external-helpers']
}),
replace({
ENV: JSON.stringify('production')
}),
uglify()
],
output: {
extend: true,
file: pkg.main,
format: 'umd',
globals,
name: 'vx'
}
},
{
input: 'src/index',
external: deps,
plugins: [
resolve(),
babel({
exclude: 'node_modules/**',
plugins: ['external-helpers']
}),
replace({
ENV: JSON.stringify('production')
})
],
output: [{ file: pkg.module, format: 'es' }]
}
];
30 changes: 30 additions & 0 deletions packages/vx-chord/src/Chord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import { chord as d3chord } from 'd3-chord';

Chord.propTypes = {
matrix: PropTypes.array.isRequired,
padAngle: PropTypes.number,
sortGroups: PropTypes.func,
sortSubgroups: PropTypes.func,
sortChords: PropTypes.func,
children: PropTypes.func.isRequired
};

export default function Chord({
matrix,
padAngle,
sortGroups,
sortSubgroups,
sortChords,
children,
...restProps
}) {
const chord = d3chord();
if (padAngle) chord.padAngle(padAngle);
if (sortGroups) chord.sortGroups(sortGroups);
if (sortSubgroups) chord.sortSubgroups(sortSubgroups);
if (sortChords) chord.sortChords(sortChords);
const chords = chord(matrix);
return children({ chords });
}
37 changes: 37 additions & 0 deletions packages/vx-chord/src/Ribbon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { ribbon as d3ribbon } from 'd3-chord';

Ribbon.propTypes = {
chord: PropTypes.object.isRequired,
source: PropTypes.func,
target: PropTypes.func,
radius: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
startAngle: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
endAngle: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
children: PropTypes.func,
className: PropTypes.string
};

export default function Ribbon({
chord,
source,
target,
radius,
startAngle,
endAngle,
children,
className,
...restProps
}) {
const ribbon = d3ribbon();
if (source) ribbon.source(source);
if (target) ribbon.target(target);
if (radius) ribbon.radius(radius);
if (startAngle) ribbon.startAngle(startAngle);
if (endAngle) ribbon.endAngle(endAngle);
const path = ribbon(chord);
if (!!children) return children({ path });
return <path className={cx('vx-ribbon', className)} d={path} {...restProps} />;
}
2 changes: 2 additions & 0 deletions packages/vx-chord/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as Chord } from './Chord';
export { default as Ribbon } from './Ribbon';
26 changes: 26 additions & 0 deletions packages/vx-chord/test/Chord.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { shallow } from 'enzyme';
import { Chord } from '../src';

const matrix = [
[11975, 5871, 8916, 2868],
[1951, 10048, 2060, 6171],
[8010, 16145, 8090, 8045],
[1013, 990, 940, 6907]
];

const ChordWrapper = ({ ...restProps }) => shallow(<Chord {...restProps} />);

describe('<Chord />', () => {
test('it should be defined', () => {
expect(Chord).toBeDefined();
});

test('it should call children as a function with required args', () => {
const children = jest.fn();
ChordWrapper({ children, matrix });
const args = children.mock.calls[0][0];
expect(children.mock.calls.length).toBe(1);
expect(args.chords).toBeDefined();
});
});
31 changes: 31 additions & 0 deletions packages/vx-chord/test/Ribbon.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { shallow } from 'enzyme';
import { Chord, Ribbon } from '../src';

const matrix = [
[11975, 5871, 8916, 2868],
[1951, 10048, 2060, 6171],
[8010, 16145, 8090, 8045],
[1013, 990, 940, 6907]
];

const ChordWrapper = ({ ...restProps }) => shallow(<Chord {...restProps} />);

describe('<Chord />', () => {
test('it should be defined', () => {
expect(Chord).toBeDefined();
});

test('it should call children as a function with required args', () => {
const children = jest.fn();
ChordWrapper({
matrix,
children: ({ chords }) => {
shallow(<Ribbon chord={chords[0]} children={children} />);
}
});
const args = children.mock.calls[0][0];
expect(children.mock.calls.length).toBe(1);
expect(args.path).toBeDefined();
});
});
4 changes: 4 additions & 0 deletions packages/vx-chord/test/enzyme-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });
32 changes: 31 additions & 1 deletion packages/vx-demo/components/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import DragI from '../components/tiles/drag-i';
import DragII from '../components/tiles/drag-ii';
import LinkTypes from '../components/tiles/linkTypes';
import Threshold from '../components/tiles/threshold';
import Chord from '../components/tiles/chord';

const items = [
'#242424',
Expand Down Expand Up @@ -830,7 +831,36 @@ export default class Gallery extends React.Component {
</div>
</Link>
</Tilt>
<div className="gallery-item placeholder" />
<Tilt className="tilt" options={{ max: 8, scale: 1 }}>
<Link prefetch href="/chord">
<div className="gallery-item" style={{ background: '#e4e3d8' }}>
<div className="image">
<ParentSize>
{({ width, height }) => (
<Chord
width={width}
height={height}
centerSize={10}
margin={{
top: 0,
left: 0,
right: 0,
bottom: 30
}}
/>
)}
</ParentSize>
</div>
<div className="details" style={{ color: '#111' }}>
<div className="title">Chords</div>
<div className="description">
<pre>{`<Chord.Chord /> + <Chord.Ribbon />`}</pre>
</div>
</div>
</div>
</Link>
</Tilt>
{false && <div className="gallery-item placeholder" />}
</div>

<div>
Expand Down
Loading