Skip to content

Commit

Permalink
feat(line): add support for layers to Line component
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Klug authored and Raphaël Benitte committed Nov 28, 2018
1 parent f872aaa commit 35911df
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 128 deletions.
306 changes: 178 additions & 128 deletions packages/line/src/Line.js
Expand Up @@ -6,7 +6,7 @@
* 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, { Fragment } from 'react'
import { area, line } from 'd3-shape'
import compose from 'recompose/compose'
import pure from 'recompose/pure'
Expand All @@ -33,126 +33,173 @@ import LineSlices from './LineSlices'
import LineDots from './LineDots'
import { LinePropTypes, LineDefaultProps } from './props'

const Line = ({
computedData,
lineGenerator,
areaGenerator,

margin,
width,
height,
outerWidth,
outerHeight,

axisTop,
axisRight,
axisBottom,
axisLeft,
enableGridX,
enableGridY,
gridXValues,
gridYValues,

lineWidth,
enableArea,
areaOpacity,
areaBlendMode,

enableDots,
dotSymbol,
dotSize,
dotColor,
dotBorderWidth,
dotBorderColor,
enableDotLabel,
dotLabel,
dotLabelFormat,
dotLabelYOffset,

markers,

theme,

animate,
motionStiffness,
motionDamping,

isInteractive,
tooltipFormat,
tooltip,
enableStackTooltip,

legends,
}) => {
const Line = props => {
const {
computedData,
lineGenerator,
areaGenerator,
layers,

margin,
width,
height,
outerWidth,
outerHeight,

axisTop,
axisRight,
axisBottom,
axisLeft,
enableGridX,
enableGridY,
gridXValues,
gridYValues,

lineWidth,
enableArea,
areaOpacity,
areaBlendMode,

enableDots,
dotSymbol,
dotSize,
dotColor,
dotBorderWidth,
dotBorderColor,
enableDotLabel,
dotLabel,
dotLabelFormat,
dotLabelYOffset,

markers,

theme,

animate,
motionStiffness,
motionDamping,

isInteractive,
tooltipFormat,
tooltip,
enableStackTooltip,

legends,
} = props

const motionProps = {
animate,
motionDamping,
motionStiffness,
}

const legendData = computedData.series
.map(line => ({
id: line.id,
label: line.id,
color: line.color,
}))
.reverse()

return (
<Container isInteractive={isInteractive} theme={theme}>
{({ showTooltip, hideTooltip }) => (
<SvgWrapper width={outerWidth} height={outerHeight} margin={margin} theme={theme}>
<Grid
theme={theme}
width={width}
height={height}
xScale={enableGridX ? computedData.xScale : null}
yScale={enableGridY ? computedData.yScale : null}
xValues={gridXValues}
yValues={gridYValues}
{...motionProps}
/>
<CartesianMarkers
markers={markers}
width={width}
height={height}
xScale={computedData.xScale}
yScale={computedData.yScale}
theme={theme}
/>
<Axes
xScale={computedData.xScale}
yScale={computedData.yScale}
width={width}
height={height}
theme={theme}
top={axisTop}
right={axisRight}
bottom={axisBottom}
left={axisLeft}
{...motionProps}
/>
{enableArea && (
{({ showTooltip, hideTooltip }) => {
const layerById = {
grid: (
<Grid
key="grid"
theme={theme}
width={width}
height={height}
xScale={enableGridX ? computedData.xScale : null}
yScale={enableGridY ? computedData.yScale : null}
xValues={gridXValues}
yValues={gridYValues}
{...motionProps}
/>
),
markers: (
<CartesianMarkers
key="markers"
markers={markers}
width={width}
height={height}
xScale={computedData.xScale}
yScale={computedData.yScale}
theme={theme}
/>
),
axes: (
<Axes
key="axes"
xScale={computedData.xScale}
yScale={computedData.yScale}
width={width}
height={height}
theme={theme}
top={axisTop}
right={axisRight}
bottom={axisBottom}
left={axisLeft}
{...motionProps}
/>
),
areas: null,
lines: (
<LineLines
key="lines"
lines={computedData.series}
lineGenerator={lineGenerator}
lineWidth={lineWidth}
{...motionProps}
/>
),
slices: null,
dots: null,
legends: legends.map((legend, i) => (
<BoxLegendSvg
key={i}
{...legend}
containerWidth={width}
containerHeight={height}
data={legendData}
theme={theme}
/>
)),
}

if (enableArea) {
layerById.areas = (
<LineAreas
key="areas"
areaGenerator={areaGenerator}
areaOpacity={areaOpacity}
areaBlendMode={areaBlendMode}
lines={computedData.series}
{...motionProps}
/>
)}
<LineLines
lines={computedData.series}
lineGenerator={lineGenerator}
lineWidth={lineWidth}
{...motionProps}
/>
{isInteractive &&
enableStackTooltip && (
<LineSlices
slices={computedData.slices}
height={height}
showTooltip={showTooltip}
hideTooltip={hideTooltip}
theme={theme}
tooltipFormat={tooltipFormat}
tooltip={tooltip}
/>
)}
{enableDots && (
)
}

if (isInteractive && enableStackTooltip) {
layerById.slices = (
<LineSlices
key="slices"
slices={computedData.slices}
height={height}
showTooltip={showTooltip}
hideTooltip={hideTooltip}
theme={theme}
tooltipFormat={tooltipFormat}
tooltip={tooltip}
/>
)
}

if (enableDots) {
layerById.dots = (
<LineDots
key="dots"
lines={computedData.series}
symbol={dotSymbol}
size={dotSize}
Expand All @@ -166,29 +213,32 @@ const Line = ({
theme={theme}
{...motionProps}
/>
)}
{legends.map((legend, i) => {
const legendData = computedData.series
.map(line => ({
id: line.id,
label: line.id,
color: line.color,
}))
.reverse()

return (
<BoxLegendSvg
key={i}
{...legend}
containerWidth={width}
containerHeight={height}
data={legendData}
theme={theme}
/>
)
})}
</SvgWrapper>
)}
)
}
return (
<SvgWrapper
width={outerWidth}
height={outerHeight}
margin={margin}
theme={theme}
>
{layers.map((layer, i) => {
if (typeof layer === 'function') {
return (
<Fragment key={i}>
{layer({
...props,
xScale: computedData.xScale,
yScale: computedData.yScale,
})}
</Fragment>
)
}
return layerById[layer]
})}
</SvgWrapper>
)
}}
</Container>
)
}
Expand Down
16 changes: 16 additions & 0 deletions packages/line/src/props.js
Expand Up @@ -37,6 +37,21 @@ export const LinePropTypes = {
yScale: scalePropType.isRequired,

computedData: PropTypes.object.isRequired,
layers: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.oneOf([
'grid',
'markers',
'axes',
'areas',
'lines',
'slices',
'dots',
'legends',
]),
PropTypes.func,
])
).isRequired,

curve: lineCurvePropType.isRequired,
areaGenerator: PropTypes.func.isRequired,
Expand Down Expand Up @@ -104,6 +119,7 @@ export const LineDefaultProps = {
max: 'auto',
},

layers: ['grid', 'markers', 'axes', 'areas', 'lines', 'slices', 'dots', 'legends'],
axisBottom: {},
axisLeft: {},
enableGridX: true,
Expand Down

0 comments on commit 35911df

Please sign in to comment.