diff --git a/packages/scatterplot/src/ScatterPlot.js b/packages/scatterplot/src/ScatterPlot.js index 33a1e6d27..6f903aca1 100644 --- a/packages/scatterplot/src/ScatterPlot.js +++ b/packages/scatterplot/src/ScatterPlot.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, { Component } from 'react' +import React, { Component, Fragment } from 'react' import { TransitionMotion, spring } from 'react-motion' import setDisplayName from 'recompose/setDisplayName' import { Container, SvgWrapper, Grid, CartesianMarkers } from '@nivo/core' @@ -77,6 +77,8 @@ class ScatterPlot extends Component { computedData, points, + layers, + margin, width, height, @@ -132,14 +134,10 @@ class ScatterPlot extends Component { const onMouseMove = this.handleMouseMove(showTooltip) const onMouseLeave = this.handleMouseLeave(hideTooltip) - return ( - + const layerById = { + grid: ( + ), + axes: ( - {!animate && - points.map(point => ( - - ))} - {animate === true && ( - ({ - key: point.id, - data: point, - style: { - x: spring(point.x, springConfig), - y: spring(point.y, springConfig), - size: spring(getSymbolSize(point.data), springConfig), - }, - }))} - > - {interpolatedStyles => ( - - {interpolatedStyles.map( - ({ key, style, data: point }) => ( - - ) - )} - - )} - - )} + ), + markers: ( - {isInteractive && - useMesh && ( - + ), + mesh: null, + legends: legends.map((legend, i) => ( + + )), + } + + if (animate === true) { + layerById.points = ( + ({ + key: point.id, + data: point, + style: { + x: spring(point.x, springConfig), + y: spring(point.y, springConfig), + size: spring(getSymbolSize(point.data), springConfig), + }, + }))} + > + {interpolatedStyles => ( + + {interpolatedStyles.map(({ key, style, data: point }) => ( + + ))} + )} - {legends.map((legend, i) => ( - - ))} + + ) + } else { + layerById.points = points.map(point => ( + + )) + } + + if (isInteractive === true && useMesh === true) { + layerById.mesh = ( + + ) + } + + return ( + + {layers.map((layer, i) => { + if (typeof layer === 'function') { + return ( + + {layer({ ...this.props, xScale, yScale })} + + ) + } + return layerById[layer] + })} ) }} diff --git a/packages/scatterplot/src/props.js b/packages/scatterplot/src/props.js index 2b3b5e423..3903f455f 100644 --- a/packages/scatterplot/src/props.js +++ b/packages/scatterplot/src/props.js @@ -41,6 +41,13 @@ export const ScatterPlotPropTypes = { yScale: PropTypes.func.isRequired, }).isRequired, + layers: PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.oneOf(['grid', 'axes', 'points', 'markers', 'mesh', 'legends']), + PropTypes.func, + ]) + ).isRequired, + axisTop: axisPropType, axisRight: axisPropType, axisBottom: axisPropType, @@ -91,6 +98,8 @@ export const ScatterPlotDefaultProps = { max: 'auto', }, + layers: ['grid', 'axes', 'points', 'markers', 'mesh', 'legends'], + axisBottom: {}, axisLeft: {}, enableGridX: true, diff --git a/packages/scatterplot/stories/ScatterPlot.stories.js b/packages/scatterplot/stories/ScatterPlot.stories.js index 710feaf03..eb7a78605 100644 --- a/packages/scatterplot/stories/ScatterPlot.stories.js +++ b/packages/scatterplot/stories/ScatterPlot.stories.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import omit from 'lodash/omit' +import { area, curveMonotoneX } from 'd3-shape' import { storiesOf } from '@storybook/react' import { withInfo } from '@storybook/addon-info' import { ScatterPlot, ResponsiveScatterPlot } from '../index' @@ -370,3 +371,55 @@ stories.add( /> )) ) + +const AreaLayer = ({ points, xScale, yScale }) => { + const areaGenerator = area() + .x(d => xScale(d.data.x)) + .y0(d => yScale(d.data.low)) + .y1(d => yScale(d.data.high)) + .curve(curveMonotoneX) + + return +} + +stories.add( + 'adding extra layers', + withInfo({ + source: false, + text: ` + You can use the layers property to add extra layers + to the scatterplot chart. + `, + })(() => ( + + )) +) diff --git a/website/src/components/charts/bar/props.js b/website/src/components/charts/bar/props.js index 32035ff64..5f43a5a5f 100644 --- a/website/src/components/charts/bar/props.js +++ b/website/src/components/charts/bar/props.js @@ -97,7 +97,8 @@ export default [ description: (
Defines the order of layers, available layers are: - thing A, thing B.
+ grid, axes, bars, markers,{' '} + legends.
You can also use this to insert extra layers to the chart, this extra layer must be a function which will receive the chart computed data and must return a valid SVG element. diff --git a/website/src/components/charts/scatterplot/props.js b/website/src/components/charts/scatterplot/props.js index c5805d2c2..2ffcb3a81 100644 --- a/website/src/components/charts/scatterplot/props.js +++ b/website/src/components/charts/scatterplot/props.js @@ -192,6 +192,22 @@ export default [ step: 5, }, }, + { + key: 'layers', + scopes: ['ScatterPlot'], + description: ( +
+ Defines the order of layers, available layers are: + grid, axes, points, markers,{' '} + mesh, legends.
+ You can also use this to insert extra layers to the chart, this extra layer must be + a function which will receive the chart computed data and must return a valid SVG + element. +
+ ), + required: false, + default: defaults.layers, + }, { key: 'pixelRatio', scopes: ['ScatterPlotCanvas'],