Skip to content

Commit

Permalink
Merge pull request #165 from JesperLekland/feature/min-max-clamp
Browse files Browse the repository at this point in the history
Feature/min max clamp
  • Loading branch information
JesperLekland authored Jun 10, 2018
2 parents da6ee11 + 3309d13 commit 6a08d0f
Show file tree
Hide file tree
Showing 25 changed files with 370 additions and 65 deletions.
16 changes: 7 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
5.x.0

* Added `cornerRadius` to progressCircle
* Adhere to `Svg` api with `height` and `width` instead of `flex: 1`
* StackedBarChart now supports `svg` prop for each data entry! Allowing onPress among other things.
* StackedAreaChart now supports `svg` prop for each area! Allowing onPress among other things
* The two above changes does remove the other "svg" props from the charts, for example `renderGradient`
that is now replaces with the same gradient API as the other charts (i.e children).
* PieChart supports `(start|end)Angle`
5.2.0

* Add `x(Min|Max)` and `y(Min|Max)`
* Add `clamp(X|Y)` to use in conjunction with above props (default `false`)
* Add xScale to StackedAreaChart
* Deprecate `AreaChart` prop `start` in favour of `baseline` due to better naming.




8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ yarn storybook
| contentInset | { top: 0, left: 0, right: 0, bottom: 0 } | An object that specifies how much fake "margin" to use inside of the SVG canvas. This is particularly helpful on Android where `overflow: "visible"` isn't supported and might cause clipping. Note: important to have same contentInset on axis's and chart |
| numberOfTicks | 10 | We use [d3-array](https://github.com/d3/d3-array#ticks) to evenly distribute the grid and dataPoints on the yAxis. This prop specifies how many "ticks" we should try to render. Note: important that this prop is the same on both the chart and on the yAxis |
| showGrid | true | Whether or not to show the grid lines |
| gridMin | undefined | Normally the graph tries to draw from edge to edge within the view bounds. Using this prop will allow the grid to reach further than the actual dataPoints. [Example](#gridmin/max) |
| gridMax | undefined | The same as "gridMin" but will instead increase the grids maximum value |
| children | undefined | One or many `react-native-svg` components that will be used to enhance your chart|
| yMin | undefined | Alter how the chart bounds are calculated |
| yMax | undefined | Alter how the chart bounds are calculated |
| xMin | undefined | Alter how the chart bounds are calculated |
| xMax | undefined | Alter how the chart bounds are calculated |
| children | undefined | One or many `react-native-svg` components that will be used to enhance your chart |

## Common arguments to children

Expand Down
13 changes: 12 additions & 1 deletion src/bar-chart/bar-chart-grouped.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class GroupedBarChart extends BarChart {
},
spacingInner,
spacingOuter,
clamp,
} = this.props

const { width } = this.state
Expand All @@ -23,6 +24,7 @@ class GroupedBarChart extends BarChart {
return scale.scaleLinear()
.domain(domain)
.range([ left, width - right ])
.clamp(clamp)
}

return scale.scaleBand()
Expand All @@ -41,6 +43,7 @@ class GroupedBarChart extends BarChart {
top = 0,
bottom = 0,
},
clamp,
} = this.props

const { height } = this.state
Expand All @@ -56,6 +59,7 @@ class GroupedBarChart extends BarChart {
return scale.scaleLinear()
.domain(domain)
.range([ height - bottom, top ])
.clamp(clamp)
}

calcAreas(x, y) {
Expand Down Expand Up @@ -138,7 +142,14 @@ class GroupedBarChart extends BarChart {
data.map(obj => obj.data.map(item => yAccessor({ item })))
)

return array.extent([ ...dataExtent, gridMax, gridMin ])
const extent = array.extent([ ...dataExtent, gridMax, gridMin ])

const {
yMin = extent[ 0 ],
yMax = extent[ 1 ],
} = this.props

return [ yMin, yMax ]
}

calcIndexes() {
Expand Down
17 changes: 16 additions & 1 deletion src/bar-chart/bar-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class BarChart extends PureComponent {
},
spacingInner,
spacingOuter,
clamp,
} = this.props

const { width } = this.state
Expand All @@ -36,6 +37,7 @@ class BarChart extends PureComponent {
return scale.scaleLinear()
.domain(domain)
.range([ left, width - right ])
.clamp(clamp)
}

return scale.scaleBand()
Expand All @@ -54,6 +56,7 @@ class BarChart extends PureComponent {
},
spacingInner,
spacingOuter,
clamp,
} = this.props

const { height } = this.state
Expand All @@ -69,6 +72,7 @@ class BarChart extends PureComponent {
return scale.scaleLinear()
.domain(domain)
.range([ height - bottom, top ])
.clamp(clamp)
}

calcAreas(x, y) {
Expand Down Expand Up @@ -107,7 +111,14 @@ class BarChart extends PureComponent {
const { data, gridMin, gridMax, yAccessor } = this.props
const values = data.map(obj => yAccessor({ item: obj }))

return array.extent([ ...values, gridMax, gridMin ])
const extent = array.extent([ ...values, gridMax, gridMin ])

const {
yMin = extent[ 0 ],
yMax = extent[ 1 ],
} = this.props

return [ yMin, yMax ]
}

calcIndexes() {
Expand Down Expand Up @@ -230,6 +241,10 @@ BarChart.propTypes = {
gridMin: PropTypes.number,
gridMax: PropTypes.number,
svg: PropTypes.object,

yMin: PropTypes.any,
yMax: PropTypes.any,
clamp: PropTypes.bool,
}

BarChart.defaultProps = {
Expand Down
23 changes: 20 additions & 3 deletions src/chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class Chart extends PureComponent {
},
gridMax,
gridMin,
clampX,
clampY,
svg,
children,
} = this.props
Expand All @@ -64,14 +66,23 @@ class Chart extends PureComponent {
const yExtent = array.extent([ ...yValues, gridMin, gridMax ])
const xExtent = array.extent([ ...xValues ])

const {
yMin = yExtent[ 0 ],
yMax = yExtent[ 1 ],
xMin = xExtent[ 0 ],
xMax = xExtent[ 1 ],
} = this.props

//invert range to support svg coordinate system
const y = yScale()
.domain(yExtent)
.domain([ yMin, yMax ])
.range([ height - bottom, top ])
.clamp(clampY)

const x = xScale()
.domain(xExtent)
.domain([ xMin, xMax ])
.range([ left, width - right ])
.clamp(clampX)

const paths = this.createPaths({
data: mappedData,
Expand Down Expand Up @@ -152,7 +163,13 @@ Chart.propTypes = {

gridMin: PropTypes.number,
gridMax: PropTypes.number,
gridProps: PropTypes.object,

yMin: PropTypes.any,
yMax: PropTypes.any,
xMin: PropTypes.any,
xMax: PropTypes.any,
clampX: PropTypes.bool,
clampY: PropTypes.bool,

xScale: PropTypes.func,
yScale: PropTypes.func,
Expand Down
43 changes: 35 additions & 8 deletions src/stacked-area-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class AreaStack extends PureComponent {
offset,
order,
svgs,
xAccessor,
xScale,
clampY,
clampX,
} = this.props

const { height, width } = this.state
Expand All @@ -67,24 +71,36 @@ class AreaStack extends PureComponent {
.offset(offset)
(data)

//double merge arrays to extract just the values
const values = array.merge(array.merge(series))
//double merge arrays to extract just the yValues
const yValues = array.merge(array.merge(series))
const xValues = data.map((item, index) => xAccessor({ item, index }))

const extent = array.extent([ ...values, gridMin, gridMax ])
const ticks = array.ticks(extent[ 0 ], extent[ 1 ], numberOfTicks)
const yExtent = array.extent([ ...yValues, gridMin, gridMax ])
const xExtent = array.extent(xValues)

const {
yMin = yExtent[ 0 ],
yMax = yExtent[ 1 ],
xMin = xExtent[ 0 ],
xMax = xExtent[ 1 ],
} = this.props

//invert range to support svg coordinate system
const y = scale.scaleLinear()
.domain([ extent[ 0 ], extent[ 1 ] ])
.domain([ yMin, yMax ])
.range([ height - bottom, top ])
.clamp(clampY)

const x = scale.scaleLinear()
.domain([ 0, data.length - 1 ])
const x = xScale()
.domain([ xMin, xMax ])
.range([ left, width - right ])
.clamp(clampX)

const ticks = y.ticks(numberOfTicks)

const areas = series.map((serie, index) => {
const path = shape.area()
.x((d, index) => x(index))
.x((d, index) => x(xAccessor({ item: d.data, index })))
.y0(d => y(d[ 0 ]))
.y1(d => y(d[ 1 ]))
.curve(curve)
Expand Down Expand Up @@ -168,6 +184,15 @@ AreaStack.propTypes = {
}),
numberOfTicks: PropTypes.number,
showGrid: PropTypes.bool,
xScale: PropTypes.func,
xAccessor: PropTypes.func,

yMin: PropTypes.any,
yMax: PropTypes.any,
xMin: PropTypes.any,
xMax: PropTypes.any,
clampX: PropTypes.bool,
clampY: PropTypes.bool,
}

AreaStack.defaultProps = {
Expand All @@ -179,6 +204,8 @@ AreaStack.defaultProps = {
contentInset: {},
numberOfTicks: 10,
showGrid: true,
xScale: scale.scaleLinear,
xAccessor: ({ index }) => index,
}

export default AreaStack
8 changes: 7 additions & 1 deletion src/x-axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class XAxis extends PureComponent {
numberOfTicks,
svg,
children,
min,
max,
} = this.props

const { height, width } = this.state
Expand All @@ -71,7 +73,9 @@ class XAxis extends PureComponent {

const values = data.map((item, index) => xAccessor({ item, index }))
const extent = array.extent(values)
const domain = scale === d3Scale.scaleBand ? values : extent
const domain = scale === d3Scale.scaleBand ?
values :
[ min || extent[ 0 ], max || extent[ 1 ] ]

const x = this._getX(domain)
const ticks = numberOfTicks ? x.ticks(numberOfTicks) : values
Expand Down Expand Up @@ -142,6 +146,8 @@ XAxis.propTypes = {
numberOfTicks: PropTypes.number,
xAccessor: PropTypes.func,
svg: PropTypes.object,
min: PropTypes.any,
max: PropTypes.any,
}

XAxis.defaultProps = {
Expand Down
16 changes: 10 additions & 6 deletions src/y-axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ class YAxis extends PureComponent {
yAccessor,
numberOfTicks,
formatLabel,
min,
max,
svg,
children,
} = this.props
Expand All @@ -75,15 +73,21 @@ class YAxis extends PureComponent {
const values = data.map((item, index) => yAccessor({ item, index }))

const extent = array.extent([ ...values, min, max ])
const ticks = scale === d3Scale.scaleBand ?
values :
array.ticks(extent[ 0 ], extent[ 1 ], numberOfTicks)

const domain = scale === d3Scale.scaleBand ? values : extent
const {
min = extent[ 0 ],
max = extent[ 1 ],
} = this.props

const domain = scale === d3Scale.scaleBand ? values : [ min, max ]

//invert range to support svg coordinate system
const y = this.getY(domain)

const ticks = scale === d3Scale.scaleBand ?
values :
y.ticks(numberOfTicks)

const longestValue = ticks
.map((value, index) => formatLabel(value, index))
.reduce((prev, curr) => prev.toString().length > curr.toString().length ? prev : curr, 0)
Expand Down
4 changes: 4 additions & 0 deletions storybook/stories/area-chart/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import { storiesOf } from '@storybook/react-native'

import Regular from './standard'
import Partial from './partial'
import WithGradient from './with-gradient'
import WithDifferentBase from './with-differen-base'
import ShowcaseCard from '../showcase-card'

storiesOf('AreaChart', module)
.addDecorator(getStory => <ShowcaseCard>{ getStory() }</ShowcaseCard>)
.add('Standard', () => <Regular/>)
.add('Partial', () => <Partial/>)
.add('With gradient', () => <WithGradient/>)
.add('With different base', () => <WithDifferentBase/>)
28 changes: 28 additions & 0 deletions storybook/stories/area-chart/with-differen-base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { AreaChart, Grid } from 'react-native-svg-charts'
import * as shape from 'd3-shape'
import * as array from 'd3-array'

class DifferentBaseExample extends React.PureComponent {

render() {

const data = [ 50, 10, 40, 95, -4, -24, 85, 91, 35, 53, -53, 24, 50, -20, -80 ]
const min = array.extent(data)[ 0 ]

return (
<AreaChart
style={{ height: 200 }}
data={ data }
contentInset={{ top: 30, bottom: 30 }}
curve={ shape.curveNatural }
svg={{ fill: 'rgba(134, 65, 244, 0.8)' }}
start={ min }
>
<Grid/>
</AreaChart>
)
}
}

export default DifferentBaseExample
2 changes: 2 additions & 0 deletions storybook/stories/area-stack/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { storiesOf } from '@storybook/react-native'

import Regular from './standard'
import WithTimeScale from './with-time-scale'
import WithGradient from './with-gradient'
import WithYAxis from './with-y-axis'
import ShowcaseCard from '../showcase-card'

Expand All @@ -11,3 +12,4 @@ storiesOf('StackedAreaChart', module)
.add('Standard', () => <Regular/>)
.add('With time scale', () => <WithTimeScale/>)
.add('With y axis', () => <WithYAxis/>)
.add('With gradient', () => <WithGradient/>)
Loading

0 comments on commit 6a08d0f

Please sign in to comment.