Skip to content

Commit

Permalink
fix(line): avoid re-rerendering LineDots
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte committed Dec 9, 2017
1 parent 71e1c4b commit a6f5137
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 136 deletions.
14 changes: 10 additions & 4 deletions packages/nivo-line/src/Line.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ const Line = ({
enableDots,
dotSymbol,
dotSize,
dotColor,
getDotColor,
dotBorderWidth,
dotBorderColor,
getDotBorderColor,
enableDotLabel,
dotLabel,
dotLabelFormat,
Expand Down Expand Up @@ -154,9 +154,9 @@ const Line = ({
lines={lines}
symbol={dotSymbol}
size={dotSize}
color={getInheritedColorGenerator(dotColor)}
color={getDotColor}
borderWidth={dotBorderWidth}
borderColor={getInheritedColorGenerator(dotBorderColor)}
borderColor={getDotBorderColor}
enableLabel={enableDotLabel}
label={dotLabel}
labelFormat={dotLabelFormat}
Expand Down Expand Up @@ -259,6 +259,12 @@ const enhance = compose(
return { lines, slices }
}
),
withPropsOnChange(['dotColor'], ({ dotColor }) => ({
getDotColor: getInheritedColorGenerator(dotColor),
})),
withPropsOnChange(['dotBorderColor'], ({ dotBorderColor }) => ({
getDotBorderColor: getInheritedColorGenerator(dotBorderColor),
})),
pure
)

Expand Down
266 changes: 134 additions & 132 deletions packages/nivo-line/src/LineDots.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,109 +6,112 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React from 'react'
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { TransitionMotion, spring } from 'react-motion'
import { motionPropTypes } from '@nivo/core'
import { getLabelGenerator } from '@nivo/core'
import { DotsItem } from '@nivo/core'

const LineDots = ({
lines,

symbol,
size,
color,
borderWidth,
borderColor,

// labels
enableLabel,
label,
labelFormat,
labelYOffset,

// theming
theme,

// motion
animate,
motionStiffness,
motionDamping,
}) => {
const getLabel = getLabelGenerator(label, labelFormat)

const points = lines.reduce((acc, line) => {
const { id, points } = line

return [
...acc,
...points.filter(point => point.value !== null).map(point => {
const pointData = {
serie: { id },
x: point.key,
y: point.value,
}

return {
key: `${id}.${point.x}`,
x: point.x,
y: point.y,
fill: color(line),
stroke: borderColor(line),
label: enableLabel ? getLabel(pointData) : null,
}
}),
]
}, [])

if (animate !== true) {
return (
<g>
{points.map(point => (
<DotsItem
key={point.key}
x={point.x}
y={point.y}
symbol={symbol}
size={size}
color={point.fill}
borderWidth={borderWidth}
borderColor={point.stroke}
label={point.label}
labelYOffset={labelYOffset}
theme={theme}
/>
))}
</g>
)
export default class LineDots extends PureComponent {
static propTypes = {
lines: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
})
),

symbol: PropTypes.func,
size: PropTypes.number.isRequired,
color: PropTypes.func.isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.func.isRequired,

// labels
enableLabel: PropTypes.bool.isRequired,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
labelFormat: PropTypes.string,
labelYOffset: PropTypes.number,

// theming
theme: PropTypes.shape({
dots: PropTypes.shape({
textColor: PropTypes.string.isRequired,
fontSize: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,

// motion
...motionPropTypes,
}
const springConfig = {
motionDamping,
motionStiffness,

static defaultProps = {
// labels
enableLabel: false,
label: 'y',
}

return (
<TransitionMotion
styles={points.map(point => {
return {
key: point.key,
data: point,
style: {
x: spring(point.x, springConfig),
y: spring(point.y, springConfig),
size: spring(size, springConfig),
},
}
})}
>
{interpolatedStyles => (
render() {
const {
lines,

symbol,
size,
color,
borderWidth,
borderColor,

// labels
enableLabel,
label,
labelFormat,
labelYOffset,

// theming
theme,

// motion
animate,
motionStiffness,
motionDamping,
} = this.props

const getLabel = getLabelGenerator(label, labelFormat)

const points = lines.reduce((acc, line) => {
const { id, points } = line

return [
...acc,
...points.filter(point => point.value !== null).map(point => {
const pointData = {
serie: { id },
x: point.key,
y: point.value,
}

return {
key: `${id}.${point.x}`,
x: point.x,
y: point.y,
fill: color(line),
stroke: borderColor(line),
label: enableLabel ? getLabel(pointData) : null,
}
}),
]
}, [])

if (animate !== true) {
return (
<g>
{interpolatedStyles.map(({ key, style, data: point }) => (
{points.map(point => (
<DotsItem
key={key}
{...style}
key={point.key}
x={point.x}
y={point.y}
symbol={symbol}
size={size}
color={point.fill}
borderWidth={borderWidth}
borderColor={point.stroke}
Expand All @@ -118,46 +121,45 @@ const LineDots = ({
/>
))}
</g>
)}
</TransitionMotion>
)
}

LineDots.propTypes = {
lines: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
})
),

symbol: PropTypes.func,
size: PropTypes.number.isRequired,
color: PropTypes.func.isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.func.isRequired,

// labels
enableLabel: PropTypes.bool.isRequired,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
labelFormat: PropTypes.string,
labelYOffset: PropTypes.number,

// theming
theme: PropTypes.shape({
dots: PropTypes.shape({
textColor: PropTypes.string.isRequired,
fontSize: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,

// motion
...motionPropTypes,
}
)
}
const springConfig = {
motionDamping,
motionStiffness,
}

LineDots.defaultProps = {
// labels
enableLabel: false,
label: 'y',
return (
<TransitionMotion
styles={points.map(point => {
return {
key: point.key,
data: point,
style: {
x: spring(point.x, springConfig),
y: spring(point.y, springConfig),
size: spring(size, springConfig),
},
}
})}
>
{interpolatedStyles => (
<g>
{interpolatedStyles.map(({ key, style, data: point }) => (
<DotsItem
key={key}
{...style}
symbol={symbol}
color={point.fill}
borderWidth={borderWidth}
borderColor={point.stroke}
label={point.label}
labelYOffset={labelYOffset}
theme={theme}
/>
))}
</g>
)}
</TransitionMotion>
)
}
}

export default LineDots

0 comments on commit a6f5137

Please sign in to comment.