From e12cdf15d326c2989b277d90b63ff7af478e9d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Benitte?= Date: Sun, 24 Mar 2019 02:10:25 +0900 Subject: [PATCH] feat(sankey): adjust labels for vertical layout --- packages/sankey/src/Sankey.js | 2 + packages/sankey/src/SankeyLabels.js | 59 +++++++++++++------ packages/sankey/src/SankeyLinks.js | 52 +--------------- packages/sankey/src/enhance.js | 2 +- packages/sankey/src/links.js | 59 +++++++++++++++++++ .../src/components/charts/sankey/Sankey.js | 2 +- website/src/components/charts/sankey/props.js | 4 +- 7 files changed, 106 insertions(+), 74 deletions(-) create mode 100644 packages/sankey/src/links.js diff --git a/packages/sankey/src/Sankey.js b/packages/sankey/src/Sankey.js index 277a432c3..e73acbcfe 100644 --- a/packages/sankey/src/Sankey.js +++ b/packages/sankey/src/Sankey.js @@ -145,7 +145,9 @@ const Sankey = ({ {enableLabels && ( { let x + let y let textAnchor - if (node.x < width / 2) { - if (labelPosition === 'inside') { - x = node.x1 + labelPadding - textAnchor = labelOrientation === 'vertical' ? 'middle' : 'start' + if (layout === 'horizontal') { + y = node.y + node.height / 2 + if (node.x < width / 2) { + if (labelPosition === 'inside') { + x = node.x1 + labelPadding + textAnchor = labelOrientation === 'vertical' ? 'middle' : 'start' + } else { + x = node.x - labelPadding + textAnchor = labelOrientation === 'vertical' ? 'middle' : 'end' + } } else { - x = node.x - labelPadding - textAnchor = labelOrientation === 'vertical' ? 'middle' : 'end' + if (labelPosition === 'inside') { + x = node.x - labelPadding + textAnchor = labelOrientation === 'vertical' ? 'middle' : 'end' + } else { + x = node.x1 + labelPadding + textAnchor = labelOrientation === 'vertical' ? 'middle' : 'start' + } } - } else { - if (labelPosition === 'inside') { - x = node.x - labelPadding - textAnchor = labelOrientation === 'vertical' ? 'middle' : 'end' + } else if (layout === 'vertical') { + x = node.x + node.width / 2 + if (node.y < height / 2) { + if (labelPosition === 'inside') { + y = node.y1 + labelPadding + textAnchor = labelOrientation === 'vertical' ? 'end' : 'middle' + } else { + y = node.y - labelPadding + textAnchor = labelOrientation === 'vertical' ? 'start' : 'middle' + } } else { - x = node.x1 + labelPadding - textAnchor = labelOrientation === 'vertical' ? 'middle' : 'start' + if (labelPosition === 'inside') { + y = node.y - labelPadding + textAnchor = labelOrientation === 'vertical' ? 'start' : 'middle' + } else { + y = node.y1 + labelPadding + textAnchor = labelOrientation === 'vertical' ? 'end' : 'middle' + } } } @@ -54,7 +75,7 @@ const SankeyLabels = ({ id: node.id, label: node.label, x, - y: node.y + node.height / 2, + y, textAnchor, color: getLabelTextColor(node), } @@ -144,9 +165,9 @@ SankeyLabels.propTypes = { height: PropTypes.number.isRequired, }) ).isRequired, - + layout: PropTypes.oneOf(['horizontal', 'vertical']).isRequired, width: PropTypes.number.isRequired, - + height: PropTypes.number.isRequired, labelPosition: PropTypes.oneOf(['inside', 'outside']).isRequired, labelPadding: PropTypes.number.isRequired, labelOrientation: PropTypes.oneOf(['horizontal', 'vertical']).isRequired, diff --git a/packages/sankey/src/SankeyLinks.js b/packages/sankey/src/SankeyLinks.js index 54bb27332..d4419303f 100644 --- a/packages/sankey/src/SankeyLinks.js +++ b/packages/sankey/src/SankeyLinks.js @@ -9,59 +9,9 @@ import React, { Fragment } from 'react' import PropTypes from 'prop-types' import pure from 'recompose/pure' -import { line, curveMonotoneX, curveMonotoneY } from 'd3-shape' import { motionPropTypes, SmartMotion, blendModePropType } from '@nivo/core' import SankeyLinksItem from './SankeyLinksItem' - -const sankeyLinkHorizontal = () => { - const lineGenerator = line().curve(curveMonotoneX) - - return (n, contract) => { - const thickness = Math.max(1, n.thickness - contract * 2) - console.log(n.thickness, contract) - const halfThickness = thickness / 2 - const linkLength = n.target.x0 - n.source.x1 - const padLength = linkLength * 0.12 - - const dots = [ - [n.source.x1, n.pos0 - halfThickness], - [n.source.x1 + padLength, n.pos0 - halfThickness], - [n.target.x0 - padLength, n.pos1 - halfThickness], - [n.target.x0, n.pos1 - halfThickness], - [n.target.x0, n.pos1 + halfThickness], - [n.target.x0 - padLength, n.pos1 + halfThickness], - [n.source.x1 + padLength, n.pos0 + halfThickness], - [n.source.x1, n.pos0 + halfThickness], - [n.source.x1, n.pos0 - halfThickness], - ] - - return lineGenerator(dots) + 'Z' - } -} - -const sankeyLinkVertical = () => { - const lineGenerator = line().curve(curveMonotoneY) - - return n => { - const halfThickness = n.thickness / 2 - const linkLength = n.target.y0 - n.source.y1 - const padLength = linkLength * 0.12 - - const dots = [ - [n.pos0 + halfThickness, n.source.y1], - [n.pos0 + halfThickness, n.source.y1 + padLength], - [n.pos1 + halfThickness, n.target.y0 - padLength], - [n.pos1 + halfThickness, n.target.y0], - [n.pos1 - halfThickness, n.target.y0], - [n.pos1 - halfThickness, n.target.y0 - padLength], - [n.pos0 - halfThickness, n.source.y1 + padLength], - [n.pos0 - halfThickness, n.source.y1], - [n.pos0 + halfThickness, n.source.y1], - ] - - return lineGenerator(dots) + 'Z' - } -} +import { sankeyLinkHorizontal, sankeyLinkVertical } from './links' const SankeyLinks = ({ links, diff --git a/packages/sankey/src/enhance.js b/packages/sankey/src/enhance.js index 35b5b303d..84205964d 100644 --- a/packages/sankey/src/enhance.js +++ b/packages/sankey/src/enhance.js @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ import { cloneDeep } from 'lodash' -import { compose, defaultProps, withState, withPropsOnChange, pure, withProps } from 'recompose' +import { compose, defaultProps, withState, withPropsOnChange, pure } from 'recompose' import { sankey as d3Sankey } from 'd3-sankey' import { getLabelGenerator, diff --git a/packages/sankey/src/links.js b/packages/sankey/src/links.js new file mode 100644 index 000000000..ba187787f --- /dev/null +++ b/packages/sankey/src/links.js @@ -0,0 +1,59 @@ +/* + * This file is part of the nivo project. + * + * Copyright 2016-present, Raphaƫl Benitte. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +import { line, curveMonotoneX, curveMonotoneY } from 'd3-shape' + +export const sankeyLinkHorizontal = () => { + const lineGenerator = line().curve(curveMonotoneX) + + return (n, contract) => { + const thickness = Math.max(1, n.thickness - contract * 2) + const halfThickness = thickness / 2 + const linkLength = n.target.x0 - n.source.x1 + const padLength = linkLength * 0.12 + + const dots = [ + [n.source.x1, n.pos0 - halfThickness], + [n.source.x1 + padLength, n.pos0 - halfThickness], + [n.target.x0 - padLength, n.pos1 - halfThickness], + [n.target.x0, n.pos1 - halfThickness], + [n.target.x0, n.pos1 + halfThickness], + [n.target.x0 - padLength, n.pos1 + halfThickness], + [n.source.x1 + padLength, n.pos0 + halfThickness], + [n.source.x1, n.pos0 + halfThickness], + [n.source.x1, n.pos0 - halfThickness], + ] + + return lineGenerator(dots) + 'Z' + } +} + +export const sankeyLinkVertical = () => { + const lineGenerator = line().curve(curveMonotoneY) + + return (n, contract) => { + const thickness = Math.max(1, n.thickness - contract * 2) + const halfThickness = thickness / 2 + const linkLength = n.target.y0 - n.source.y1 + const padLength = linkLength * 0.12 + + const dots = [ + [n.pos0 + halfThickness, n.source.y1], + [n.pos0 + halfThickness, n.source.y1 + padLength], + [n.pos1 + halfThickness, n.target.y0 - padLength], + [n.pos1 + halfThickness, n.target.y0], + [n.pos1 - halfThickness, n.target.y0], + [n.pos1 - halfThickness, n.target.y0 - padLength], + [n.pos0 - halfThickness, n.source.y1 + padLength], + [n.pos0 - halfThickness, n.source.y1], + [n.pos0 + halfThickness, n.source.y1], + ] + + return lineGenerator(dots) + 'Z' + } +} diff --git a/website/src/components/charts/sankey/Sankey.js b/website/src/components/charts/sankey/Sankey.js index 0af97e64a..d82498b07 100644 --- a/website/src/components/charts/sankey/Sankey.js +++ b/website/src/components/charts/sankey/Sankey.js @@ -28,7 +28,7 @@ const initialSettings = { left: 50, }, - layout: 'horizontal', + layout: 'vertical', align: 'justify', sort: 'auto', colors: 'category10', diff --git a/website/src/components/charts/sankey/props.js b/website/src/components/charts/sankey/props.js index 9b23c99c6..f5603223c 100644 --- a/website/src/components/charts/sankey/props.js +++ b/website/src/components/charts/sankey/props.js @@ -422,7 +422,7 @@ export default [ type: '{string}', required: false, default: defaults.labelPosition, - controlType: 'choices', + controlType: 'radio', controlGroup: 'Labels', controlOptions: { choices: ['inside', 'outside'].map(key => ({ @@ -472,7 +472,7 @@ export default [ type: '{string}', required: false, default: defaults.labelOrientation, - controlType: 'choices', + controlType: 'radio', controlGroup: 'Labels', controlOptions: { choices: ['horizontal', 'vertical'].map(key => ({