diff --git a/packages/nivo-sankey/src/Sankey.js b/packages/nivo-sankey/src/Sankey.js index be76f6c41..79faeb3a6 100644 --- a/packages/nivo-sankey/src/Sankey.js +++ b/packages/nivo-sankey/src/Sankey.js @@ -49,6 +49,8 @@ const Sankey = ({ linkHoverOpacity, linkHoverOthersOpacity, linkContract, + linkBlendMode, + enableLinkGradient, getLinkColor, // computed setCurrentLink, // injected currentLink, // injected @@ -152,6 +154,8 @@ const Sankey = ({ linkOpacity={linkOpacity} linkHoverOpacity={linkHoverOpacity} linkHoverOthersOpacity={linkHoverOthersOpacity} + linkBlendMode={linkBlendMode} + enableLinkGradient={enableLinkGradient} showTooltip={showTooltip} hideTooltip={hideTooltip} setCurrentLink={setCurrentLink} diff --git a/packages/nivo-sankey/src/SankeyLabels.js b/packages/nivo-sankey/src/SankeyLabels.js index f987326d1..438aaf8c1 100644 --- a/packages/nivo-sankey/src/SankeyLabels.js +++ b/packages/nivo-sankey/src/SankeyLabels.js @@ -6,7 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -import React from 'react' +import React, { Fragment } from 'react' import PropTypes from 'prop-types' import pure from 'recompose/pure' import { TransitionMotion, spring } from 'react-motion' @@ -102,7 +102,7 @@ const SankeyLabels = ({ })} > {interpolatedStyles => ( - + {interpolatedStyles.map(({ key, style, data }) => { const color = getInterpolatedColor(style) @@ -124,7 +124,7 @@ const SankeyLabels = ({ ) })} - + )} ) diff --git a/packages/nivo-sankey/src/SankeyLinks.js b/packages/nivo-sankey/src/SankeyLinks.js index 8fbacbf7c..4920a137d 100644 --- a/packages/nivo-sankey/src/SankeyLinks.js +++ b/packages/nivo-sankey/src/SankeyLinks.js @@ -6,11 +6,12 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -import React from 'react' +import React, { Fragment } from 'react' import PropTypes from 'prop-types' import pure from 'recompose/pure' import { sankeyLinkHorizontal } from 'd3-sankey' import { motionPropTypes, SmartMotion } from '@nivo/core' +import { blendModePropType } from './props' import SankeyLinksItem from './SankeyLinksItem' const getLinkPath = sankeyLinkHorizontal() @@ -23,6 +24,8 @@ const SankeyLinks = ({ linkHoverOpacity, linkHoverOthersOpacity, linkContract, + linkBlendMode, + enableLinkGradient, // motion animate, @@ -60,6 +63,8 @@ const SankeyLinks = ({ color={link.color} opacity={getOpacity(link)} contract={linkContract} + blendMode={linkBlendMode} + enableGradient={enableLinkGradient} showTooltip={showTooltip} hideTooltip={hideTooltip} setCurrent={setCurrentLink} @@ -79,7 +84,7 @@ const SankeyLinks = ({ } return ( - + {links.map(link => ( ))} - + ) } @@ -131,6 +138,8 @@ SankeyLinks.propTypes = { linkHoverOpacity: PropTypes.number.isRequired, linkHoverOthersOpacity: PropTypes.number.isRequired, linkContract: PropTypes.number.isRequired, + linkBlendMode: blendModePropType.isRequired, + enableLinkGradient: PropTypes.bool.isRequired, theme: PropTypes.object.isRequired, tooltip: PropTypes.func, diff --git a/packages/nivo-sankey/src/SankeyLinksItem.js b/packages/nivo-sankey/src/SankeyLinksItem.js index c1ee3b1d5..0cf260ec9 100644 --- a/packages/nivo-sankey/src/SankeyLinksItem.js +++ b/packages/nivo-sankey/src/SankeyLinksItem.js @@ -6,13 +6,14 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -import React from 'react' +import React, { Fragment } from 'react' import PropTypes from 'prop-types' import compose from 'recompose/compose' import withPropsOnChange from 'recompose/withPropsOnChange' import withHandlers from 'recompose/withHandlers' import pure from 'recompose/pure' import { BasicTooltip, Chip } from '@nivo/core' +import { blendModePropType } from './props' const tooltipStyles = { container: { @@ -61,24 +62,42 @@ const SankeyLinksItem = ({ color, opacity, contract, + blendMode, + enableGradient, // interactivity handleMouseEnter, handleMouseMove, handleMouseLeave, onClick, + + link, }) => ( - + + {enableGradient && ( + + + + + )} + + ) SankeyLinksItem.propTypes = { @@ -86,10 +105,12 @@ SankeyLinksItem.propTypes = { source: PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + color: PropTypes.string.isRequired, }).isRequired, target: PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + color: PropTypes.string.isRequired, }).isRequired, color: PropTypes.string.isRequired, value: PropTypes.number.isRequired, @@ -100,6 +121,8 @@ SankeyLinksItem.propTypes = { color: PropTypes.string.isRequired, opacity: PropTypes.number.isRequired, contract: PropTypes.number.isRequired, + blendMode: blendModePropType.isRequired, + enableGradient: PropTypes.bool.isRequired, theme: PropTypes.object.isRequired, diff --git a/packages/nivo-sankey/src/SankeyNodes.js b/packages/nivo-sankey/src/SankeyNodes.js index e41099417..296693e17 100644 --- a/packages/nivo-sankey/src/SankeyNodes.js +++ b/packages/nivo-sankey/src/SankeyNodes.js @@ -6,7 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -import React from 'react' +import React, { Fragment } from 'react' import PropTypes from 'prop-types' import pure from 'recompose/pure' import { TransitionMotion, spring } from 'react-motion' @@ -48,7 +48,7 @@ const SankeyNodes = ({ if (!animate) { return ( - + {nodes.map(node => ( ))} - + ) } @@ -96,7 +96,7 @@ const SankeyNodes = ({ })} > {interpolatedStyles => ( - + {interpolatedStyles.map(({ key, style, data: node }) => { const color = getInterpolatedColor(style) @@ -121,7 +121,7 @@ const SankeyNodes = ({ /> ) })} - + )} ) diff --git a/packages/nivo-sankey/src/props.js b/packages/nivo-sankey/src/props.js index 83459cab0..87066abaf 100644 --- a/packages/nivo-sankey/src/props.js +++ b/packages/nivo-sankey/src/props.js @@ -24,6 +24,25 @@ export const sankeyAlignmentPropType = PropTypes.oneOf(sankeyAlignmentPropKeys) export const sankeyAlignmentFromProp = prop => sankeyAlignmentPropMapping[prop] +export const blendModePropType = PropTypes.oneOf([ + 'normal', + 'multiply', + 'screen', + 'overlay', + 'darken', + 'lighten', + 'color-dodge', + 'color-burn', + 'hard-light', + 'soft-light', + 'difference', + 'exclusion', + 'hue', + 'saturation', + 'color', + 'luminosity', +]) + export const SankeyPropTypes = { data: PropTypes.shape({ nodes: PropTypes.arrayOf( @@ -56,6 +75,8 @@ export const SankeyPropTypes = { linkHoverOpacity: PropTypes.number.isRequired, linkHoverOthersOpacity: PropTypes.number.isRequired, linkContract: PropTypes.number.isRequired, + linkBlendMode: blendModePropType.isRequired, + enableLinkGradient: PropTypes.bool.isRequired, // labels enableLabels: PropTypes.bool.isRequired, @@ -98,6 +119,8 @@ export const SankeyDefaultProps = { linkHoverOpacity: 0.6, linkHoverOthersOpacity: 0.15, linkContract: 0, + linkBlendMode: 'multiply', + enableLinkGradient: false, // labels enableLabels: true, diff --git a/website/src/components/charts/sankey/Sankey.js b/website/src/components/charts/sankey/Sankey.js index a503fa99d..aba95b448 100644 --- a/website/src/components/charts/sankey/Sankey.js +++ b/website/src/components/charts/sankey/Sankey.js @@ -9,7 +9,7 @@ import React, { Component } from 'react' import { Link } from 'react-router-dom' import MediaQuery from 'react-responsive' -import { ResponsiveSankey } from '@nivo/sankey' +import { ResponsiveSankey, SankeyDefaultProps as defaults } from '@nivo/sankey' import ChartHeader from '../../ChartHeader' import ChartTabs from '../../ChartTabs' import SankeyControls from './SankeyControls' @@ -34,22 +34,24 @@ export default class Sankey extends Component { colors: 'd320b', // nodes - nodeOpacity: 0.75, + nodeOpacity: 1, nodeHoverOpacity: 1, nodeWidth: 18, - nodePaddingX: 4, + nodePaddingX: 0, nodePaddingY: 12, - nodeBorderWidth: 0, + nodeBorderWidth: 1, nodeBorderColor: { type: 'inherit:darker', - gamma: 0.4, + gamma: 0.8, }, // links - linkOpacity: 0.2, + linkOpacity: 0.25, linkHoverOpacity: 0.6, linkHoverOthersOpacity: 0.1, linkContract: 0, + linkBlendMode: 'multiply', + enableLinkGradient: true, // labels enableLabels: true, @@ -58,7 +60,7 @@ export default class Sankey extends Component { labelPadding: 16, labelTextColor: { type: 'inherit:darker', - gamma: 0.8, + gamma: 1, }, // motion @@ -94,7 +96,10 @@ export default class Sankey extends Component { const mappedSettings = propsMapper(settings) - const code = generateCode('ResponsiveSankey', mappedSettings, { pkg: '@nivo/sankey' }) + const code = generateCode('ResponsiveSankey', mappedSettings, { + pkg: '@nivo/sankey', + defaults, + }) const header = diff --git a/website/src/components/charts/sankey/SankeyAPI.js b/website/src/components/charts/sankey/SankeyAPI.js index 71a0a23eb..5c4f0bdab 100644 --- a/website/src/components/charts/sankey/SankeyAPI.js +++ b/website/src/components/charts/sankey/SankeyAPI.js @@ -47,6 +47,8 @@ export default class SankeyAPI extends Component { // links linkOpacity: 0.15, + linkBlendMode: 'multiply', + enableLinkGradient: true, linkContract: 0, // labels diff --git a/website/src/components/charts/sankey/SankeyPage.js b/website/src/components/charts/sankey/SankeyPage.js index df04b6d57..02e6a6cf1 100644 --- a/website/src/components/charts/sankey/SankeyPage.js +++ b/website/src/components/charts/sankey/SankeyPage.js @@ -11,7 +11,7 @@ import Helmet from 'react-helmet' import random from 'lodash/random' import { generateSankeyData } from '@nivo/generators' -const generateData = () => generateSankeyData({ nodeCount: 9, maxIterations: 2 }) +const generateData = () => generateSankeyData({ nodeCount: 13, maxIterations: 2 }) export default class SankeyPage extends Component { state = { diff --git a/website/src/components/charts/sankey/props.js b/website/src/components/charts/sankey/props.js index d47bb6abc..fef3ab01e 100644 --- a/website/src/components/charts/sankey/props.js +++ b/website/src/components/charts/sankey/props.js @@ -280,6 +280,60 @@ export default [ max: 60, }, }, + { + key: 'linkBlendMode', + scopes: '*', + description: ( + + Defines CSS mix-blend-mode property for links, see{' '} + + MDN documentation + . + + ), + type: '{string}', + required: false, + default: defaults.linkBlendMode, + controlType: 'choices', + controlGroup: 'Links', + controlOptions: { + choices: [ + 'normal', + 'multiply', + 'screen', + 'overlay', + 'darken', + 'lighten', + 'color-dodge', + 'color-burn', + 'hard-light', + 'soft-light', + 'difference', + 'exclusion', + 'hue', + 'saturation', + 'color', + 'luminosity', + ].map(key => ({ + label: key, + value: key, + })), + }, + }, + { + key: 'enableLinkGradient', + scopes: '*', + description: 'Enable/disable gradient from source/target nodes instead of plain color.', + type: '{boolean}', + required: false, + default: defaults.enableLinkGradient, + controlType: 'switch', + controlGroup: 'Links', + }, { key: 'enableLabels', scopes: '*',