react-native-svg-charts
Version:
Customizable charts (Line, Bar, Area, Pie, Circle, Progress) for React Native
178 lines (163 loc) • 4.96 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Text, View } from 'react-native';
import { Svg, G, Text as SVGText } from 'react-native-svg';
import * as d3Scale from 'd3-scale';
import * as array from 'd3-array';
class YAxis extends PureComponent {
constructor(...args) {
super(...args);
_defineProperty(this, "state", {
height: 0,
width: 0
});
}
_onLayout(event) {
const {
nativeEvent: {
layout: {
height,
width
}
}
} = event;
this.setState({
height,
width
});
}
getY(domain) {
const {
scale,
spacingInner,
spacingOuter,
contentInset: {
top = 0,
bottom = 0
}
} = this.props;
const {
height
} = this.state;
const y = scale().domain(domain).range([height - bottom, top]);
if (scale === d3Scale.scaleBand) {
// use index as domain identifier instead of value since
// same value can occur at several places in dataPoints
y // set range top to bottom - we are not sorting on values in scaleBand
.range([top, height - bottom]).paddingInner([spacingInner]).paddingOuter([spacingOuter]); //add half a bar to center label
return value => y(value) + y.bandwidth() / 2;
}
return y;
}
render() {
const {
style,
data,
scale,
yAccessor,
numberOfTicks,
formatLabel,
svg,
children
} = this.props;
const {
height,
width
} = this.state;
if (data.length === 0) {
return /*#__PURE__*/React.createElement(View, {
style: style
});
}
const values = data.map((item, index) => yAccessor({
item,
index
}));
const extent = array.extent(values);
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);
const extraProps = {
y,
ticks,
width,
height,
formatLabel
};
return /*#__PURE__*/React.createElement(View, {
style: [style]
}, /*#__PURE__*/React.createElement(View, {
style: {
flexGrow: 1
},
onLayout: event => this._onLayout(event)
}, /*#__PURE__*/React.createElement(Text, {
style: {
opacity: 0,
fontSize: svg.fontSize,
fontFamily: svg.fontFamily,
fontWeight: svg.fontWeight
}
}, longestValue), height > 0 && width > 0 && /*#__PURE__*/React.createElement(Svg, {
style: {
position: 'absolute',
top: 0,
left: 0,
height,
width
}
}, /*#__PURE__*/React.createElement(G, null, 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 /*#__PURE__*/React.createElement(SVGText, _extends({
originY: y(value),
textAnchor: 'middle',
x: '50%',
alignmentBaseline: 'middle'
}, svg, {
key: y(value),
y: y(value)
}), formatLabel(value, index, ticks.length));
})))));
}
}
YAxis.propTypes = {
data: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.arrayOf(PropTypes.number)]).isRequired,
svg: PropTypes.object,
style: PropTypes.any,
numberOfTicks: PropTypes.number,
formatLabel: PropTypes.func,
contentInset: PropTypes.shape({
top: PropTypes.number,
bottom: PropTypes.number
}),
min: PropTypes.number,
max: PropTypes.number,
yAccessor: PropTypes.func,
scale: PropTypes.func,
spacingInner: PropTypes.number,
spacingOuter: PropTypes.number
};
YAxis.defaultProps = {
numberOfTicks: 10,
spacingInner: 0.05,
spacingOuter: 0.05,
contentInset: {},
svg: {},
scale: d3Scale.scaleLinear,
formatLabel: value => value && value.toString(),
yAccessor: ({
item
}) => item
};
export default YAxis;
//# sourceMappingURL=y-axis.js.map