diff --git a/packages/nivo-chord/src/ChordArcs.js b/packages/nivo-chord/src/ChordArcs.js index a12c266b8..72592d90c 100644 --- a/packages/nivo-chord/src/ChordArcs.js +++ b/packages/nivo-chord/src/ChordArcs.js @@ -12,11 +12,7 @@ import { TransitionMotion, spring } from 'react-motion' import pure from 'recompose/pure' import { colorMotionSpring, getInterpolatedColor } from '@nivo/core' import ChordArcTooltip from './ChordArcTooltip' -import { - defaultAnimate, - defaultMotionDamping, - defaultMotionStiffness, -} from '@nivo/core' +import { motionPropTypes } from '@nivo/core' const ChordArcs = ({ arcs, @@ -134,9 +130,7 @@ ChordArcs.propTypes = { showTooltip: PropTypes.func.isRequired, hideTooltip: PropTypes.func.isRequired, tooltipFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), - animate: defaultAnimate, - motionDamping: defaultMotionDamping, - motionStiffness: defaultMotionStiffness, + ...motionPropTypes, } export default pure(ChordArcs) diff --git a/packages/nivo-chord/src/ChordLabels.js b/packages/nivo-chord/src/ChordLabels.js index 33a440333..758b71df1 100644 --- a/packages/nivo-chord/src/ChordLabels.js +++ b/packages/nivo-chord/src/ChordLabels.js @@ -10,11 +10,7 @@ import React from 'react' import PropTypes from 'prop-types' import { TransitionMotion, spring } from 'react-motion' import { midAngle, getPolarLabelProps } from '@nivo/core' -import { - defaultAnimate, - defaultMotionDamping, - defaultMotionStiffness, -} from '@nivo/core' +import { motionPropTypes } from '@nivo/core' const ChordLabels = ({ arcs, @@ -107,9 +103,7 @@ ChordLabels.propTypes = { getLabel: PropTypes.func.isRequired, getColor: PropTypes.func.isRequired, theme: PropTypes.object.isRequired, - animate: defaultAnimate, - motionDamping: defaultMotionDamping, - motionStiffness: defaultMotionStiffness, + ...motionPropTypes, } export default ChordLabels diff --git a/packages/nivo-chord/src/ChordRibbons.js b/packages/nivo-chord/src/ChordRibbons.js index 246f34089..6cd97fc65 100644 --- a/packages/nivo-chord/src/ChordRibbons.js +++ b/packages/nivo-chord/src/ChordRibbons.js @@ -17,11 +17,7 @@ import pure from 'recompose/pure' import { colorMotionSpring, getInterpolatedColor } from '@nivo/core' import { midAngle } from '@nivo/core' import { TableTooltip, Chip } from '@nivo/core' -import { - defaultAnimate, - defaultMotionDamping, - defaultMotionStiffness, -} from '@nivo/core' +import { motionPropTypes } from '@nivo/core' /** * Used to get ribbon angles, instead of using source and target arcs, @@ -228,9 +224,7 @@ ChordRibbons.propTypes = { showTooltip: PropTypes.func.isRequired, hideTooltip: PropTypes.func.isRequired, tooltipFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), - animate: defaultAnimate, - motionDamping: defaultMotionDamping, - motionStiffness: defaultMotionStiffness, + ...motionPropTypes, } const enhance = compose( diff --git a/packages/nivo-core/src/lib/interactivity/index.js b/packages/nivo-core/src/lib/interactivity/index.js index 7bb871a7e..ee2b0e1a1 100644 --- a/packages/nivo-core/src/lib/interactivity/index.js +++ b/packages/nivo-core/src/lib/interactivity/index.js @@ -10,8 +10,8 @@ export * from './detect' export const getRelativeCursor = (el, event) => { - const { pageX, pageY } = event + const { clientX, clientY } = event const bounds = el.getBoundingClientRect() - return [pageX - bounds.left, pageY - bounds.top] + return [clientX - bounds.left, clientY - bounds.top] } diff --git a/packages/nivo-scatterplot/src/ScatterPlot.js b/packages/nivo-scatterplot/src/ScatterPlot.js index 929d1afe3..f2389e2aa 100644 --- a/packages/nivo-scatterplot/src/ScatterPlot.js +++ b/packages/nivo-scatterplot/src/ScatterPlot.js @@ -39,6 +39,9 @@ const ScatterPlot = ({ theme, getColor, + // symbols, + symbolSize, + // motion animate, motionStiffness, @@ -67,89 +70,103 @@ const ScatterPlot = ({ fill: getColor(serie), })) - const symbols = data.reduce((agg, serie) => { - return [ + const symbols = data.reduce( + (agg, serie) => [ ...agg, - ...serie.data.map(d => { - return { - id: `${serie.id}.${d.id}`, - x: xScale(d.x), - y: yScale(d.y), - color: getColor(serie), - data: { ...d, serie: serie.id }, - } - }), - ] - }, []) + ...serie.data.map(d => ({ + id: `${serie.id}.${d.id}`, + x: xScale(d.x), + y: yScale(d.y), + color: getColor(serie), + data: { ...d, serie: serie.id }, + })), + ], + [] + ) return ( - {({ showTooltip, hideTooltip }) => { - return ( - - - - {animate === true && ( - ({ - key: symbol.id, - data: symbol, - style: { - x: spring(symbol.x, springConfig), - y: spring(symbol.y, springConfig), - }, - }))} - > - {interpolatedStyles => ( - - {interpolatedStyles.map(({ key, style, data: symbol }) => ( - - ))} - - )} - - )} - {legends.map((legend, i) => ( - ( + + + + {!animate && + symbols.map(symbol => ( + ))} - - ) - }} + {animate === true && ( + ({ + key: symbol.id, + data: symbol, + style: { + x: spring(symbol.x, springConfig), + y: spring(symbol.y, springConfig), + }, + }))} + > + {interpolatedStyles => ( + + {interpolatedStyles.map(({ key, style, data: symbol }) => ( + + ))} + + )} + + )} + {legends.map((legend, i) => ( + + ))} + + )} ) } diff --git a/packages/nivo-scatterplot/src/ScatterPlotCanvas.js b/packages/nivo-scatterplot/src/ScatterPlotCanvas.js index c5f8cb9a8..81039b015 100644 --- a/packages/nivo-scatterplot/src/ScatterPlotCanvas.js +++ b/packages/nivo-scatterplot/src/ScatterPlotCanvas.js @@ -17,7 +17,14 @@ import enhance from './enhance' const findNodeUnderCursor = (nodes, margin, x, y) => nodes.find(node => - isCursorInRect(node.x + margin.left, node.y + margin.top, node.width, node.height, x, y) + isCursorInRect( + node.x + margin.left - node.size / 2, + node.y + margin.top - node.size / 2, + node.size, + node.size, + x, + y + ) ) class ScatterPlotCanvas extends Component { @@ -69,6 +76,9 @@ class ScatterPlotCanvas extends Component { enableGridX, enableGridY, + // symbols + symbolSize, + // theming getColor, @@ -111,13 +121,27 @@ class ScatterPlotCanvas extends Component { left: axisLeft, }) - data.forEach(serie => { - serie.data.forEach(d => { - this.ctx.fillStyle = getColor(serie) - this.ctx.fillRect(xScale(d.x) - 2, yScale(d.y) - 2, 4, 4) - }) + const items = data.reduce( + (agg, serie) => [ + ...agg, + ...serie.data.map(d => ({ + x: xScale(d.x), + y: yScale(d.y), + size: symbolSize, + color: getColor(serie), + data: { ...d, serie: serie.id }, + })), + ], + [] + ) + + items.forEach(d => { + this.ctx.fillStyle = d.color + this.ctx.fillRect(d.x - symbolSize / 2, d.y - symbolSize / 2, symbolSize, symbolSize) }) + this.items = items + const legendData = data.map(serie => ({ label: serie.id, fill: getColor(serie), @@ -134,20 +158,19 @@ class ScatterPlotCanvas extends Component { } handleMouseHover = (showTooltip, hideTooltip) => event => { - if (!this.bars) return + if (!this.items) return const { margin, theme } = this.props const [x, y] = getRelativeCursor(this.surface, event) - const bar = findNodeUnderCursor(this.bars, margin, x, y) - - if (bar !== undefined) { + const item = findNodeUnderCursor(this.items, margin, x, y) + if (item !== undefined) { showTooltip( , event @@ -162,13 +185,13 @@ class ScatterPlotCanvas extends Component { } handleClick = event => { - if (!this.bars) return + if (!this.items) return const { margin, onClick } = this.props const [x, y] = getRelativeCursor(this.surface, event) - const node = findNodeUnderCursor(this.bars, margin, x, y) - if (node !== undefined) onClick(node.data, event) + const item = findNodeUnderCursor(this.items, margin, x, y) + if (item !== undefined) onClick(item.data, event) } render() { diff --git a/packages/nivo-scatterplot/src/ScatterPlotItem.js b/packages/nivo-scatterplot/src/ScatterPlotItem.js index 585a6f3a5..0aff2c417 100644 --- a/packages/nivo-scatterplot/src/ScatterPlotItem.js +++ b/packages/nivo-scatterplot/src/ScatterPlotItem.js @@ -78,10 +78,6 @@ ScatterPlotItem.propTypes = { }).isRequired, } -ScatterPlotItem.defaultProps = { - size: 6, -} - const enhance = compose( withPropsOnChange(['data', 'onClick'], ({ data, onClick }) => ({ onClick: event => onClick(data, event), diff --git a/packages/nivo-scatterplot/src/props.js b/packages/nivo-scatterplot/src/props.js index efdefdd51..26ab6dcd9 100644 --- a/packages/nivo-scatterplot/src/props.js +++ b/packages/nivo-scatterplot/src/props.js @@ -45,6 +45,10 @@ export const ScatterPlotPropTypes = { enableGridX: PropTypes.bool.isRequired, enableGridY: PropTypes.bool.isRequired, + // symbols + symbolSize: PropTypes.number.isRequired, + symbolShape: PropTypes.oneOfType([PropTypes.oneOf(['circle', 'square'])]).isRequired, + // styling getColor: PropTypes.func.isRequired, @@ -74,6 +78,10 @@ export const ScatterPlotDefaultProps = { enableGridX: true, enableGridY: true, + // symbols + symbolSize: 6, + symbolShape: 'circle', + // styling colors: 'nivo', colorBy: 'id', diff --git a/website/package.json b/website/package.json index e1709ae5c..041d046c3 100644 --- a/website/package.json +++ b/website/package.json @@ -9,23 +9,23 @@ "source-map-explorer": "^1.5.0" }, "dependencies": { - "@nivo/bar": "0.33.0-5", - "@nivo/calendar": "0.33.0-5", - "@nivo/chord": "0.33.0-5", - "@nivo/circle-packing": "0.33.0-5", - "@nivo/core": "0.33.0-5", - "@nivo/generators": "0.33.0-5", - "@nivo/heatmap": "0.33.0-5", - "@nivo/legends": "0.33.0-5", - "@nivo/line": "0.33.0-5", - "@nivo/pie": "0.33.0-5", - "@nivo/radar": "0.33.0-5", - "@nivo/sankey": "0.33.0-5", - "@nivo/scatterplot": "0.33.0-5", - "@nivo/stream": "0.33.0-5", - "@nivo/sunburst": "0.33.0-5", - "@nivo/treemap": "0.33.0-5", - "@nivo/voronoi": "0.33.0-5", + "@nivo/bar": "0.33.0-7", + "@nivo/calendar": "0.33.0-7", + "@nivo/chord": "0.33.0-7", + "@nivo/circle-packing": "0.33.0-7", + "@nivo/core": "0.33.0-7", + "@nivo/generators": "0.33.0-7", + "@nivo/heatmap": "0.33.0-7", + "@nivo/legends": "0.33.0-7", + "@nivo/line": "0.33.0-7", + "@nivo/pie": "0.33.0-7", + "@nivo/radar": "0.33.0-7", + "@nivo/sankey": "0.33.0-7", + "@nivo/scatterplot": "0.33.0-7", + "@nivo/stream": "0.33.0-7", + "@nivo/sunburst": "0.33.0-7", + "@nivo/treemap": "0.33.0-7", + "@nivo/voronoi": "0.33.0-7", "classnames": "2.2.4", "d3-scale": "^1.0.6", "d3-scale-chromatic": "^1.1.1", diff --git a/website/src/components/charts/scatterplot/ScatterPlot.js b/website/src/components/charts/scatterplot/ScatterPlot.js index a13aac78a..253d21b59 100644 --- a/website/src/components/charts/scatterplot/ScatterPlot.js +++ b/website/src/components/charts/scatterplot/ScatterPlot.js @@ -34,6 +34,9 @@ export default class ScatterPlot extends Component { colors: 'nivo', colorBy: 'id', + // symbols + symbolSize: 6, + // axes 'enable axisTop': false, axisTop: { diff --git a/website/src/components/charts/scatterplot/ScatterPlotCanvas.js b/website/src/components/charts/scatterplot/ScatterPlotCanvas.js index bccae3c3b..2186b4877 100644 --- a/website/src/components/charts/scatterplot/ScatterPlotCanvas.js +++ b/website/src/components/charts/scatterplot/ScatterPlotCanvas.js @@ -33,14 +33,12 @@ export default class ScatterPlotCanvas extends Component { pixelRatio: window && window.devicePixelRatio ? window.devicePixelRatio : 1, - minX: 0, - maxX: 'auto', - minY: 0, - maxY: 'auto', - colors: 'nivo', colorBy: 'id', + // symbols + symbolSize: 4, + // axes 'enable axisTop': false, axisTop: { diff --git a/website/src/components/charts/scatterplot/generators.js b/website/src/components/charts/scatterplot/generators.js index 64b95cd4e..9c2eca162 100644 --- a/website/src/components/charts/scatterplot/generators.js +++ b/website/src/components/charts/scatterplot/generators.js @@ -2,7 +2,7 @@ import { range, random } from 'lodash' const keys = ['group A', 'group B', 'group C', 'group D', 'group E'] const ageRange = [0, 100] -const weightRange = [4, 120] +const weightRange = [0, 120] const generateData = size => keys.map(key => ({ @@ -16,4 +16,4 @@ const generateData = size => export const generateLightDataSet = () => generateData(50) -export const generateHeavyDataSet = () => generateData(700) +export const generateHeavyDataSet = () => generateData(800) diff --git a/website/src/components/charts/scatterplot/props.js b/website/src/components/charts/scatterplot/props.js index 57afb9a1d..bd103e306 100644 --- a/website/src/components/charts/scatterplot/props.js +++ b/website/src/components/charts/scatterplot/props.js @@ -118,6 +118,20 @@ export default [ ], }, }, + { + key: 'symbolSize', + scopes: '*', + description: `Symbol size (px).`, + required: false, + default: defaults.symbolSize, + type: `{number}`, + controlType: 'range', + controlGroup: 'Symbols', + controlOptions: { + min: 2, + max: 24, + }, + }, ...marginProperties, ...axesProperties, {