react-native-svg-charts
Advanced tools
Comparing version 5.2.1 to 5.3.0
@@ -1,5 +0,25 @@ | ||
5.2.0 | ||
# 5.3.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 along with (x|y)Accessor | ||
### Contributions | ||
- update README ([@andrewdazs](https://github.com/andrewdazs) and [@iammosespaulr](https://github.com/iammosespaulr)) | ||
- fix crash in Axis component ([@krzysztof-miemiec](https://github.com/krzysztof-miemiec) - [#238](https://github.com/JesperLekland/react-native-svg-charts/pull/238)) | ||
- Introduce grouped LineChart ([@alburdette619](https://github.com/alburdette619) - [#240](https://github.com/JesperLekland/react-native-svg-charts/pull/240)) | ||
- Introduce grouped StackedBarChart ([@alburdette619](https://github.com/alburdette619) - #239) | ||
- Fix 'transparent' color for X-Axis and Y-Axis in RN 0.57 ([@denieler](https://github.com/denieler) - #256) | ||
- Added extra props to axis children ([@alburdette619](https://github.com/alburdette619) - #276) | ||
- Create interaction handle during animation ([@Jyrno42](https://github.com/Jyrno42) - #314) | ||
- Stacked Area Chart: Pass `areas` down to children ([@attitude](https://github.com/attitude) - #316) | ||
- Added more props to axis children ([@buschco](https://github.com/buschco) - #326) | ||
- Fix blinking animation ([@andycloke](https://github.com/andycloke) - #329) | ||
- Fix YAxis using Unnecessary max/min value before definition ([@saji-ryu](https://github.com/saji-ryu) - #354) | ||
- prevent crash on undefined data ([@usrbowe](https://github.com/usrbowe) - #355) | ||
* remove eslint formatting in favor of prettier (easier to contribute) | ||
* remove circleci checks as they didn't add any value (easier to contribute) | ||
# 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 along with (x|y)Accessor |
12
index.js
@@ -20,6 +20,3 @@ /* eslint-disable no-unused-vars */ | ||
> | ||
{ | ||
'Welcome to "react-native-svg-charts". \n' + | ||
'To see showcases of all our charts\n' | ||
} | ||
{'Welcome to "react-native-svg-charts". \n' + 'To see showcases of all our charts\n'} | ||
</Text> | ||
@@ -32,11 +29,8 @@ <Text | ||
> | ||
{ | ||
'• Stop your packager \n' + | ||
{'• Stop your packager \n' + | ||
'• run "yarn storybook" \n' + | ||
'• Go to "localhost:7008" in your browser\n' + | ||
'• reload your device \n' + | ||
'• browse our charts' | ||
} | ||
'• browse our charts'} | ||
</Text> | ||
</View> | ||
@@ -43,0 +37,0 @@ ) |
172
package.json
{ | ||
"name": "react-native-svg-charts", | ||
"version": "5.2.1", | ||
"private": false, | ||
"description": "Customizable charts (Line, Bar, Area, Pie, Circle, Progress) for React Native", | ||
"main": "src/index.js", | ||
"scripts": { | ||
"start": "node node_modules/react-native/local-cli/cli.js start", | ||
"test": "jest", | ||
"storybook": "storybook start -p 7008", | ||
"eslint": "./node_modules/.bin/eslint ." | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "yarn lint-staged" | ||
"name": "react-native-svg-charts", | ||
"version": "5.3.0", | ||
"private": false, | ||
"description": "Customizable charts (Line, Bar, Area, Pie, Circle, Progress) for React Native", | ||
"main": "src/index.js", | ||
"scripts": { | ||
"start": "node node_modules/react-native/local-cli/cli.js start", | ||
"test": "jest", | ||
"storybook": "storybook start -p 7008", | ||
"eslint": "./node_modules/.bin/eslint ." | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "pretty-quick --staged" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.js": "eslint" | ||
}, | ||
"keywords": [ | ||
"react-native", | ||
"react-component", | ||
"react-native-component", | ||
"react", | ||
"mobile", | ||
"ios", | ||
"android", | ||
"vector", | ||
"charts", | ||
"chart", | ||
"d3" | ||
], | ||
"author": { | ||
"name": "Jesper Lekland", | ||
"email": "jesper.lekland@push2prod.se" | ||
}, | ||
"homepage": "https://github.com/JesperLekland/react-native-svg-charts", | ||
"bugs": { | ||
"url": "https://github.com/JesperLekland/react-native-svg-charts/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/JesperLekland/react-native-svg-charts.git" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
"d3-array": "^1.2.0", | ||
"d3-interpolate-path": "2.0.0", | ||
"d3-scale": "^1.0.6", | ||
"d3-shape": "^1.0.6", | ||
"prop-types": "^15.6.0" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.0.0-alpha.12", | ||
"react-native": ">=0.46.0", | ||
"react-native-svg": "^6.2.1||^7.0.3" | ||
}, | ||
"devDependencies": { | ||
"@storybook/addon-actions": "^3.2.14", | ||
"@storybook/addon-knobs": "^3.2.14", | ||
"@storybook/addon-links": "^3.2.14", | ||
"@storybook/react-native": "^3.2.14", | ||
"babel-eslint": "^7.2.3", | ||
"babel-jest": "20.0.1", | ||
"babel-preset-react-native": "1.9.1", | ||
"date-fns": "^1.28.5", | ||
"eslint": "^4.19.0", | ||
"eslint-config-standard": "^10.2.1", | ||
"eslint-plugin-import": "^2.6.0", | ||
"eslint-plugin-node": "^5.1.0", | ||
"eslint-plugin-promise": "^3.5.0", | ||
"eslint-plugin-react": "^7.7.0", | ||
"eslint-plugin-react-native": "^2.3.2", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"husky": "^3.0.0", | ||
"jest": "20.0.1", | ||
"lint-staged": "^7.1.3", | ||
"prettier": "^1.18.2", | ||
"pretty-quick": "^1.11.1", | ||
"react": "16.2.0", | ||
"react-dom": ">=16.0.0-alpha.12", | ||
"react-native": "0.52.2", | ||
"react-native-svg": "^6.2.1", | ||
"react-test-renderer": "16.0.0-alpha.6" | ||
}, | ||
"jest": { | ||
"preset": "react-native" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.js": "eslint" | ||
}, | ||
"keywords": [ | ||
"react-native", | ||
"react-component", | ||
"react-native-component", | ||
"react", | ||
"mobile", | ||
"ios", | ||
"android", | ||
"vector", | ||
"charts", | ||
"chart", | ||
"d3" | ||
], | ||
"author": { | ||
"name": "Jesper Lekland", | ||
"email": "jesper.lekland@push2prod.se" | ||
}, | ||
"homepage": "https://github.com/JesperLekland/react-native-svg-charts", | ||
"bugs": { | ||
"url": "https://github.com/JesperLekland/react-native-svg-charts/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/JesperLekland/react-native-svg-charts.git" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
"d3-array": "^1.2.0", | ||
"d3-interpolate-path": "2.0.0", | ||
"d3-scale": "^1.0.6", | ||
"d3-shape": "^1.0.6", | ||
"prop-types": "^15.6.0" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.0.0-alpha.12", | ||
"react-native": ">=0.46.0", | ||
"react-native-svg": "^6.2.1" | ||
}, | ||
"devDependencies": { | ||
"date-fns": "^1.28.5", | ||
"@storybook/addon-actions": "^3.2.14", | ||
"@storybook/addon-knobs": "^3.2.14", | ||
"@storybook/addon-links": "^3.2.14", | ||
"@storybook/react-native": "^3.2.14", | ||
"babel-eslint": "^7.2.3", | ||
"babel-jest": "20.0.1", | ||
"babel-preset-react-native": "1.9.1", | ||
"eslint": "^4.19.0", | ||
"eslint-config-standard": "^10.2.1", | ||
"eslint-plugin-import": "^2.6.0", | ||
"eslint-plugin-node": "^5.1.0", | ||
"eslint-plugin-promise": "^3.5.0", | ||
"eslint-plugin-react": "^7.7.0", | ||
"eslint-plugin-react-native": "^2.3.2", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"husky": "^1.0.0-rc.8", | ||
"jest": "20.0.1", | ||
"lint-staged": "^7.1.3", | ||
"react": "16.2.0", | ||
"react-dom": ">=16.0.0-alpha.12", | ||
"react-native": "0.52.2", | ||
"react-native-svg": "^6.2.1", | ||
"react-test-renderer": "16.0.0-alpha.6" | ||
}, | ||
"jest": { | ||
"preset": "react-native" | ||
} | ||
} |
@@ -10,2 +10,4 @@ # react-native-svg-charts | ||
### Looking for maintainers! I alone don't have the time to maintain this library anymore. Preferably looking for somebody who uses this library in their proffesional work (how I originally got the time to maintain). | ||
### version 5 is now available! | ||
@@ -576,12 +578,2 @@ A much improved decorator system has been introduced, allowing for greater flexibility and less complexity. | ||
#### Arguments to children | ||
| Property | Description | ||
| --- | --- | | ||
| width | the width of the canvas in pixels | | ||
| height | the height of the canvas in pixels | | ||
| data | the same data array provided to the chart, use this to map over your data points if you want decorators on each point | | ||
### YAxis | ||
@@ -747,3 +739,3 @@ | ||
### Examples | ||
There is a ton of examples over at [react-native-svg-chart-exampels](https://github.com/JesperLekland/react-native-svg-charts-examples) | ||
There are tons of examples over at [react-native-svg-chart-examples](https://github.com/JesperLekland/react-native-svg-charts-examples) | ||
@@ -750,0 +742,0 @@ |
import React, { Component } from 'react' | ||
import { InteractionManager } from 'react-native' | ||
import PropTypes from 'prop-types' | ||
@@ -7,3 +8,2 @@ import { Path } from 'react-native-svg' | ||
class AnimatedPath extends Component { | ||
constructor(props) { | ||
@@ -17,3 +17,3 @@ super(props) | ||
const { d: newD, animate } = this.props | ||
const { d: oldD } = props | ||
const { d: oldD } = props | ||
@@ -30,3 +30,3 @@ this.newD = newD | ||
this.newD = newD | ||
this.newD = newD | ||
this.interpolator = interpolate.interpolatePath(oldD, newD) | ||
@@ -39,2 +39,3 @@ | ||
cancelAnimationFrame(this.animation) | ||
this._clearInteraction() | ||
} | ||
@@ -46,2 +47,5 @@ | ||
if (!start) { | ||
this._clearInteraction() | ||
this.handle = InteractionManager.createInteractionHandle() | ||
start = timestamp | ||
@@ -58,2 +62,3 @@ } | ||
// Stop our animation loop. | ||
this._clearInteraction() | ||
return | ||
@@ -76,7 +81,15 @@ } | ||
_clearInteraction() { | ||
if (this.handle) { | ||
InteractionManager.clearInteractionHandle(this.handle) | ||
this.handle = null | ||
} | ||
} | ||
render() { | ||
return ( | ||
<Path | ||
ref={ ref => this.component = ref } | ||
{ ...this.props } | ||
ref={(ref) => (this.component = ref)} | ||
{...this.props} | ||
d={this.props.animate ? this.state.d : this.props.d} | ||
/> | ||
@@ -83,0 +96,0 @@ ) |
import * as shape from 'd3-shape' | ||
import PropTypes from 'prop-types' | ||
import Chart from './chart' | ||
import Chart from './chart/chart' | ||
class AreaChart extends Chart { | ||
createPaths({ data, x, y }) { | ||
const { curve, start } = this.props | ||
const area = shape.area() | ||
.x(d => x(d.x)) | ||
const area = shape | ||
.area() | ||
.x((d) => x(d.x)) | ||
.y0(y(start)) | ||
.y1(d => y(d.y)) | ||
.defined(item => typeof item.y === 'number') | ||
.curve(curve) | ||
(data) | ||
.y1((d) => y(d.y)) | ||
.defined((item) => typeof item.y === 'number') | ||
.curve(curve)(data) | ||
const line = shape.line() | ||
const line = shape | ||
.line() | ||
.x((d) => x(d.x)) | ||
.y(d => y(d.y)) | ||
.defined(item => typeof item.y === 'number') | ||
.curve(curve) | ||
(data) | ||
.y((d) => y(d.y)) | ||
.defined((item) => typeof item.y === 'number') | ||
.curve(curve)(data) | ||
@@ -25,0 +24,0 @@ return { |
@@ -8,10 +8,6 @@ import PropTypes from 'prop-types' | ||
class GroupedBarChart extends BarChart { | ||
calcXScale(domain) { | ||
const { | ||
horizontal, | ||
contentInset: { | ||
left = 0, | ||
right = 0, | ||
}, | ||
contentInset: { left = 0, right = 0 }, | ||
spacingInner, | ||
@@ -25,13 +21,15 @@ spacingOuter, | ||
if (horizontal) { | ||
return scale.scaleLinear() | ||
return scale | ||
.scaleLinear() | ||
.domain(domain) | ||
.range([ left, width - right ]) | ||
.range([left, width - right]) | ||
.clamp(clamp) | ||
} | ||
return scale.scaleBand() | ||
return scale | ||
.scaleBand() | ||
.domain(domain) | ||
.range([ left, width - right ]) | ||
.paddingInner([ spacingInner ]) | ||
.paddingOuter([ spacingOuter ]) | ||
.range([left, width - right]) | ||
.paddingInner([spacingInner]) | ||
.paddingOuter([spacingOuter]) | ||
} | ||
@@ -44,6 +42,3 @@ | ||
spacingOuter, | ||
contentInset: { | ||
top = 0, | ||
bottom = 0, | ||
}, | ||
contentInset: { top = 0, bottom = 0 }, | ||
clamp, | ||
@@ -55,12 +50,14 @@ } = this.props | ||
if (horizontal) { | ||
return scale.scaleBand() | ||
return scale | ||
.scaleBand() | ||
.domain(domain) | ||
.range([ top, height - bottom ]) | ||
.paddingInner([ spacingInner ]) | ||
.paddingOuter([ spacingOuter ]) | ||
.range([top, height - bottom]) | ||
.paddingInner([spacingInner]) | ||
.paddingOuter([spacingOuter]) | ||
} | ||
return scale.scaleLinear() | ||
return scale | ||
.scaleLinear() | ||
.domain(domain) | ||
.range([ height - bottom, top ]) | ||
.range([height - bottom, top]) | ||
.clamp(clamp) | ||
@@ -72,8 +69,7 @@ } | ||
const _data = data.map(obj => { | ||
const _data = data.map((obj) => { | ||
const { svg = {} } = obj | ||
return { | ||
...obj, | ||
data: obj.data.map(item => { | ||
data: obj.data.map((item) => { | ||
if (typeof item === 'number') { | ||
@@ -101,3 +97,2 @@ return { | ||
if (horizontal) { | ||
const barWidth = y.bandwidth() / data.length | ||
@@ -109,16 +104,16 @@ | ||
bar: item, | ||
path: shape.area() | ||
.y((value, _index) => _index === 0 ? | ||
y(valueIndex) + (barWidth * collectionIndex) : | ||
y(valueIndex) + barWidth + (barWidth * collectionIndex)) | ||
path: shape | ||
.area() | ||
.y((value, _index) => | ||
_index === 0 | ||
? y(valueIndex) + barWidth * collectionIndex | ||
: y(valueIndex) + barWidth + barWidth * collectionIndex | ||
) | ||
.x0(x(0)) | ||
.x1(value => x(value)) | ||
.defined(value => typeof value === 'number') | ||
([ item.value, item.value ]), | ||
.x1((value) => x(value)) | ||
.defined((value) => typeof value === 'number')([item.value, item.value]), | ||
}) | ||
}) | ||
}) | ||
} else { | ||
const barWidth = x.bandwidth() / data.length | ||
@@ -130,10 +125,12 @@ | ||
bar: item, | ||
path: shape.area() | ||
.x((value, _index) => _index === 0 ? | ||
x(valueIndex) + (barWidth * collectionIndex) : | ||
x(valueIndex) + barWidth + (barWidth * collectionIndex)) | ||
path: shape | ||
.area() | ||
.x((value, _index) => | ||
_index === 0 | ||
? x(valueIndex) + barWidth * collectionIndex | ||
: x(valueIndex) + barWidth + barWidth * collectionIndex | ||
) | ||
.y0(y(0)) | ||
.y1(value => y(value)) | ||
.defined(value => typeof value === 'number') | ||
([ item.value, item.value ]), | ||
.y1((value) => y(value)) | ||
.defined((value) => typeof value === 'number')([item.value, item.value]), | ||
}) | ||
@@ -149,14 +146,9 @@ }) | ||
const { data, yAccessor, gridMin, gridMax } = this.props | ||
const dataExtent = array.merge( | ||
data.map(obj => obj.data.map(item => yAccessor({ item }))) | ||
) | ||
const dataExtent = array.merge(data.map((obj) => obj.data.map((item) => yAccessor({ item })))) | ||
const extent = array.extent([ ...dataExtent, gridMax, gridMin ]) | ||
const extent = array.extent([...dataExtent, gridMax, gridMin]) | ||
const { | ||
yMin = extent[ 0 ], | ||
yMax = extent[ 1 ], | ||
} = this.props | ||
const { yMin = extent[0], yMax = extent[1] } = this.props | ||
return [ yMin, yMax ] | ||
return [yMin, yMax] | ||
} | ||
@@ -166,3 +158,3 @@ | ||
const { data } = this.props | ||
return data[ 0 ].data.map((_, index) => index) | ||
return data[0].data.map((_, index) => index) | ||
} | ||
@@ -173,8 +165,10 @@ } | ||
...BarChart.propTypes, | ||
data: PropTypes.arrayOf(PropTypes.shape({ | ||
data: PropTypes.array.isRequired, | ||
svg: PropTypes.object, | ||
})).isRequired, | ||
data: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
data: PropTypes.array.isRequired, | ||
svg: PropTypes.object, | ||
}) | ||
).isRequired, | ||
} | ||
export default GroupedBarChart |
@@ -11,3 +11,2 @@ import * as array from 'd3-array' | ||
class BarChart extends PureComponent { | ||
state = { | ||
@@ -19,3 +18,7 @@ width: 0, | ||
_onLayout(event) { | ||
const { nativeEvent: { layout: { height, width } } } = event | ||
const { | ||
nativeEvent: { | ||
layout: { height, width }, | ||
}, | ||
} = event | ||
this.setState({ height, width }) | ||
@@ -27,6 +30,3 @@ } | ||
horizontal, | ||
contentInset: { | ||
left = 0, | ||
right = 0, | ||
}, | ||
contentInset: { left = 0, right = 0 }, | ||
spacingInner, | ||
@@ -40,13 +40,15 @@ spacingOuter, | ||
if (horizontal) { | ||
return scale.scaleLinear() | ||
return scale | ||
.scaleLinear() | ||
.domain(domain) | ||
.range([ left, width - right ]) | ||
.range([left, width - right]) | ||
.clamp(clamp) | ||
} | ||
return scale.scaleBand() | ||
return scale | ||
.scaleBand() | ||
.domain(domain) | ||
.range([ left, width - right ]) | ||
.paddingInner([ spacingInner ]) | ||
.paddingOuter([ spacingOuter ]) | ||
.range([left, width - right]) | ||
.paddingInner([spacingInner]) | ||
.paddingOuter([spacingOuter]) | ||
} | ||
@@ -57,6 +59,3 @@ | ||
horizontal, | ||
contentInset: { | ||
top = 0, | ||
bottom = 0, | ||
}, | ||
contentInset: { top = 0, bottom = 0 }, | ||
spacingInner, | ||
@@ -70,12 +69,14 @@ spacingOuter, | ||
if (horizontal) { | ||
return scale.scaleBand() | ||
return scale | ||
.scaleBand() | ||
.domain(domain) | ||
.range([ top, height - bottom ]) | ||
.paddingInner([ spacingInner ]) | ||
.paddingOuter([ spacingOuter ]) | ||
.range([top, height - bottom]) | ||
.paddingInner([spacingInner]) | ||
.paddingOuter([spacingOuter]) | ||
} | ||
return scale.scaleLinear() | ||
return scale | ||
.scaleLinear() | ||
.domain(domain) | ||
.range([ height - bottom, top ]) | ||
.range([height - bottom, top]) | ||
.clamp(clamp) | ||
@@ -87,3 +88,3 @@ } | ||
const values = data.map(item => yAccessor({ item })) | ||
const values = data.map((item) => yAccessor({ item })) | ||
@@ -93,10 +94,8 @@ if (horizontal) { | ||
bar, | ||
path: shape.area() | ||
.y((value, _index) => _index === 0 ? | ||
y(index) : | ||
y(index) + y.bandwidth()) | ||
path: shape | ||
.area() | ||
.y((value, _index) => (_index === 0 ? y(index) : y(index) + y.bandwidth())) | ||
.x0(x(0)) | ||
.x1(value => x(value)) | ||
.defined(value => typeof value === 'number') | ||
([ values[ index ], values[ index ] ]), | ||
.x1((value) => x(value)) | ||
.defined((value) => typeof value === 'number')([values[index], values[index]]), | ||
})) | ||
@@ -107,10 +106,8 @@ } | ||
bar, | ||
path: shape.area() | ||
path: shape | ||
.area() | ||
.y0(y(0)) | ||
.y1(value => y(value)) | ||
.x((value, _index) => _index === 0 ? | ||
x(index) : | ||
x(index) + x.bandwidth()) | ||
.defined(value => typeof value === 'number') | ||
([ values[ index ], values[ index ] ]), | ||
.y1((value) => y(value)) | ||
.x((value, _index) => (_index === 0 ? x(index) : x(index) + x.bandwidth())) | ||
.defined((value) => typeof value === 'number')([values[index], values[index]]), | ||
})) | ||
@@ -121,12 +118,9 @@ } | ||
const { data, gridMin, gridMax, yAccessor } = this.props | ||
const values = data.map(obj => yAccessor({ item: obj })) | ||
const values = data.map((obj) => yAccessor({ item: obj })) | ||
const extent = array.extent([ ...values, gridMax, gridMin ]) | ||
const extent = array.extent([...values, gridMax, gridMin]) | ||
const { | ||
yMin = extent[ 0 ], | ||
yMax = extent[ 1 ], | ||
} = this.props | ||
const { yMin = extent[0], yMax = extent[1] } = this.props | ||
return [ yMin, yMax ] | ||
return [yMin, yMax] | ||
} | ||
@@ -140,12 +134,3 @@ | ||
render() { | ||
const { | ||
data, | ||
animate, | ||
animationDuration, | ||
style, | ||
numberOfTicks, | ||
svg, | ||
horizontal, | ||
children, | ||
} = this.props | ||
const { data, animate, animationDuration, style, numberOfTicks, svg, horizontal, children } = this.props | ||
@@ -155,3 +140,3 @@ const { height, width } = this.state | ||
if (data.length === 0) { | ||
return <View style={ style }/> | ||
return <View style={style} /> | ||
} | ||
@@ -161,3 +146,3 @@ | ||
const indexes = this.calcIndexes() | ||
const ticks = array.ticks(extent[ 0 ], extent[ 1 ], numberOfTicks) | ||
const ticks = array.ticks(extent[0], extent[1], numberOfTicks) | ||
@@ -172,8 +157,5 @@ const xDomain = horizontal ? extent : indexes | ||
const areas = this.calcAreas(x, y) | ||
.filter(area => ( | ||
area.bar !== null && | ||
area.bar !== undefined && | ||
area.path !== null | ||
)) | ||
const areas = this.calcAreas(x, y).filter( | ||
(area) => area.bar !== null && area.bar !== undefined && area.path !== null | ||
) | ||
@@ -191,43 +173,35 @@ const extraProps = { | ||
return ( | ||
<View style={ style }> | ||
<View | ||
style={{ flex: 1 }} | ||
onLayout={ event => this._onLayout(event) } | ||
> | ||
{ | ||
height > 0 && width > 0 && | ||
<View style={style}> | ||
<View style={{ flex: 1 }} onLayout={(event) => this._onLayout(event)}> | ||
{height > 0 && width > 0 && ( | ||
<Svg style={{ height, width }}> | ||
{ | ||
React.Children.map(children, child => { | ||
if(child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
}) | ||
} | ||
{ | ||
areas.map((area, index) => { | ||
{React.Children.map(children, (child) => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
})} | ||
{areas.map((area, index) => { | ||
const { | ||
bar: { svg: barSvg = {} }, | ||
path, | ||
} = area | ||
const { bar: { svg: barSvg = {} }, path } = area | ||
return ( | ||
<Path | ||
key={ index } | ||
{ ...svg } | ||
{ ...barSvg } | ||
d={ path } | ||
animate={ animate } | ||
animationDuration={ animationDuration } | ||
/> | ||
) | ||
}) | ||
} | ||
{ | ||
React.Children.map(children, child => { | ||
if(child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
}) | ||
} | ||
return ( | ||
<Path | ||
key={index} | ||
{...svg} | ||
{...barSvg} | ||
d={path} | ||
animate={animate} | ||
animationDuration={animationDuration} | ||
/> | ||
) | ||
})} | ||
{React.Children.map(children, (child) => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
})} | ||
</Svg> | ||
} | ||
)} | ||
</View> | ||
@@ -240,6 +214,3 @@ </View> | ||
BarChart.propTypes = { | ||
data: PropTypes.arrayOf(PropTypes.oneOfType([ | ||
PropTypes.number, | ||
PropTypes.object, | ||
])).isRequired, | ||
data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.object])).isRequired, | ||
style: PropTypes.any, | ||
@@ -246,0 +217,0 @@ spacingInner: PropTypes.number, |
@@ -8,9 +8,9 @@ import React from 'react' | ||
if (data[ 0 ].hasOwnProperty('data')) { | ||
return <BarChartGrouped { ...props }/> | ||
if (data[0] && data[0].hasOwnProperty('data')) { | ||
return <BarChartGrouped {...props} /> | ||
} | ||
return <BarChart { ...props }/> | ||
return <BarChart {...props} /> | ||
} | ||
export default BarChartGate |
@@ -5,3 +5,2 @@ import React from 'react' | ||
class Card extends React.PureComponent { | ||
state = { | ||
@@ -17,14 +16,7 @@ hasError: false, | ||
render() { | ||
const { hasError } = this.state | ||
const { hasError } = this.state | ||
const { style, children } = this.props | ||
return ( | ||
<View style={ [ styles.container, style ] }> | ||
{ | ||
hasError ? | ||
<Text>{'Something went wrong'}</Text> : | ||
children | ||
} | ||
</View> | ||
<View style={[styles.container, style]}>{hasError ? <Text>{'Something went wrong'}</Text> : children}</View> | ||
) | ||
@@ -31,0 +23,0 @@ } |
@@ -5,14 +5,5 @@ import React from 'react' | ||
class HorizontalLine extends React.Component { | ||
render() { | ||
const { y, value, ...other } = this.props | ||
return ( | ||
<Line | ||
x1={ '0%' } | ||
x2={ '100%' } | ||
y1={ y(value) } | ||
y2={ y(value) } | ||
{ ...other } | ||
/> | ||
) | ||
return <Line x1={'0%'} x2={'100%'} y1={y(value)} y2={y(value)} {...other} /> | ||
} | ||
@@ -19,0 +10,0 @@ } |
@@ -7,14 +7,6 @@ import PropTypes from 'prop-types' | ||
if (isNaN(value)) { | ||
return <Circle/> | ||
return <Circle /> | ||
} | ||
return ( | ||
<Circle | ||
cx={ x(index) } | ||
cy={ y(value) } | ||
r={ radius } | ||
stroke={ color } | ||
fill={ 'white' } | ||
/> | ||
) | ||
return <Circle cx={x(index)} cy={y(value)} r={radius} stroke={color} fill={'white'} /> | ||
} | ||
@@ -21,0 +13,0 @@ |
@@ -8,41 +8,9 @@ import PropTypes from 'prop-types' | ||
<G> | ||
<Line | ||
x1={ x(index) } | ||
y1={ height } | ||
x2={ x(index) } | ||
y2={ 20 } | ||
stroke={ stroke } | ||
/> | ||
<Circle | ||
cx={ x(index) } | ||
cy={ y(value) } | ||
r={ 4 } | ||
stroke={ pointStroke } | ||
strokeWidth={ 2 } | ||
fill={ 'white' } | ||
/> | ||
<G x={ x(index) < 40 ? 40 : x(index) } y={ 10 }> | ||
<Rect | ||
x={ -40 } | ||
y={ 1 } | ||
width={ 80 } | ||
height={ 20 } | ||
fill={ 'rgba(0, 0, 0, 0.2)' } | ||
rx={ 2 } | ||
ry={ 2 } | ||
/> | ||
<Rect | ||
x={ -40 } | ||
y={ 0 } | ||
width={ 80 } | ||
height={ 20 } | ||
fill={ 'white' } | ||
rx={ 2 } | ||
ry={ 2 } | ||
/> | ||
<Text | ||
fontSize="12" | ||
textAnchor="middle" | ||
> | ||
{ text } | ||
<Line x1={x(index)} y1={height} x2={x(index)} y2={20} stroke={stroke} /> | ||
<Circle cx={x(index)} cy={y(value)} r={4} stroke={pointStroke} strokeWidth={2} fill={'white'} /> | ||
<G x={x(index) < 40 ? 40 : x(index)} y={10}> | ||
<Rect x={-40} y={1} width={80} height={20} fill={'rgba(0, 0, 0, 0.2)'} rx={2} ry={2} /> | ||
<Rect x={-40} y={0} width={80} height={20} fill={'white'} rx={2} ry={2} /> | ||
<Text fontSize='12' textAnchor='middle'> | ||
{text} | ||
</Text> | ||
@@ -49,0 +17,0 @@ </G> |
@@ -7,7 +7,5 @@ import React from 'react' | ||
<G> | ||
{ | ||
React.Children.map(children, child => { | ||
return data.map((value, index) => React.cloneElement(child, { value, index, ...props })) | ||
}) | ||
} | ||
{React.Children.map(children, (child) => { | ||
return data.map((value, index) => React.cloneElement(child, { value, index, ...props })) | ||
})} | ||
</G> | ||
@@ -14,0 +12,0 @@ ) |
@@ -7,7 +7,5 @@ import React from 'react' | ||
<G> | ||
{ | ||
React.Children.map(children, child => { | ||
return React.cloneElement(child, props) | ||
}) | ||
} | ||
{React.Children.map(children, (child) => { | ||
return React.cloneElement(child, props) | ||
})} | ||
</G> | ||
@@ -14,0 +12,0 @@ ) |
@@ -8,16 +8,14 @@ import React from 'react' | ||
<G> | ||
{ | ||
ticks.map(tick => ( | ||
<Line | ||
key={ tick } | ||
x1={ '0%' } | ||
x2={ '100%' } | ||
y1={ y(tick) } | ||
y2={ y(tick) } | ||
strokeWidth={ 1 } | ||
stroke={ 'rgba(0,0,0,0.2)' } | ||
{ ...svg } | ||
/> | ||
)) | ||
} | ||
{ticks.map((tick) => ( | ||
<Line | ||
key={tick} | ||
x1={'0%'} | ||
x2={'100%'} | ||
y1={y(tick)} | ||
y2={y(tick)} | ||
strokeWidth={1} | ||
stroke={'rgba(0,0,0,0.2)'} | ||
{...svg} | ||
/> | ||
))} | ||
</G> | ||
@@ -30,17 +28,14 @@ ) | ||
<G> | ||
{ | ||
ticks.map((tick, index) => ( | ||
<Line | ||
key={ index } | ||
y1={ '0%' } | ||
y2={ '100%' } | ||
x1={ x(tick) } | ||
x2={ x(tick) } | ||
strokeWidth={ 1 } | ||
stroke={ 'rgba(0,0,0,0.2)' } | ||
{ ...svg } | ||
/> | ||
)) | ||
} | ||
{ticks.map((tick, index) => ( | ||
<Line | ||
key={index} | ||
y1={'0%'} | ||
y2={'100%'} | ||
x1={x(tick)} | ||
x2={x(tick)} | ||
strokeWidth={1} | ||
stroke={'rgba(0,0,0,0.2)'} | ||
{...svg} | ||
/> | ||
))} | ||
</G> | ||
@@ -53,4 +48,4 @@ ) | ||
<G> | ||
<Horizontal { ...props }/> | ||
<Vertical { ...props }/> | ||
<Horizontal {...props} /> | ||
<Vertical {...props} /> | ||
</G> | ||
@@ -84,7 +79,7 @@ ) | ||
if (direction === Direction.VERTICAL) { | ||
return <Vertical { ...props } /> | ||
return <Vertical {...props} /> | ||
} else if (direction === Direction.HORIZONTAL) { | ||
return <Horizontal { ...props } /> | ||
return <Horizontal {...props} /> | ||
} else if (direction === Direction.BOTH) { | ||
return <Both { ...props } /> | ||
return <Both {...props} /> | ||
} | ||
@@ -91,0 +86,0 @@ |
@@ -8,3 +8,2 @@ import React, { PureComponent } from 'react' | ||
class PieChart extends PureComponent { | ||
state = { | ||
@@ -16,3 +15,7 @@ height: 0, | ||
_onLayout(event) { | ||
const { nativeEvent: { layout: { height, width } } } = event | ||
const { | ||
nativeEvent: { | ||
layout: { height, width }, | ||
}, | ||
} = event | ||
@@ -24,3 +27,3 @@ this.setState({ height, width }) | ||
if (typeof arg === 'string') { | ||
return (arg.split('%')[ 0 ] / 100) * max | ||
return (arg.split('%')[0] / 100) * max | ||
} else if (arg) { | ||
@@ -58,3 +61,3 @@ return arg | ||
if (data.length === 0) { | ||
return <View style={ style }/> | ||
return <View style={style} /> | ||
} | ||
@@ -64,4 +67,4 @@ | ||
if (Math.min(...data.map(obj => valueAccessor({ item: obj }))) < 0) { | ||
console.error('don\'t pass negative numbers to pie-chart, it makes no sense!') | ||
if (Math.min(...data.map((obj) => valueAccessor({ item: obj }))) < 0) { | ||
console.error("don't pass negative numbers to pie-chart, it makes no sense!") | ||
} | ||
@@ -77,4 +80,5 @@ | ||
const arcs = data.map(item => { | ||
const arc = shape.arc() | ||
const arcs = data.map((item) => { | ||
const arc = shape | ||
.arc() | ||
.outerRadius(_outerRadius) | ||
@@ -84,9 +88,9 @@ .innerRadius(_innerRadius) | ||
item.arc && Object.entries(item.arc) | ||
.forEach(([ key, value ]) => { | ||
if (typeof arc[ key ] === 'function') { | ||
item.arc && | ||
Object.entries(item.arc).forEach(([key, value]) => { | ||
if (typeof arc[key] === 'function') { | ||
if (typeof value === 'string') { | ||
arc[ key ](value.split('%')[ 0 ] / 100 * _outerRadius) | ||
arc[key]((value.split('%')[0] / 100) * _outerRadius) | ||
} else { | ||
arc[ key ](value) | ||
arc[key](value) | ||
} | ||
@@ -99,21 +103,21 @@ } | ||
const labelArcs = | ||
data.map((item, index) => { | ||
if (labelRadius) { | ||
return shape.arc() | ||
.outerRadius(_labelRadius) | ||
.innerRadius(_labelRadius) | ||
.padAngle(padAngle) | ||
} | ||
return arcs[ index ] | ||
}) | ||
const labelArcs = data.map((item, index) => { | ||
if (labelRadius) { | ||
return shape | ||
.arc() | ||
.outerRadius(_labelRadius) | ||
.innerRadius(_labelRadius) | ||
.padAngle(padAngle) | ||
} | ||
return arcs[index] | ||
}) | ||
const pieSlices = shape.pie() | ||
.value(d => valueAccessor({ item: d })) | ||
const pieSlices = shape | ||
.pie() | ||
.value((d) => valueAccessor({ item: d })) | ||
.sort(sort) | ||
.startAngle(startAngle) | ||
.endAngle(endAngle) | ||
(data) | ||
.endAngle(endAngle)(data) | ||
const slices = pieSlices.map((slice, index) =>({ | ||
const slices = pieSlices.map((slice, index) => ({ | ||
...slice, | ||
@@ -132,47 +136,36 @@ pieCentroid: arcs[index].centroid(slice), | ||
return ( | ||
<View style={ style }> | ||
<View | ||
style={{ flex: 1 }} | ||
onLayout={ event => this._onLayout(event) } | ||
> | ||
{ | ||
height > 0 && width > 0 && | ||
<View style={style}> | ||
<View style={{ flex: 1 }} onLayout={(event) => this._onLayout(event)}> | ||
{height > 0 && width > 0 && ( | ||
<Svg style={{ height, width }}> | ||
{/* center the progress circle*/} | ||
<G | ||
x={ width / 2 } | ||
y={ height / 2 } | ||
> | ||
{ | ||
React.Children.map(children, child => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
}) | ||
} | ||
<G x={width / 2} y={height / 2}> | ||
{React.Children.map(children, (child) => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
})} | ||
{pieSlices.map((slice, index) => { | ||
const { key, onPress, svg } = data[ index ] | ||
const { key, onPress, svg } = data[index] | ||
return ( | ||
<Path | ||
key={ key } | ||
onPress={ onPress } | ||
{ ...svg } | ||
d={ arcs[ index ](slice) } | ||
animate={ animate } | ||
animationDuration={ animationDuration } | ||
key={key} | ||
onPress={onPress} | ||
{...svg} | ||
d={arcs[index](slice)} | ||
animate={animate} | ||
animationDuration={animationDuration} | ||
/> | ||
) | ||
})} | ||
{ | ||
React.Children.map(children, child => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
}) | ||
} | ||
{React.Children.map(children, (child) => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
})} | ||
</G> | ||
</Svg> | ||
} | ||
)} | ||
</View> | ||
@@ -185,11 +178,13 @@ </View> | ||
PieChart.propTypes = { | ||
data: PropTypes.arrayOf(PropTypes.shape({ | ||
svg: PropTypes.object, | ||
key: PropTypes.any.isRequired, | ||
value: PropTypes.number, | ||
arc: PropTypes.object, | ||
})).isRequired, | ||
innerRadius: PropTypes.oneOfType([ PropTypes.number, PropTypes.string ]), | ||
outerRadius: PropTypes.oneOfType([ PropTypes.number, PropTypes.string ]), | ||
labelRadius: PropTypes.oneOfType([ PropTypes.number, PropTypes.string ]), | ||
data: PropTypes.arrayOf( | ||
PropTypes.shape({ | ||
svg: PropTypes.object, | ||
key: PropTypes.any.isRequired, | ||
value: PropTypes.number, | ||
arc: PropTypes.object, | ||
}) | ||
).isRequired, | ||
innerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), | ||
outerRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), | ||
labelRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), | ||
padAngle: PropTypes.number, | ||
@@ -196,0 +191,0 @@ animate: PropTypes.bool, |
@@ -9,3 +9,2 @@ import React, { PureComponent } from 'react' | ||
class ProgressCircle extends PureComponent { | ||
state = { | ||
@@ -17,3 +16,7 @@ height: 0, | ||
_onLayout(event) { | ||
const { nativeEvent: { layout: { height, width } } } = event | ||
const { | ||
nativeEvent: { | ||
layout: { height, width }, | ||
}, | ||
} = event | ||
this.setState({ height, width }) | ||
@@ -62,21 +65,18 @@ } | ||
.pie() | ||
.value(d => d.value) | ||
.sort((a) => a.key === 'rest' ? 1 : -1) | ||
.value((d) => d.value) | ||
.sort((a) => (a.key === 'rest' ? 1 : -1)) | ||
.startAngle(startAngle) | ||
.endAngle(endAngle) | ||
(data) | ||
.endAngle(endAngle)(data) | ||
const arcs = pieSlices.map((slice, index) => ( | ||
{ | ||
...data[ index ], | ||
...slice, | ||
path: shape.arc() | ||
.outerRadius(outerDiameter / 2) // Radius of the pie | ||
.innerRadius((outerDiameter / 2) - strokeWidth) // Inner radius: to create a donut or pie | ||
.startAngle(index === 0 ? startAngle : slice.startAngle) | ||
.endAngle(index === 0 ? endAngle : slice.endAngle) | ||
.cornerRadius(cornerRadius) | ||
(), | ||
} | ||
)) | ||
const arcs = pieSlices.map((slice, index) => ({ | ||
...data[index], | ||
...slice, | ||
path: shape | ||
.arc() | ||
.outerRadius(outerDiameter / 2) // Radius of the pie | ||
.innerRadius(outerDiameter / 2 - strokeWidth) // Inner radius: to create a donut or pie | ||
.startAngle(index === 0 ? startAngle : slice.startAngle) | ||
.endAngle(index === 0 ? endAngle : slice.endAngle) | ||
.cornerRadius(cornerRadius)(), | ||
})) | ||
@@ -89,44 +89,33 @@ const extraProps = { | ||
return ( | ||
<View | ||
style={ style } | ||
onLayout={ event => this._onLayout(event) } | ||
> | ||
{ | ||
height > 0 && width > 0 && | ||
<View style={style} onLayout={(event) => this._onLayout(event)}> | ||
{height > 0 && width > 0 && ( | ||
<Svg style={{ height, width }}> | ||
{/* center the progress circle*/} | ||
<G | ||
x={ width / 2 } | ||
y={ height / 2 } | ||
> | ||
{ | ||
React.Children.map(children, child => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
}) | ||
} | ||
<G x={width / 2} y={height / 2}> | ||
{React.Children.map(children, (child) => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
})} | ||
{arcs.map((shape, index) => { | ||
return ( | ||
<Path | ||
key={ index } | ||
fill={ shape.color } | ||
d={ shape.path } | ||
animate={ animate } | ||
animationDuration={ animateDuration } | ||
key={index} | ||
fill={shape.color} | ||
d={shape.path} | ||
animate={animate} | ||
animationDuration={animateDuration} | ||
/> | ||
) | ||
})} | ||
{ | ||
React.Children.map(children, child => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
}) | ||
} | ||
{React.Children.map(children, (child) => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
})} | ||
</G> | ||
</Svg> | ||
} | ||
)} | ||
</View> | ||
@@ -133,0 +122,0 @@ ) |
@@ -11,9 +11,8 @@ import PropTypes from 'prop-types' | ||
class AreaStack extends PureComponent { | ||
static extractDataPoints(data, keys, order = shape.stackOrderNone, offset = shape.stackOffsetNone) { | ||
const series = shape.stack() | ||
const series = shape | ||
.stack() | ||
.keys(keys) | ||
.order(order) | ||
.offset(offset) | ||
(data) | ||
.offset(offset)(data) | ||
@@ -30,3 +29,7 @@ //double merge arrays to extract just the values | ||
_onLayout(event) { | ||
const { nativeEvent: { layout: { height, width } } } = event | ||
const { | ||
nativeEvent: { | ||
layout: { height, width }, | ||
}, | ||
} = event | ||
this.setState({ height, width }) | ||
@@ -36,3 +39,2 @@ } | ||
render() { | ||
const { | ||
@@ -47,8 +49,3 @@ data, | ||
numberOfTicks, | ||
contentInset: { | ||
top = 0, | ||
bottom = 0, | ||
left = 0, | ||
right = 0, | ||
}, | ||
contentInset: { top = 0, bottom = 0, left = 0, right = 0 }, | ||
gridMin, | ||
@@ -69,10 +66,10 @@ gridMax, | ||
if (data.length === 0) { | ||
return <View style={ style }/> | ||
return <View style={style} /> | ||
} | ||
const series = shape.stack() | ||
const series = shape | ||
.stack() | ||
.keys(keys) | ||
.order(order) | ||
.offset(offset) | ||
(data) | ||
.offset(offset)(data) | ||
@@ -83,21 +80,17 @@ //double merge arrays to extract just the yValues | ||
const yExtent = array.extent([ ...yValues, gridMin, gridMax ]) | ||
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 | ||
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([ yMin, yMax ]) | ||
.range([ height - bottom, top ]) | ||
const y = scale | ||
.scaleLinear() | ||
.domain([yMin, yMax]) | ||
.range([height - bottom, top]) | ||
.clamp(clampY) | ||
const x = xScale() | ||
.domain([ xMin, xMax ]) | ||
.range([ left, width - right ]) | ||
.domain([xMin, xMax]) | ||
.range([left, width - right]) | ||
.clamp(clampX) | ||
@@ -108,13 +101,13 @@ | ||
const areas = series.map((serie, index) => { | ||
const path = shape.area() | ||
const path = shape | ||
.area() | ||
.x((d, index) => x(xAccessor({ item: d.data, index }))) | ||
.y0(d => y(d[ 0 ])) | ||
.y1(d => y(d[ 1 ])) | ||
.curve(curve) | ||
(data.map((_, index) => serie[ index ])) | ||
.y0((d) => y(d[0])) | ||
.y1((d) => y(d[1])) | ||
.curve(curve)(data.map((_, index) => serie[index])) | ||
return { | ||
path, | ||
key: keys[ index ], | ||
color: colors[ index ], | ||
key: keys[index], | ||
color: colors[index], | ||
} | ||
@@ -129,43 +122,34 @@ }) | ||
ticks, | ||
areas, | ||
} | ||
return ( | ||
<View style={ style }> | ||
<View | ||
style={{ flex: 1 }} | ||
onLayout={ event => this._onLayout(event) } | ||
> | ||
{ | ||
height > 0 && width > 0 && | ||
<View style={style}> | ||
<View style={{ flex: 1 }} onLayout={(event) => this._onLayout(event)}> | ||
{height > 0 && width > 0 && ( | ||
<Svg style={{ height, width }}> | ||
{ | ||
React.Children.map(children, child => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
}) | ||
} | ||
{ | ||
areas.map((area, index) => ( | ||
<Path | ||
key={ area.key } | ||
fill={ area.color } | ||
{ ...svgs[ index ] } | ||
animate={ animate } | ||
animationDuration={ animationDuration } | ||
d={ area.path } | ||
/> | ||
)) | ||
} | ||
{ | ||
React.Children.map(children, child => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
}) | ||
} | ||
{React.Children.map(children, (child) => { | ||
if (child && child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
})} | ||
{areas.map((area, index) => ( | ||
<Path | ||
key={area.key} | ||
fill={area.color} | ||
{...svgs[index]} | ||
animate={animate} | ||
animationDuration={animationDuration} | ||
d={area.path} | ||
/> | ||
))} | ||
{React.Children.map(children, (child) => { | ||
if (child && !child.props.belowChart) { | ||
return React.cloneElement(child, extraProps) | ||
} | ||
return null | ||
})} | ||
</Svg> | ||
} | ||
)} | ||
</View> | ||
@@ -172,0 +156,0 @@ </View> |
import PropTypes from 'prop-types' | ||
const util = { | ||
sortDescending(_array) { | ||
const array = [ ..._array ] | ||
const array = [..._array] | ||
return array.sort((a, b) => { | ||
@@ -17,3 +16,2 @@ if (a > b) { | ||
}, | ||
} | ||
@@ -20,0 +18,0 @@ |
@@ -6,6 +6,5 @@ import React, { PureComponent } from 'react' | ||
import * as array from 'd3-array' | ||
import Svg, { Text as SVGText } from 'react-native-svg' | ||
import Svg, { G, Text as SVGText } from 'react-native-svg' | ||
class XAxis extends PureComponent { | ||
state = { | ||
@@ -17,3 +16,7 @@ width: 0, | ||
_onLayout(event) { | ||
const { nativeEvent: { layout: { width, height } } } = event | ||
const { | ||
nativeEvent: { | ||
layout: { width, height }, | ||
}, | ||
} = event | ||
@@ -30,6 +33,3 @@ if (width !== this.state.width) { | ||
spacingOuter, | ||
contentInset: { | ||
left = 0, | ||
right = 0, | ||
}, | ||
contentInset: { left = 0, right = 0 }, | ||
} = this.props | ||
@@ -41,12 +41,9 @@ | ||
.domain(domain) | ||
.range([ left, width - right ]) | ||
.range([left, width - right]) | ||
if (scale.name === 'scaleBand') { | ||
if (scale === d3Scale.scaleBand) { | ||
x.paddingInner([spacingInner]).paddingOuter([spacingOuter]) | ||
x | ||
.paddingInner([ spacingInner ]) | ||
.paddingOuter([ spacingOuter ]) | ||
//add half a bar to center label | ||
return (value) => x(value) + (x.bandwidth() / 2) | ||
return (value) => x(value) + x.bandwidth() / 2 | ||
} | ||
@@ -58,75 +55,67 @@ | ||
render() { | ||
const { style, scale, data, xAccessor, formatLabel, numberOfTicks, svg, children, min, max } = this.props | ||
const { | ||
style, | ||
scale, | ||
data, | ||
xAccessor, | ||
formatLabel, | ||
numberOfTicks, | ||
svg, | ||
children, | ||
min, | ||
max, | ||
} = this.props | ||
const { height, width } = this.state | ||
if (data.length === 0) { | ||
return <View style={ style }/> | ||
return <View style={style} /> | ||
} | ||
const values = data.map((item, index) => xAccessor({ item, index })) | ||
const extent = array.extent(values) | ||
const domain = scale.name === 'scaleBand' ? | ||
values : | ||
[ min || extent[ 0 ], max || extent[ 1 ] ] | ||
const extent = array.extent(values) | ||
const domain = scale === d3Scale.scaleBand ? values : [min || extent[0], max || extent[1]] | ||
const x = this._getX(domain) | ||
const x = this._getX(domain) | ||
const ticks = numberOfTicks ? x.ticks(numberOfTicks) : values | ||
const extraProps = { | ||
x, | ||
ticks, | ||
width, | ||
height, | ||
formatLabel, | ||
} | ||
return ( | ||
<View style={ style }> | ||
<View | ||
style={{ flexGrow: 1 }} | ||
onLayout={ event => this._onLayout(event) } | ||
> | ||
<View style={style}> | ||
<View style={{ flexGrow: 1 }} onLayout={(event) => this._onLayout(event)}> | ||
{/*invisible text to allow for parent resizing*/} | ||
<Text style={{ color: 'transparent', fontSize: svg.fontSize }}> | ||
{ formatLabel(ticks[0], 0) } | ||
</Text> | ||
{ | ||
height > 0 && width > 0 && | ||
<Svg style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
height, | ||
width, | ||
}}> | ||
{children} | ||
{ | ||
// don't render labels if width isn't measured yet, | ||
<Text style={{ opacity: 0, fontSize: svg.fontSize }}>{formatLabel(ticks[0], 0)}</Text> | ||
{height > 0 && width > 0 && ( | ||
<Svg | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
height, | ||
width, | ||
}} | ||
> | ||
<G> | ||
{React.Children.map(children, (child) => { | ||
return React.cloneElement(child, extraProps) | ||
})} | ||
{// don't render labels if width isn't measured yet, | ||
// causes rendering issues | ||
width > 0 && | ||
ticks.map((value, index) => { | ||
const { svg: valueSvg = {} } = data[ index ] || {} | ||
ticks.map((value, index) => { | ||
const { svg: valueSvg = {} } = data[index] || {} | ||
return ( | ||
<SVGText | ||
textAnchor={ 'middle' } | ||
originX={ x(value) } | ||
alignmentBaseline={ 'hanging' } | ||
{ ...svg } | ||
{ ...valueSvg } | ||
key={ index } | ||
x={ x(value) } | ||
> | ||
{formatLabel(value, index)} | ||
</SVGText> | ||
) | ||
}) | ||
} | ||
return ( | ||
<SVGText | ||
textAnchor={'middle'} | ||
originX={x(value)} | ||
alignmentBaseline={'hanging'} | ||
{...svg} | ||
{...valueSvg} | ||
key={index} | ||
x={x(value)} | ||
> | ||
{formatLabel(value, index)} | ||
</SVGText> | ||
) | ||
})} | ||
</G> | ||
</Svg> | ||
} | ||
)} | ||
</View> | ||
@@ -139,6 +128,3 @@ </View> | ||
XAxis.propTypes = { | ||
data: PropTypes.arrayOf(PropTypes.oneOfType([ | ||
PropTypes.number, | ||
PropTypes.object, | ||
])).isRequired, | ||
data: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.object])).isRequired, | ||
spacingInner: PropTypes.number, | ||
@@ -151,3 +137,3 @@ spacingOuter: PropTypes.number, | ||
}), | ||
scale: PropTypes.oneOf([ d3Scale.scaleTime, d3Scale.scaleLinear, d3Scale.scaleBand ]), | ||
scale: PropTypes.oneOf([d3Scale.scaleTime, d3Scale.scaleLinear, d3Scale.scaleBand]), | ||
numberOfTicks: PropTypes.number, | ||
@@ -167,5 +153,5 @@ xAccessor: PropTypes.func, | ||
scale: d3Scale.scaleLinear, | ||
formatLabel: value => value, | ||
formatLabel: (value) => value, | ||
} | ||
export default XAxis |
import React, { PureComponent } from 'react' | ||
import PropTypes from 'prop-types' | ||
import { Text, View } from 'react-native' | ||
import { Svg, Text as SVGText } from 'react-native-svg' | ||
import { Svg, G, Text as SVGText } from 'react-native-svg' | ||
import * as d3Scale from 'd3-scale' | ||
@@ -9,3 +9,2 @@ import * as array from 'd3-array' | ||
class YAxis extends PureComponent { | ||
state = { | ||
@@ -17,3 +16,7 @@ height: 0, | ||
_onLayout(event) { | ||
const { nativeEvent: { layout: { height, width } } } = event | ||
const { | ||
nativeEvent: { | ||
layout: { height, width }, | ||
}, | ||
} = event | ||
this.setState({ height, width }) | ||
@@ -27,6 +30,3 @@ } | ||
spacingOuter, | ||
contentInset: { | ||
top = 0, | ||
bottom = 0, | ||
}, | ||
contentInset: { top = 0, bottom = 0 }, | ||
} = this.props | ||
@@ -38,6 +38,5 @@ | ||
.domain(domain) | ||
.range([ height - bottom, top ]) | ||
.range([height - bottom, top]) | ||
if (scale === d3Scale.scaleBand) { | ||
// use index as domain identifier instead of value since | ||
@@ -47,8 +46,8 @@ // same value can occur at several places in dataPoints | ||
// set range top to bottom - we are not sorting on values in scaleBand | ||
.range([ top, height - bottom ]) | ||
.paddingInner([ spacingInner ]) | ||
.paddingOuter([ spacingOuter ]) | ||
.range([top, height - bottom]) | ||
.paddingInner([spacingInner]) | ||
.paddingOuter([spacingOuter]) | ||
//add half a bar to center label | ||
return (value) => y(value) + (y.bandwidth() / 2) | ||
return (value) => y(value) + y.bandwidth() / 2 | ||
} | ||
@@ -60,18 +59,8 @@ | ||
render() { | ||
const { style, data, scale, yAccessor, numberOfTicks, formatLabel, svg, children } = this.props | ||
const { | ||
style, | ||
data, | ||
scale, | ||
yAccessor, | ||
numberOfTicks, | ||
formatLabel, | ||
svg, | ||
children, | ||
} = this.props | ||
const { height, width } = this.state | ||
if (data.length === 0) { | ||
return <View style={ style }/> | ||
return <View style={style} /> | ||
} | ||
@@ -81,10 +70,7 @@ | ||
const extent = array.extent([ ...values, min, max ]) | ||
const extent = array.extent(values) | ||
const { | ||
min = extent[ 0 ], | ||
max = extent[ 1 ], | ||
} = this.props | ||
const { min = extent[0], max = extent[1] } = this.props | ||
const domain = scale === d3Scale.scaleBand ? values : [ min, max ] | ||
const domain = scale === d3Scale.scaleBand ? values : [min, max] | ||
@@ -94,54 +80,56 @@ //invert range to support svg coordinate system | ||
const ticks = scale === d3Scale.scaleBand ? | ||
values : | ||
y.ticks(numberOfTicks) | ||
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) | ||
.reduce((prev, curr) => (prev.toString().length > curr.toString().length ? prev : curr), 0) | ||
const extraProps = { | ||
y, | ||
ticks, | ||
width, | ||
height, | ||
formatLabel, | ||
} | ||
return ( | ||
<View style={ [ style ] }> | ||
<View | ||
style={{ flexGrow: 1 }} | ||
onLayout={ event => this._onLayout(event) } | ||
> | ||
<View style={[style]}> | ||
<View style={{ flexGrow: 1 }} onLayout={(event) => this._onLayout(event)}> | ||
{/*invisible text to allow for parent resizing*/} | ||
<Text | ||
style={{ color: 'transparent', fontSize: svg.fontSize }} | ||
> | ||
{longestValue} | ||
</Text> | ||
{ | ||
height > 0 && width > 0 && | ||
<Svg style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
height, | ||
width, | ||
}}> | ||
{children} | ||
{ | ||
// don't render labels if width isn't measured yet, | ||
<Text style={{ opacity: 0, fontSize: svg.fontSize }}>{longestValue}</Text> | ||
{height > 0 && width > 0 && ( | ||
<Svg | ||
style={{ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
height, | ||
width, | ||
}} | ||
> | ||
<G> | ||
{React.Children.map(children, (child) => { | ||
return React.cloneElement(child, extraProps) | ||
})} | ||
{// don't render labels if width isn't measured yet, | ||
// causes rendering issues | ||
height > 0 && | ||
ticks.map((value, index) => { | ||
return ( | ||
<SVGText | ||
originY={ y(value) } | ||
textAnchor={ 'middle' } | ||
x={ '50%' } | ||
alignmentBaseline={ 'middle' } | ||
{ ...svg } | ||
key={ index } | ||
y={ y(value) } | ||
> | ||
{formatLabel(value, index)} | ||
</SVGText> | ||
) | ||
}) | ||
} | ||
ticks.map((value, index) => { | ||
return ( | ||
<SVGText | ||
originY={y(value)} | ||
textAnchor={'middle'} | ||
x={'50%'} | ||
alignmentBaseline={'middle'} | ||
{...svg} | ||
key={y(value)} | ||
y={y(value)} | ||
> | ||
{formatLabel(value, index, ticks.length)} | ||
</SVGText> | ||
) | ||
})} | ||
</G> | ||
</Svg> | ||
} | ||
)} | ||
</View> | ||
@@ -154,6 +142,3 @@ </View> | ||
YAxis.propTypes = { | ||
data: PropTypes.oneOfType([ | ||
PropTypes.arrayOf(PropTypes.object), | ||
PropTypes.arrayOf(PropTypes.number), | ||
]).isRequired, | ||
data: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.arrayOf(PropTypes.number)]).isRequired, | ||
svg: PropTypes.object, | ||
@@ -182,3 +167,3 @@ style: PropTypes.any, | ||
scale: d3Scale.scaleLinear, | ||
formatLabel: value => value && value.toString(), | ||
formatLabel: (value) => value && value.toString(), | ||
yAccessor: ({ item }) => item, | ||
@@ -185,0 +170,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
170348
50
2464
26
742
1