Skip to content

Commit

Permalink
feat(line): add gradient support to line areas (#844)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnteWall committed May 17, 2020
1 parent ef1ee4c commit b84ec05
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/core/index.d.ts
Expand Up @@ -141,7 +141,7 @@ declare module '@nivo/core' {
| 'stepAfter'
| 'stepBefore'

type DataFormatter = (value: DatumValue) => string | number
export type DataFormatter = (value: DatumValue) => string | number

export function useValueFormatter(formatter?: DataFormatter | string): DataFormatter
}
3 changes: 2 additions & 1 deletion packages/line/index.d.ts
Expand Up @@ -13,6 +13,7 @@ import {
Theme,
MotionProps,
CartesianMarkerProps,
SvgDefsAndFill,
DataFormatter,
DatumValue as CoreDatumValue,
} from '@nivo/core'
Expand Down Expand Up @@ -193,7 +194,7 @@ declare module '@nivo/line' {
legends?: LegendProps[]
}

export interface LineSvgProps extends LineProps, MotionProps {
export interface LineSvgProps extends LineProps, MotionProps, SvgDefsAndFill<Datum> {
enablePointLabel?: boolean
pointLabel?: string
pointLabelYOffset?: number
Expand Down
8 changes: 4 additions & 4 deletions packages/line/src/Areas.js
Expand Up @@ -19,11 +19,11 @@ const Areas = ({ areaGenerator, areaOpacity, areaBlendMode, lines }) => {
{lines
.slice(0)
.reverse()
.map(({ id, data, color: areaColor }) => (
.map(({ id, data, color: areaColor, fill }) => (
<path
key={id}
d={areaGenerator(data.map(d => d.position))}
fill={areaColor}
fill={fill ? fill : areaColor}
fillOpacity={areaOpacity}
strokeWidth={0}
style={{
Expand All @@ -40,7 +40,7 @@ const Areas = ({ areaGenerator, areaOpacity, areaBlendMode, lines }) => {
{lines
.slice(0)
.reverse()
.map(({ id, data, color: areaColor }) => (
.map(({ id, data, color: areaColor, fill }) => (
<SmartMotion
key={id}
style={spring => ({
Expand All @@ -52,7 +52,7 @@ const Areas = ({ areaGenerator, areaOpacity, areaBlendMode, lines }) => {
<path
key={id}
d={style.d}
fill={areaColor}
fill={fill ? fill : areaColor}
fillOpacity={areaOpacity}
strokeWidth={0}
style={{ mixBlendMode: areaBlendMode }}
Expand Down
16 changes: 14 additions & 2 deletions packages/line/src/Line.js
Expand Up @@ -7,7 +7,14 @@
* file that was distributed with this source code.
*/
import React, { Fragment, useState, useMemo } from 'react'
import { withContainer, useDimensions, useTheme, SvgWrapper, CartesianMarkers } from '@nivo/core'
import {
bindDefs,
withContainer,
useDimensions,
useTheme,
SvgWrapper,
CartesianMarkers,
} from '@nivo/core'
import { useInheritedColor } from '@nivo/colors'
import { Axes, Grid } from '@nivo/axes'
import { BoxLegendSvg } from '@nivo/legends'
Expand Down Expand Up @@ -62,6 +69,9 @@ const Line = props => {
pointLabelFormat,
pointLabelYOffset,

defs,
fill,

markers,

legends,
Expand Down Expand Up @@ -185,6 +195,8 @@ const Line = props => {
)),
}

const boundDefs = bindDefs(defs, series, fill)

if (enableArea) {
layerById.areas = (
<Areas
Expand Down Expand Up @@ -278,7 +290,7 @@ const Line = props => {
}

return (
<SvgWrapper width={outerWidth} height={outerHeight} margin={margin}>
<SvgWrapper defs={boundDefs} width={outerWidth} height={outerHeight} margin={margin}>
{layers.map((layer, i) => {
if (typeof layer === 'function') {
return (
Expand Down
12 changes: 4 additions & 8 deletions packages/line/src/props.js
Expand Up @@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
import PropTypes from 'prop-types'
import { lineCurvePropType, blendModePropType, motionPropTypes } from '@nivo/core'
import { lineCurvePropType, blendModePropType, motionPropTypes, defsPropTypes } from '@nivo/core'
import { ordinalColorsPropType } from '@nivo/colors'
import { axisPropType } from '@nivo/axes'
import { scalePropType } from '@nivo/scales'
Expand Down Expand Up @@ -112,11 +112,6 @@ const commonPropTypes = {
PropTypes.instanceOf(Date),
]).isRequired,
lineWidth: PropTypes.number.isRequired,
defs: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
})
).isRequired,

legends: PropTypes.arrayOf(PropTypes.shape(LegendPropShape)).isRequired,

Expand All @@ -139,6 +134,7 @@ export const LinePropTypes = {
enablePointLabel: PropTypes.bool.isRequired,
useMesh: PropTypes.bool.isRequired,
...motionPropTypes,
...defsPropTypes,
}

export const LineCanvasPropTypes = {
Expand Down Expand Up @@ -188,8 +184,6 @@ const commonDefaultProps = {
areaBlendMode: 'normal',
lineWidth: 2,

defs: [],

legends: [],

isInteractive: true,
Expand All @@ -209,6 +203,8 @@ export const LineDefaultProps = {
animate: true,
motionStiffness: 90,
motionDamping: 15,
defs: [],
fill: [],
}

export const LineCanvasDefaultProps = {
Expand Down
25 changes: 22 additions & 3 deletions packages/line/stories/line.stories.js
Expand Up @@ -12,7 +12,7 @@ import last from 'lodash/last'
import { storiesOf } from '@storybook/react'
import { withKnobs, boolean, select } from '@storybook/addon-knobs'
import { generateDrinkStats } from '@nivo/generators'
import { Defs } from '@nivo/core'
import { Defs, linearGradientDef } from '@nivo/core'
import { area, curveMonotoneX } from 'd3-shape'
import * as time from 'd3-time'
import { timeFormat } from 'd3-time-format'
Expand Down Expand Up @@ -110,7 +110,7 @@ stories.add(
By default, \`xScale\` is a point scale, but you can switch to linear using
the \`xScale.type\` property. It supports irregular intervals while \`point\`
scale doesn't.
If you want missing datums to appear as holes instead of connecting defined ones,
you should set their y value to \`null\`.
`,
Expand Down Expand Up @@ -526,7 +526,7 @@ stories.add(
text: `
Please note that when using stacked y scale with variable length/data holes,
if one of the y value is \`null\` all subsequent values will be skipped
as we cannot properly compute the sum.
as we cannot properly compute the sum.
`,
},
}
Expand Down Expand Up @@ -1011,3 +1011,22 @@ stories.add(
},
}
)

stories.add('area gradients', () => (
<Line
{...commonProperties}
enableArea={true}
yScale={{
type: 'linear',
stacked: true,
}}
curve={select('curve', curveOptions, 'linear')}
defs={[
linearGradientDef('gradientA', [
{ offset: 0, color: 'inherit' },
{ offset: 100, color: 'inherit', opacity: 0 },
]),
]}
fill={[{ match: '*', id: 'gradientA' }]}
/>
))
2 changes: 2 additions & 0 deletions website/src/data/components/line/meta.yml
Expand Up @@ -40,6 +40,8 @@ Line:
link: line--formatting-values
- label: adding custom layers
link: line--custom-layers
- label: area gradients
link: line--area-gradients
description: |
Line chart with stacking ability.
Expand Down
2 changes: 2 additions & 0 deletions website/src/data/components/line/props.js
Expand Up @@ -13,6 +13,7 @@ import {
motionProperties,
getLegendsProps,
groupProperties,
defsProperties,
} from '../../../lib/componentProperties'

const props = [
Expand Down Expand Up @@ -277,6 +278,7 @@ const props = [
controlType: 'blendMode',
group: 'Style',
},
...defsProperties('Style', ['svg']),
{
key: 'layers',
group: 'Customization',
Expand Down

0 comments on commit b84ec05

Please sign in to comment.