Skip to content

Commit

Permalink
feat(bar): improve custom tooltip support
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed May 19, 2018
1 parent 82473c1 commit 5816555
Show file tree
Hide file tree
Showing 12 changed files with 800 additions and 433 deletions.
22 changes: 18 additions & 4 deletions conf/rollup.config.js
Expand Up @@ -35,15 +35,29 @@ export default {
'prop-types',
'lodash',
'lodash/without',
'lodash/flattenDepth',
'lodash/isPlainObject',
'lodash/isFunction',
'lodash/isArray',
'lodash/memoize',
'lodash/last',
'lodash/merge',
'lodash/pick',
'lodash/cloneDeep',
'lodash/min',
'lodash/minBy',
'lodash/max',
'lodash.range',
'lodash.random',
'lodash.shuffle',
'uniq',
'lodash/maxBy',
'lodash/range',
'lodash/random',
'lodash/shuffle',
'lodash/uniq',
'lodash/get',
'lodash/set',
'lodash/sortBy',
'lodash/partial',
'lodash/partialRight',
'lodash/isEqual',
'recompose/setDisplayName',
'recompose/defaultProps',
'recompose/withState',
Expand Down
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -20,9 +20,9 @@
"@ekino/config": "^0.3.0",
"@nivo/babel-preset": "^0.32.0-9",
"@nivo/generators": "^0.33.0",
"@storybook/addon-info": "^3.2.17",
"@storybook/addon-knobs": "^3.2.17",
"@storybook/react": "^3.2.17",
"@storybook/addon-info": "^3.4.5",
"@storybook/addon-knobs": "^3.4.5",
"@storybook/react": "^3.4.5",
"babel-eslint": "^8.2.1",
"chalk": "^2.3.0",
"clog-cli": "^1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/nivo-bar/src/BarItem.js
Expand Up @@ -101,8 +101,8 @@ BarItem.propTypes = {
}

const enhance = compose(
withPropsOnChange(['data', 'onClick'], ({ data, onClick }) => ({
onClick: event => onClick(data, event),
withPropsOnChange(['data', 'color', 'onClick'], ({ data, color, onClick }) => ({
onClick: event => onClick({ color, ...data }, event),
})),
withPropsOnChange(
['data', 'color', 'theme', 'tooltip', 'tooltipFormat'],
Expand Down
14 changes: 6 additions & 8 deletions packages/nivo-bar/stories/bar.stories.js
Expand Up @@ -210,17 +210,15 @@ stories.add(
minimumFractionDigits: 2,
}),
}}
tooltip={({ id, value, color }) => {
return (
<strong style={{ color }}>
{id}: {value}
</strong>
)
}}
tooltip={({ id, value, color }) => (
<strong style={{ color }}>
{id}: {value}
</strong>
)}
theme={{
tooltip: {
container: {
background: 'gray',
background: '#333',
},
},
}}
Expand Down
14 changes: 6 additions & 8 deletions packages/nivo-bar/stories/barCanvas.stories.js
Expand Up @@ -25,17 +25,15 @@ stories.add(
withInfo()(() => (
<BarCanvas
{...commonProps}
tooltip={({ id, value, color }) => {
return (
<strong style={{ color }}>
{id}: {value}
</strong>
)
}}
tooltip={({ id, value, color }) => (
<strong style={{ color }}>
{id}: {value}
</strong>
)}
theme={{
tooltip: {
container: {
background: 'gray',
background: '#333',
},
},
}}
Expand Down
10 changes: 9 additions & 1 deletion website/src/components/charts/bar/Bar.js
Expand Up @@ -22,6 +22,10 @@ import nivoTheme from '../../../nivoTheme'
import { generateLightDataSet as generateData } from './generators'
import propsMapper from './propsMapper'

const Tooltip = data => {
/* return custom tooltip */
}

export default class Bar extends Component {
state = {
...generateData(),
Expand Down Expand Up @@ -132,6 +136,8 @@ export default class Bar extends Component {

// interactivity
isInteractive: true,
'custom tooltip example': false,
tooltip: null,

legends: [
{
Expand All @@ -145,6 +151,8 @@ export default class Bar extends Component {
symbolSize: 20,
},
],

theme: nivoTheme,
},
}

Expand All @@ -170,6 +178,7 @@ export default class Bar extends Component {
{
keys,
...mappedSettings,
tooltip: mappedSettings.tooltip ? Tooltip : undefined,
},
{ pkg: '@nivo/bar', defaults: BarDefaultProps }
)
Expand Down Expand Up @@ -249,7 +258,6 @@ export default class Bar extends Component {
data={data}
keys={keys}
{...mappedSettings}
theme={nivoTheme}
onClick={this.handleNodeClick}
/>
</ChartTabs>
Expand Down
15 changes: 9 additions & 6 deletions website/src/components/charts/bar/BarCanvas.js
Expand Up @@ -20,6 +20,10 @@ import nivoTheme from '../../../nivoTheme'
import { generateHeavyDataSet as generateData } from './generators'
import propsMapper from './propsMapper'

const Tooltip = data => {
/* return custom tooltip */
}

export default class BarCanvas extends Component {
state = {
...generateData(),
Expand Down Expand Up @@ -105,13 +109,12 @@ export default class BarCanvas extends Component {
gamma: 1.6,
},

// motion
animate: true,
motionStiffness: 90,
motionDamping: 15,

// interactivity
isInteractive: true,
'custom tooltip example': false,
tooltip: null,

theme: nivoTheme,
},
}

Expand All @@ -137,6 +140,7 @@ export default class BarCanvas extends Component {
{
keys,
...mappedSettings,
tooltip: mappedSettings.tooltip ? Tooltip : undefined,
},
{ pkg: '@nivo/bar' }
)
Expand Down Expand Up @@ -175,7 +179,6 @@ export default class BarCanvas extends Component {
data={data}
keys={keys}
{...mappedSettings}
theme={nivoTheme}
onClick={this.handleNodeClick}
/>
</ChartTabs>
Expand Down
78 changes: 73 additions & 5 deletions website/src/components/charts/bar/props.js
Expand Up @@ -8,6 +8,7 @@
*/
import React from 'react'
import { Link } from 'react-router-dom'
import dedent from 'dedent-js'
import { BarDefaultProps as defaults } from '@nivo/bar'
import {
marginProperties,
Expand Down Expand Up @@ -206,11 +207,11 @@ export default [
max: 10,
},
},
/*—————————————————————————————————————————————————————————————————————————————
/*——————————————————————————————————————————————————————————————————————————
Styling
————————————————————————————————————————————————————————————————————————————*/
————————————————————————————————————————————————————————————————————————————*/
{
key: 'colors',
scopes: '*',
Expand Down Expand Up @@ -298,11 +299,11 @@ export default [
},
...defsProperties(['Bar']),
...marginProperties,
/*—————————————————————————————————————————————————————————————————————————————
/*——————————————————————————————————————————————————————————————————————————
Labels
————————————————————————————————————————————————————————————————————————————*/
————————————————————————————————————————————————————————————————————————————*/
{
key: 'enableLabel',
scopes: '*',
Expand Down Expand Up @@ -377,6 +378,11 @@ export default [
controlType: 'switch',
controlGroup: 'Grid',
},
/*——————————————————————————————————————————————————————————————————————————
Interactivity
————————————————————————————————————————————————————————————————————————————*/
{
key: 'isInteractive',
scopes: ['Bar', 'BarCanvas'],
Expand All @@ -387,12 +393,74 @@ export default [
controlType: 'switch',
controlGroup: 'Interactivity',
},
{
key: 'custom tooltip example',
scopes: ['Bar', 'BarCanvas'],
excludeFromDoc: true,
description: (
<span>
You can customize the tooltip using the <code>tooltip</code> property and{' '}
<code>theme.tooltip</code> object.
</span>
),
type: '{boolean}',
controlType: 'switch',
controlGroup: 'Interactivity',
},
{
key: 'tooltip',
scopes: ['Bar', 'BarCanvas'],
type: '{Function}',
required: false,
description: (
<div>
A function allowing complete tooltip customisation, it must return a valid HTML
element and will receive the following data:
<pre className="code code-block">
{dedent`
{
id: {string|number},
value: {number},
index: {number},
indexValue: {string|number},
color: {string},
// datum associated to the current index (raw data)
data: {object}
}
`}
</pre>
</div>
),
},
{
key: 'onClick',
scopes: ['Bar', 'BarCanvas'],
description: 'onClick handler, it receives clicked bar data and mouse event.',
type: '{Function}',
required: false,
description: (
<div>
onClick handler, will receive node data as first argument & event as second one. The
node data has the following shape:
<pre className="code code-block">
{dedent`
{
id: {string|number},
value: {number},
index: {number},
indexValue: {string|number},
color: {string},
// datum associated to the current index (raw data)
data: {object}
}
`}
</pre>
</div>
),
},
/*——————————————————————————————————————————————————————————————————————————
Motion
————————————————————————————————————————————————————————————————————————————*/
...motionProperties(['Bar'], defaults),
]
55 changes: 54 additions & 1 deletion website/src/components/charts/bar/propsMapper.js
Expand Up @@ -6,8 +6,37 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React from 'react'
import styled from 'styled-components'
import { settingsMapper, mapAxis, mapInheritedColor } from '../../../lib/settings'

const TooltipWrapper = styled.div`
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 12px;
`
const TooltipKey = styled.span`
font-weight: 600;
`
const TooltipValue = styled.span``

const CustomTooltip = node => {
return (
<TooltipWrapper style={{ color: node.color }}>
<TooltipKey>id</TooltipKey>
<TooltipValue>{node.id}</TooltipValue>
<TooltipKey>value</TooltipKey>
<TooltipValue>{node.value}</TooltipValue>
<TooltipKey>index</TooltipKey>
<TooltipValue>{node.index}</TooltipValue>
<TooltipKey>indexValue</TooltipKey>
<TooltipValue>{node.indexValue}</TooltipValue>
<TooltipKey>color</TooltipKey>
<TooltipValue>{node.color}</TooltipValue>
</TooltipWrapper>
)
}

export default settingsMapper(
{
colorBy: value => {
Expand All @@ -21,8 +50,32 @@ export default settingsMapper(
axisLeft: mapAxis('left'),
borderColor: mapInheritedColor,
labelTextColor: mapInheritedColor,
theme: (value, values) => {
if (!values['custom tooltip example']) return value

return {
...values.theme,
tooltip: {
container: {
...values.theme.tooltip.container,
background: '#333',
},
},
}
},
tooltip: (value, values) => {
if (!values['custom tooltip example']) return null

return CustomTooltip
},
},
{
exclude: ['enable axisTop', 'enable axisRight', 'enable axisBottom', 'enable axisLeft'],
exclude: [
'enable axisTop',
'enable axisRight',
'enable axisBottom',
'enable axisLeft',
'custom tooltip example',
],
}
)

0 comments on commit 5816555

Please sign in to comment.