From 6ce539cbda6293dd67655c4d07ef4091c91ec78e Mon Sep 17 00:00:00 2001 From: plouc Date: Tue, 16 Jun 2020 09:21:58 +0900 Subject: [PATCH] feat(funnel): add support for tooltip --- packages/funnel/src/Funnel.js | 11 ++----- packages/funnel/src/PartTooltip.js | 29 ++++++++++++++++ packages/funnel/src/hooks.js | 33 ++++++++++++++----- .../controls/MotionConfigControl.js | 3 +- 4 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 packages/funnel/src/PartTooltip.js diff --git a/packages/funnel/src/Funnel.js b/packages/funnel/src/Funnel.js index 973d35dd88..f74b988cc5 100644 --- a/packages/funnel/src/Funnel.js +++ b/packages/funnel/src/Funnel.js @@ -18,37 +18,29 @@ import { FunnelAnnotations } from './FunnelAnnotations' const Funnel = props => { const { data, - width, height, margin: partialMargin, - direction, interpolation, spacing, shapeBlending, valueFormat, - colors, fillOpacity, borderWidth, borderColor, borderOpacity, - enableLabel, labelColor, - enableBeforeSeparators, beforeSeparatorLength, beforeSeparatorOffset, enableAfterSeparators, afterSeparatorLength, afterSeparatorOffset, - layers, - annotations, - isInteractive, currentPartSizeExtension, currentBorderWidth, @@ -149,8 +141,9 @@ const Funnel = props => { ) } +Funnel.propTypes = FunnelPropTypes + const WrappedFunnel = withContainer(Funnel) -WrappedFunnel.propTypes = FunnelPropTypes WrappedFunnel.defaultProps = FunnelDefaultProps export default WrappedFunnel diff --git a/packages/funnel/src/PartTooltip.js b/packages/funnel/src/PartTooltip.js new file mode 100644 index 0000000000..a694fea981 --- /dev/null +++ b/packages/funnel/src/PartTooltip.js @@ -0,0 +1,29 @@ +/* + * 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' +import { BasicTooltip } from '@nivo/tooltip' + +const PartTooltip = memo(({ part }) => { + return ( + + ) +}) + +PartTooltip.displayName = 'ChordArcTooltip' +PartTooltip.propTypes = { + part: PropTypes.object.isRequired, +} + +export default PartTooltip diff --git a/packages/funnel/src/hooks.js b/packages/funnel/src/hooks.js index 9285ec7847..050e7bf156 100644 --- a/packages/funnel/src/hooks.js +++ b/packages/funnel/src/hooks.js @@ -1,10 +1,12 @@ -import { useMemo, useState } from 'react' +import React, { useMemo, useState } from 'react' import { line, area, curveBasis, curveLinear } from 'd3-shape' import { scaleLinear } from 'd3-scale' import { useInheritedColor, useOrdinalColorScale } from '@nivo/colors' import { useTheme, useValueFormatter } from '@nivo/core' import { useAnnotations } from '@nivo/annotations' +import { useTooltip } from '@nivo/tooltip' import { FunnelDefaultProps as defaults } from './props' +import PartTooltip from './PartTooltip' export const computeShapeGenerators = (interpolation, direction) => { // area generator which is used to draw funnel chart parts. @@ -166,26 +168,28 @@ export const computePartsHandlers = ({ onMouseLeave, onMouseMove, onClick, + showTooltipFromEvent, + hideTooltip, }) => { if (!isInteractive) return parts return parts.map(part => { const boundOnMouseEnter = event => { setCurrentPartId(part.data.id) + showTooltipFromEvent(React.createElement(PartTooltip, { part }), event) onMouseEnter !== undefined && onMouseEnter(part, event) } const boundOnMouseLeave = event => { setCurrentPartId(null) + hideTooltip() onMouseLeave !== undefined && onMouseLeave(part, event) } - const boundOnMouseMove = - onMouseMove !== undefined - ? event => { - onMouseMove(part, event) - } - : undefined + const boundOnMouseMove = event => { + showTooltipFromEvent(React.createElement(PartTooltip, { part }), event) + onMouseMove !== undefined && onMouseMove(part, event) + } const boundOnClick = onClick !== undefined @@ -461,6 +465,7 @@ export const useFunnel = ({ currentPartId, ]) + const { showTooltipFromEvent, hideTooltip } = useTooltip() const partsWithHandlers = useMemo( () => computePartsHandlers({ @@ -471,8 +476,20 @@ export const useFunnel = ({ onMouseLeave, onMouseMove, onClick, + showTooltipFromEvent, + hideTooltip, }), - [parts, setCurrentPartId, isInteractive, onMouseEnter, onMouseLeave, onMouseMove, onClick] + [ + parts, + setCurrentPartId, + isInteractive, + onMouseEnter, + onMouseLeave, + onMouseMove, + onClick, + showTooltipFromEvent, + hideTooltip, + ] ) const [beforeSeparators, afterSeparators] = useMemo( diff --git a/website/src/components/controls/MotionConfigControl.js b/website/src/components/controls/MotionConfigControl.js index 3b42c7e546..a2ffd7b19f 100644 --- a/website/src/components/controls/MotionConfigControl.js +++ b/website/src/components/controls/MotionConfigControl.js @@ -12,7 +12,6 @@ import { isString } from 'lodash' import styled from 'styled-components' import Control from './Control' import PropertyHeader from './PropertyHeader' -import TextInput from './TextInput' import Radio from './Radio' import Select from './Select' import Switch from './Switch' @@ -174,7 +173,7 @@ const MotionConfigControl = memo(({ id, property, flavors, currentFlavor, value, onChange={handleClampChange} /> - + )}