From b29fed2a7d388a65a8e2d3fc134cb6ccb77a51e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Benitte?= Date: Fri, 13 Dec 2019 07:14:17 +0900 Subject: [PATCH] feat(bump): add ability to use custom point component --- .storybook/config.js | 1 + packages/bump/src/bump/Bump.js | 3 +- packages/bump/src/bump/Point.js | 37 ++++++++++++++++ packages/bump/src/bump/Points.js | 53 +++++++++++------------ packages/bump/src/bump/props.js | 3 ++ packages/bump/stories/.eslintrc.yml | 5 +++ packages/bump/stories/bump.stories.js | 45 +++++++++++++++++++ website/src/data/components/bump/meta.yml | 6 ++- 8 files changed, 124 insertions(+), 29 deletions(-) create mode 100644 packages/bump/src/bump/Point.js create mode 100644 packages/bump/stories/.eslintrc.yml create mode 100644 packages/bump/stories/bump.stories.js diff --git a/.storybook/config.js b/.storybook/config.js index f65b264f0..75c980d9d 100644 --- a/.storybook/config.js +++ b/.storybook/config.js @@ -48,6 +48,7 @@ function loadStories() { require('../packages/bar/stories/raceChart.stories') require('../packages/bar/stories/barCanvas.stories') require('../packages/bullet/stories/bullet.stories') + require('../packages/bump/stories/bump.stories') require('../packages/calendar/stories/calendar.stories') require('../packages/chord/stories/chord.stories') require('../packages/circle-packing/stories/bubble.stories') diff --git a/packages/bump/src/bump/Bump.js b/packages/bump/src/bump/Bump.js index 8af7fe9e2..e10246596 100644 --- a/packages/bump/src/bump/Bump.js +++ b/packages/bump/src/bump/Bump.js @@ -45,6 +45,7 @@ const Bump = props => { endLabelPadding, endLabelTextColor, + pointComponent, pointSize, activePointSize, inactivePointSize, @@ -149,7 +150,7 @@ const Bump = props => { ))} ), - points: , + points: , } if (startLabel !== false) { diff --git a/packages/bump/src/bump/Point.js b/packages/bump/src/bump/Point.js new file mode 100644 index 000000000..23b56c12d --- /dev/null +++ b/packages/bump/src/bump/Point.js @@ -0,0 +1,37 @@ +/* + * 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 React, { memo } from 'react' +import PropTypes from 'prop-types' + +const pointStyle = { pointerEvents: 'none' } + +const Point = ({ x, y, size, color, borderColor, borderWidth }) => { + return ( + + ) +} + +Point.propTypes = { + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + size: PropTypes.number.isRequired, + color: PropTypes.string.isRequired, + borderColor: PropTypes.string.isRequired, + borderWidth: PropTypes.number.isRequired, +} + +export default memo(Point) diff --git a/packages/bump/src/bump/Points.js b/packages/bump/src/bump/Points.js index 22b48aea6..61ed77e5d 100644 --- a/packages/bump/src/bump/Points.js +++ b/packages/bump/src/bump/Points.js @@ -13,22 +13,21 @@ import { useMotionConfig } from '@nivo/core' const pointStyle = { pointerEvents: 'none' } -const Points = ({ points }) => { +const Points = ({ pointComponent, points }) => { const { animate, springConfig } = useMotionConfig() if (!animate) { - return points.map(point => ( - - )) + return points.map(point => { + return React.createElement(pointComponent, { + key: point.id, + x: point.x, + y: point.y, + size: point.style.size, + color: point.color, + borderColor: point.borderColor, + borderWidth: point.style.borderWidth, + }) + }) } return ( @@ -39,25 +38,24 @@ const Points = ({ points }) => { style: { x: spring(point.x, springConfig), y: spring(point.y, springConfig), - r: spring(point.style.size / 2, springConfig), - strokeWidth: spring(point.style.borderWidth, springConfig), + size: spring(point.style.size, springConfig), + borderWidth: spring(point.style.borderWidth, springConfig), }, }))} > {interpolated => ( <> - {interpolated.map(({ key, style, data: point }) => ( - - ))} + {interpolated.map(({ key, style, data: point }) => { + return React.createElement(pointComponent, { + key, + x: style.x, + y: point.y, + size: Math.max(style.size, 0), + color: point.color, + borderColor: point.borderColor, + borderWidth: Math.max(style.borderWidth, 0), + }) + })} )} @@ -65,6 +63,7 @@ const Points = ({ points }) => { } Points.propTypes = { + pointComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired, points: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, diff --git a/packages/bump/src/bump/props.js b/packages/bump/src/bump/props.js index 20bdf912e..a56f891a8 100644 --- a/packages/bump/src/bump/props.js +++ b/packages/bump/src/bump/props.js @@ -11,6 +11,7 @@ import { motionPropTypes } from '@nivo/core' import { ordinalColorsPropType, inheritedColorPropType } from '@nivo/colors' import { axisPropType } from '@nivo/axes' import LineTooltip from './LineTooltip' +import Point from './Point' const commonPropTypes = { data: PropTypes.arrayOf( @@ -54,6 +55,7 @@ const commonPropTypes = { endLabelPadding: PropTypes.number.isRequired, endLabelTextColor: inheritedColorPropType.isRequired, + pointComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired, pointSize: PropTypes.oneOfType([PropTypes.number, PropTypes.func]).isRequired, activePointSize: PropTypes.oneOfType([PropTypes.number, PropTypes.func]).isRequired, inactivePointSize: PropTypes.oneOfType([PropTypes.number, PropTypes.func]).isRequired, @@ -127,6 +129,7 @@ const commonDefaultProps = { export const BumpDefaultProps = { ...commonDefaultProps, + pointComponent: Point, animate: true, motionStiffness: 90, motionDamping: 15, diff --git a/packages/bump/stories/.eslintrc.yml b/packages/bump/stories/.eslintrc.yml new file mode 100644 index 000000000..b86501d4a --- /dev/null +++ b/packages/bump/stories/.eslintrc.yml @@ -0,0 +1,5 @@ +globals: + module: true + +rules: + react/prop-types: 0 \ No newline at end of file diff --git a/packages/bump/stories/bump.stories.js b/packages/bump/stories/bump.stories.js new file mode 100644 index 000000000..5d0c58bfb --- /dev/null +++ b/packages/bump/stories/bump.stories.js @@ -0,0 +1,45 @@ +import React from 'react' +import { storiesOf } from '@storybook/react' +import range from 'lodash/range' +import shuffle from 'lodash/shuffle' +import { Bump } from '../src' + +const generateData = () => { + const years = range(2000, 2005) + const ranks = range(1, 7) + + const series = ranks.map(rank => { + return { + id: `Serie ${rank}`, + data: [], + } + }) + + years.forEach(year => { + shuffle(ranks).forEach((rank, i) => { + series[i].data.push({ + x: year, + y: rank, + }) + }) + }) + + return series +} + +const commonProps = { + width: 900, + height: 360, + margin: { top: 40, right: 100, bottom: 40, left: 100 }, + titleOffsetX: -80, + data: generateData(), + spacing: 80, +} + +const stories = storiesOf('Bump', module) + +stories.add('default', () => ) + +stories.add('Custom points', () => ) + +stories.add('Missing data', () => ) diff --git a/website/src/data/components/bump/meta.yml b/website/src/data/components/bump/meta.yml index 48faab618..59e1a0c67 100644 --- a/website/src/data/components/bump/meta.yml +++ b/website/src/data/components/bump/meta.yml @@ -7,7 +7,11 @@ Bump: tags: - svg - isomorphic - stories: [] + stories: + - label: Custom points + link: bump--custom-points + - label: Missing data + link: bump--missing-data description: | The Bump chart can be used to show the ranking of several series over time. It is quite similar to [line](self:/line/) charts,