From 6b344bd936a5f519afdaf676d03fa5fef40cd28f Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 8 Nov 2017 23:25:40 -0500 Subject: [PATCH] Add support for step, curve, and line links. Issue #174 --- packages/vx-shape/src/index.js | 15 ++++- .../shapes/link/curve/LinkHorizontalCurve.js | 46 +++++++++++++++ .../src/shapes/link/curve/LinkRadialCurve.js | 56 +++++++++++++++++++ .../shapes/link/curve/LinkVerticalCurve.js | 46 +++++++++++++++ .../{ => link/diagonal}/LinkHorizontal.js | 2 +- .../shapes/{ => link/diagonal}/LinkRadial.js | 9 ++- .../{ => link/diagonal}/LinkVertical.js | 2 +- .../shapes/link/line/LinkHorizontalLine.js | 31 ++++++++++ .../src/shapes/link/line/LinkRadialLine.js | 45 +++++++++++++++ .../src/shapes/link/line/LinkVerticalLine.js | 31 ++++++++++ .../shapes/link/step/LinkHorizontalStep.js | 35 ++++++++++++ .../src/shapes/link/step/LinkRadialStep.js | 50 +++++++++++++++++ .../src/shapes/link/step/LinkVerticalStep.js | 35 ++++++++++++ 13 files changed, 397 insertions(+), 6 deletions(-) create mode 100644 packages/vx-shape/src/shapes/link/curve/LinkHorizontalCurve.js create mode 100644 packages/vx-shape/src/shapes/link/curve/LinkRadialCurve.js create mode 100644 packages/vx-shape/src/shapes/link/curve/LinkVerticalCurve.js rename packages/vx-shape/src/shapes/{ => link/diagonal}/LinkHorizontal.js (90%) rename packages/vx-shape/src/shapes/{ => link/diagonal}/LinkRadial.js (69%) rename packages/vx-shape/src/shapes/{ => link/diagonal}/LinkVertical.js (89%) create mode 100644 packages/vx-shape/src/shapes/link/line/LinkHorizontalLine.js create mode 100644 packages/vx-shape/src/shapes/link/line/LinkRadialLine.js create mode 100644 packages/vx-shape/src/shapes/link/line/LinkVerticalLine.js create mode 100644 packages/vx-shape/src/shapes/link/step/LinkHorizontalStep.js create mode 100644 packages/vx-shape/src/shapes/link/step/LinkRadialStep.js create mode 100644 packages/vx-shape/src/shapes/link/step/LinkVerticalStep.js diff --git a/packages/vx-shape/src/index.js b/packages/vx-shape/src/index.js index ccf71594d..ed6b03692 100644 --- a/packages/vx-shape/src/index.js +++ b/packages/vx-shape/src/index.js @@ -3,9 +3,18 @@ export { default as Pie } from './shapes/Pie'; export { default as Line } from './shapes/Line'; export { default as LinePath } from './shapes/LinePath'; export { default as LineRadial } from './shapes/LineRadial'; -export { default as LinkHorizontal } from './shapes/LinkHorizontal'; -export { default as LinkVertical } from './shapes/LinkVertical'; -export { default as LinkRadial } from './shapes/LinkRadial'; +export { default as LinkHorizontal } from './shapes/link/diagonal/LinkHorizontal'; +export { default as LinkVertical } from './shapes/link/diagonal/LinkVertical'; +export { default as LinkRadial } from './shapes/link/diagonal/LinkRadial'; +export { default as LinkHorizontalCurve } from './shapes/link/curve/LinkHorizontalCurve'; +export { default as LinkVerticalCurve } from './shapes/link/curve/LinkVerticalCurve'; +export { default as LinkRadialCurve } from './shapes/link/curve/LinkRadialCurve'; +export { default as LinkHorizontalLine } from './shapes/link/line/LinkHorizontalLine'; +export { default as LinkVerticalLine } from './shapes/link/line/LinkVerticalLine'; +export { default as LinkRadialLine } from './shapes/link/line/LinkRadialLine'; +export { default as LinkHorizontalStep } from './shapes/link/step/LinkHorizontalStep'; +export { default as LinkVerticalStep } from './shapes/link/step/LinkVerticalStep'; +export { default as LinkRadialStep } from './shapes/link/step/LinkRadialStep'; export { default as Area } from './shapes/Area'; export { default as AreaClosed } from './shapes/AreaClosed'; export { default as AreaStack } from './shapes/AreaStack'; diff --git a/packages/vx-shape/src/shapes/link/curve/LinkHorizontalCurve.js b/packages/vx-shape/src/shapes/link/curve/LinkHorizontalCurve.js new file mode 100644 index 000000000..70a3735a4 --- /dev/null +++ b/packages/vx-shape/src/shapes/link/curve/LinkHorizontalCurve.js @@ -0,0 +1,46 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import { pointRadial } from 'd3-shape'; +import additionalProps from '../../../util/additionalProps'; + +LinkHorizontalCurve.propTypes = { + innerRef: PropTypes.func +}; + +export default function LinkHorizontalCurve({ + className, + innerRef, + data, + x = d => d.y, + y = d => d.x, + ...restProps +}) { + + const curve = (source, target) => { + const sx = x(source); + const sy = y(source); + const tx = x(target); + const ty = y(target); + + const dx = tx - sx; + const dy = ty - sy; + const ix = 0.2 * (dx + dy); + const iy = 0.2 * (dy - dx); + + return `M${sx},${sy} + C${sx + ix},${sy + iy} + ${tx + iy},${ty - ix} + ${tx},${ty} + `; + }; + + return ( + + ); +} \ No newline at end of file diff --git a/packages/vx-shape/src/shapes/link/curve/LinkRadialCurve.js b/packages/vx-shape/src/shapes/link/curve/LinkRadialCurve.js new file mode 100644 index 000000000..a2cbb23af --- /dev/null +++ b/packages/vx-shape/src/shapes/link/curve/LinkRadialCurve.js @@ -0,0 +1,56 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import { pointRadial } from 'd3-shape'; +import additionalProps from '../../../util/additionalProps'; + +LinkRadialCurve.propTypes = { + innerRef: PropTypes.func +}; + +export default function LinkRadialCurve({ + className, + innerRef, + data, + x = d => d.x, + y = d => d.y, + ...restProps +}) { + + const curve = (source, target) => { + const sa = x(source) - Math.PI / 2; + const sr = y(source); + const ta = x(target) - Math.PI / 2; + const tr = y(target); + + const sc = Math.cos(sa); + const ss = Math.sin(sa); + const tc = Math.cos(ta); + const ts = Math.sin(ta); + + const sx = sr * sc; + const sy = sr * ss; + const tx = tr * tc; + const ty = tr * ts; + + const dx = tx - sx; + const dy = ty - sy; + const ix = 0.2 * (dx + dy); + const iy = 0.2 * (dy - dx); + + return `M${sx},${sy} + C${sx + ix},${sy + iy} + ${tx + iy},${ty - ix} + ${tx},${ty} + `; + }; + + return ( + + ); +} \ No newline at end of file diff --git a/packages/vx-shape/src/shapes/link/curve/LinkVerticalCurve.js b/packages/vx-shape/src/shapes/link/curve/LinkVerticalCurve.js new file mode 100644 index 000000000..a6cf7b231 --- /dev/null +++ b/packages/vx-shape/src/shapes/link/curve/LinkVerticalCurve.js @@ -0,0 +1,46 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import { pointRadial } from 'd3-shape'; +import additionalProps from '../../../util/additionalProps'; + +LinkVerticalCurve.propTypes = { + innerRef: PropTypes.func +}; + +export default function LinkVerticalCurve({ + className, + innerRef, + data, + x = d => d.x, + y = d => d.y, + ...restProps +}) { + + const curve = (source, target) => { + const sx = x(source); + const sy = y(source); + const tx = x(target); + const ty = y(target); + + const dx = tx - sx; + const dy = ty - sy; + const ix = 0.2 * (dx + dy); + const iy = 0.2 * (dy - dx); + + return `M${sx},${sy} + C${sx + ix},${sy + iy} + ${tx + iy},${ty - ix} + ${tx},${ty} + `; + }; + + return ( + + ); +} \ No newline at end of file diff --git a/packages/vx-shape/src/shapes/LinkHorizontal.js b/packages/vx-shape/src/shapes/link/diagonal/LinkHorizontal.js similarity index 90% rename from packages/vx-shape/src/shapes/LinkHorizontal.js rename to packages/vx-shape/src/shapes/link/diagonal/LinkHorizontal.js index 8c5cc86aa..32aecd4a0 100644 --- a/packages/vx-shape/src/shapes/LinkHorizontal.js +++ b/packages/vx-shape/src/shapes/link/diagonal/LinkHorizontal.js @@ -2,7 +2,7 @@ import React from 'react'; import cx from 'classnames'; import PropTypes from 'prop-types'; import { linkHorizontal } from 'd3-shape'; -import additionalProps from '../util/additionalProps'; +import additionalProps from '../../../util/additionalProps'; LinkHorizontal.propTypes = { innerRef: PropTypes.func, diff --git a/packages/vx-shape/src/shapes/LinkRadial.js b/packages/vx-shape/src/shapes/link/diagonal/LinkRadial.js similarity index 69% rename from packages/vx-shape/src/shapes/LinkRadial.js rename to packages/vx-shape/src/shapes/link/diagonal/LinkRadial.js index 794cb4153..14535f64a 100644 --- a/packages/vx-shape/src/shapes/LinkRadial.js +++ b/packages/vx-shape/src/shapes/link/diagonal/LinkRadial.js @@ -1,10 +1,16 @@ import React from 'react'; import cx from 'classnames'; +import PropTypes from 'prop-types'; import { linkRadial } from 'd3-shape'; -import additionalProps from '../util/additionalProps'; +import additionalProps from '../../../util/additionalProps'; + +LinkRadial.propTypes = { + innerRef: PropTypes.func, +}; export default function LinkRadial({ className, + innerRef, data, angle = d => d.x, radius = d => d.y, @@ -15,6 +21,7 @@ export default function LinkRadial({ link.radius(radius); return ( d.y, + y = d => d.x, + ...restProps +}) { + const line = (source, target) => ` + M${x(source)},${y(source)} + L${x(target)},${y(target)} + `; + + return ( + + ); +} diff --git a/packages/vx-shape/src/shapes/link/line/LinkRadialLine.js b/packages/vx-shape/src/shapes/link/line/LinkRadialLine.js new file mode 100644 index 000000000..bfe907ffc --- /dev/null +++ b/packages/vx-shape/src/shapes/link/line/LinkRadialLine.js @@ -0,0 +1,45 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import { pointRadial } from 'd3-shape'; +import additionalProps from '../../../util/additionalProps'; + +LinkRadialStep.propTypes = { + innerRef: PropTypes.func +}; + +export default function LinkRadialStep({ + className, + innerRef, + data, + x = d => d.x, + y = d => d.y, + ...restProps +}) { + + const line = (source, target) => { + const sa = x(source) - Math.PI / 2; + const sr = y(source); + const ta = x(target) - Math.PI / 2; + const tr = y(target); + + const sc = Math.cos(sa); + const ss = Math.sin(sa); + const tc = Math.cos(ta); + const ts = Math.sin(ta); + + return ` + M${sr * sc},${sr * ss} + L${tr * tc},${tr * ts} + `; + }; + + return ( + + ); +} \ No newline at end of file diff --git a/packages/vx-shape/src/shapes/link/line/LinkVerticalLine.js b/packages/vx-shape/src/shapes/link/line/LinkVerticalLine.js new file mode 100644 index 000000000..100dd8a0d --- /dev/null +++ b/packages/vx-shape/src/shapes/link/line/LinkVerticalLine.js @@ -0,0 +1,31 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import additionalProps from '../../../util/additionalProps'; + +LinkVerticalLine.propTypes = { + innerRef: PropTypes.func +}; + +export default function LinkVerticalLine({ + className, + innerRef, + data, + x = d => d.x, + y = d => d.y, + ...restProps +}) { + const line = (source, target) => ` + M${x(source)},${y(source)} + L${x(target)},${y(target)} + `; + + return ( + + ); +} diff --git a/packages/vx-shape/src/shapes/link/step/LinkHorizontalStep.js b/packages/vx-shape/src/shapes/link/step/LinkHorizontalStep.js new file mode 100644 index 000000000..167a4238f --- /dev/null +++ b/packages/vx-shape/src/shapes/link/step/LinkHorizontalStep.js @@ -0,0 +1,35 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import additionalProps from '../../../util/additionalProps'; + +LinkHorizontalStep.propTypes = { + innerRef: PropTypes.func, + percent: PropTypes.number +}; + +export default function LinkHorizontalStep({ + className, + innerRef, + data, + percent = 0.5, + x = d => d.y, + y = d => d.x, + ...restProps +}) { + const line = (source, target) => ` + M${x(source)},${y(source)} + H${x(source) + (x(target) - x(source)) * percent} + V${y(target)} + H${x(target)} + `; + + return ( + + ); +} \ No newline at end of file diff --git a/packages/vx-shape/src/shapes/link/step/LinkRadialStep.js b/packages/vx-shape/src/shapes/link/step/LinkRadialStep.js new file mode 100644 index 000000000..48ecd903c --- /dev/null +++ b/packages/vx-shape/src/shapes/link/step/LinkRadialStep.js @@ -0,0 +1,50 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import { pointRadial } from 'd3-shape'; +import additionalProps from '../../../util/additionalProps'; + +LinkRadialStep.propTypes = { + innerRef: PropTypes.func +}; + +export default function LinkRadialStep({ + className, + innerRef, + data, + x = d => d.x, + y = d => d.y, + ...restProps +}) { + + const step = (source, target) => { + const sa = x(source) - Math.PI / 2; + const sr = y(source); + const ta = x(target) - Math.PI / 2; + const tr = y(target); + + const sc = Math.cos(sa); + const ss = Math.sin(sa); + const tc = Math.cos(ta); + const ts = Math.sin(ta); + const sf = Math.abs(ta - sa) > Math.PI ? ta <= sa : ta > sa; + + return ` + M${sr * sc},${sr * ss} + A${sr},${sr} 0 0,${sf ? 1 : 0} + ${sr * tc},${sr * ts} + L${tr * tc},${tr * ts} + `; + }; + + const line = step; + + return ( + + ); +} \ No newline at end of file diff --git a/packages/vx-shape/src/shapes/link/step/LinkVerticalStep.js b/packages/vx-shape/src/shapes/link/step/LinkVerticalStep.js new file mode 100644 index 000000000..4c8aea3ad --- /dev/null +++ b/packages/vx-shape/src/shapes/link/step/LinkVerticalStep.js @@ -0,0 +1,35 @@ +import React from 'react'; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import additionalProps from '../../../util/additionalProps'; + +LinkVerticalStep.propTypes = { + innerRef: PropTypes.func, + percent: PropTypes.number, +}; + +export default function LinkVerticalStep({ + className, + innerRef, + data, + percent = 0.5, + x = d => d.x, + y = d => d.y, + ...restProps +}) { + const line = (source, target) => ` + M${x(source)},${y(source)} + V${y(source) + (y(target) - y(source)) * percent} + H${x(target)} + V${y(target)} + `; + + return ( + + ); +}