UNPKG

react-svg-line-chart

Version:

A lightweight responsive line chart component for React using only SVG

183 lines (152 loc) 6.4 kB
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"]); 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; } import PropTypes from "prop-types"; import React from "react"; import styled from "styled-components"; var SvgArea = styled.path(_templateObject, function (props) { return props.color; }, function (props) { return props.opacity; }); var SvgPath = styled.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 ? React.createElement( "g", null, pathVisible && React.createElement(SvgPath, { d: this.getPath(), opacity: pathOpacity, color: pathColor, width: pathWidth }), areaVisible && React.createElement(SvgArea, { d: this.getAreaPath(), color: areaColor, opacity: areaOpacity }) ) : null; }; return Path; }(React.Component); Path.propTypes = process.env.NODE_ENV !== "production" ? { areaColor: PropTypes.string, areaOpacity: PropTypes.number, areaVisible: PropTypes.bool, data: PropTypes.arrayOf(PropTypes.shape({ x: PropTypes.number, y: PropTypes.number })).isRequired, getX: PropTypes.func, getY: PropTypes.func, pathColor: PropTypes.string, pathOpacity: PropTypes.number, pathSmoothing: PropTypes.number, pathVisible: PropTypes.bool, pathWidth: PropTypes.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 }; export default Path;