Skip to content

Commit

Permalink
feat(sankey): adjust labels for vertical layout
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed Mar 23, 2019
1 parent e299590 commit e12cdf1
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 74 deletions.
2 changes: 2 additions & 0 deletions packages/sankey/src/Sankey.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ const Sankey = ({
{enableLabels && (
<SankeyLabels
nodes={nodes}
layout={layout}
width={width}
height={height}
labelPosition={labelPosition}
labelPadding={labelPadding}
labelOrientation={labelOrientation}
Expand Down
59 changes: 40 additions & 19 deletions packages/sankey/src/SankeyLabels.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,68 @@ import { colorMotionSpring, getInterpolatedColor, motionPropTypes } from '@nivo/

const SankeyLabels = ({
nodes,

layout,
width,

height,
labelPosition,
labelPadding,
labelOrientation,
getLabelTextColor,

theme,

animate,
motionDamping,
motionStiffness,
}) => {
const labelRotation = labelOrientation === 'vertical' ? -90 : 0
const labels = nodes.map(node => {
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'
}
}
}

return {
id: node.id,
label: node.label,
x,
y: node.y + node.height / 2,
y,
textAnchor,
color: getLabelTextColor(node),
}
Expand Down Expand Up @@ -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,
Expand Down
52 changes: 1 addition & 51 deletions packages/sankey/src/SankeyLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion packages/sankey/src/enhance.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
59 changes: 59 additions & 0 deletions packages/sankey/src/links.js
Original file line number Diff line number Diff line change
@@ -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'
}
}
2 changes: 1 addition & 1 deletion website/src/components/charts/sankey/Sankey.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const initialSettings = {
left: 50,
},

layout: 'horizontal',
layout: 'vertical',
align: 'justify',
sort: 'auto',
colors: 'category10',
Expand Down
4 changes: 2 additions & 2 deletions website/src/components/charts/sankey/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 => ({
Expand Down Expand Up @@ -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 => ({
Expand Down

0 comments on commit e12cdf1

Please sign in to comment.