react-svg-line-chart
Version:
A lightweight responsive line chart component for React using only SVG
198 lines (159 loc) • 7 kB
JavaScript
;
exports.__esModule = true;
var _templateObject = _taggedTemplateLiteralLoose(["\n fill: ", ";\n opacity: ", ";\n stroke: none;\n"], ["\n fill: ", ";\n opacity: ", ";\n stroke: none;\n"]),
_templateObject2 = _taggedTemplateLiteralLoose(["\n fill: none;\n opacity: ", ";\n stroke-width: ", ";\n stroke: ", ";\n"], ["\n fill: none;\n opacity: ", ";\n stroke-width: ", ";\n stroke: ", ";\n"]);
var _propTypes = require("prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _styledComponents = require("styled-components");
var _styledComponents2 = _interopRequireDefault(_styledComponents);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
var SvgArea = _styledComponents2.default.path(_templateObject, function (props) {
return props.color;
}, function (props) {
return props.opacity;
});
var SvgPath = _styledComponents2.default.path(_templateObject2, function (props) {
return props.opacity;
}, function (props) {
return props.width;
}, function (props) {
return props.color;
});
var Path = function (_React$Component) {
_inherits(Path, _React$Component);
function Path() {
_classCallCheck(this, Path);
return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
}
Path.prototype.getBasisPoint = function getBasisPoint(i) {
var _props = this.props,
data = _props.data,
pathSmoothing = _props.pathSmoothing;
var totalData = data.length - 1;
var iPoint = i < 0 ? 0 : i > totalData ? totalData : i;
var point = data[iPoint];
var ratio = 1 - pathSmoothing;
var tangent = iPoint / totalData;
var firstPoint = data[0];
var distance = {
x: data[totalData].x - firstPoint.x,
y: data[totalData].y - firstPoint.y
};
return {
x: ratio * point.x + (1 - ratio) * (firstPoint.x + tangent * distance.x),
y: ratio * point.y + (1 - ratio) * (firstPoint.y + tangent * distance.y)
};
};
Path.prototype.getCurvePath = function getCurvePath(i) {
var _props2 = this.props,
getX = _props2.getX,
getY = _props2.getY;
var pCurrent = this.getBasisPoint(i);
var pMinus1 = this.getBasisPoint(i - 1);
var pMinus2 = this.getBasisPoint(i - 2);
var x1 = (2 * pMinus2.x + pMinus1.x) / 3;
var y1 = (2 * pMinus2.y + pMinus1.y) / 3;
var x2 = (pMinus2.x + 2 * pMinus1.x) / 3;
var y2 = (pMinus2.y + 2 * pMinus1.y) / 3;
var x3 = (pMinus2.x + 4 * pMinus1.x + pCurrent.x) / 6;
var y3 = (pMinus2.y + 4 * pMinus1.y + pCurrent.y) / 6;
return "C\n " + getX(x1) + "\n " + getY(y1) + "\n " + getX(x2) + "\n " + getY(y2) + "\n " + getX(x3) + "\n " + getY(y3) + "\n ";
};
Path.prototype.getLinePath = function getLinePath(point) {
var _props3 = this.props,
getX = _props3.getX,
getY = _props3.getY;
return "L " + getX(point.x) + " " + getY(point.y);
};
Path.prototype.getPath = function getPath() {
var _this2 = this;
var _props4 = this.props,
data = _props4.data,
getX = _props4.getX,
getY = _props4.getY,
pathSmoothing = _props4.pathSmoothing;
var isSmooth = pathSmoothing !== null && pathSmoothing >= 0 && pathSmoothing <= 1 && data.length > 1;
var d = data.reduce(function (acc, point, i) {
var partialPath = isSmooth ? _this2.getCurvePath(i) : _this2.getLinePath(point);
return i === 0 ? "M " + getX(point.x) + " " + getY(point.y) + " " : acc + " " + partialPath + " ";
}, "");
if (isSmooth) {
d += this.getCurvePath(data.length);
d += "L " + getX(data[data.length - 1].x) + " " + getY(data[data.length - 1].y) + " ";
}
return d;
};
Path.prototype.getAreaPath = function getAreaPath() {
var _props5 = this.props,
data = _props5.data,
getX = _props5.getX,
getY = _props5.getY;
return "\n " + this.getPath() + "\n L " + getX(data[data.length - 1].x) + " " + getY(0) + "\n L " + getX(data[0].x) + " " + getY(0) + "\n ";
};
Path.prototype.render = function render() {
var _props6 = this.props,
areaColor = _props6.areaColor,
areaOpacity = _props6.areaOpacity,
areaVisible = _props6.areaVisible,
pathColor = _props6.pathColor,
pathOpacity = _props6.pathOpacity,
pathVisible = _props6.pathVisible,
pathWidth = _props6.pathWidth;
return pathVisible || areaVisible ? _react2.default.createElement(
"g",
null,
pathVisible && _react2.default.createElement(SvgPath, {
d: this.getPath(),
opacity: pathOpacity,
color: pathColor,
width: pathWidth
}),
areaVisible && _react2.default.createElement(SvgArea, {
d: this.getAreaPath(),
color: areaColor,
opacity: areaOpacity
})
) : null;
};
return Path;
}(_react2.default.Component);
Path.propTypes = process.env.NODE_ENV !== "production" ? {
areaColor: _propTypes2.default.string,
areaOpacity: _propTypes2.default.number,
areaVisible: _propTypes2.default.bool,
data: _propTypes2.default.arrayOf(_propTypes2.default.shape({
x: _propTypes2.default.number,
y: _propTypes2.default.number
})).isRequired,
getX: _propTypes2.default.func,
getY: _propTypes2.default.func,
pathColor: _propTypes2.default.string,
pathOpacity: _propTypes2.default.number,
pathSmoothing: _propTypes2.default.number,
pathVisible: _propTypes2.default.bool,
pathWidth: _propTypes2.default.number
} : {};
Path.defaultProps = {
areaColor: "#34495e",
areaOpacity: 0.5,
areaVisible: false,
getX: function getX(x) {
return x;
},
getY: function getY(y) {
return y;
},
pathColor: "#34495e",
pathOpacity: 1,
pathSmoothing: null,
pathVisible: true,
pathWidth: 2
};
exports.default = Path;
module.exports = exports["default"];