From f1a8814a8e7e9b05bb13f60b45ec2fb3beb93bfc Mon Sep 17 00:00:00 2001 From: Atanas Atanasov Date: Fri, 4 Sep 2020 09:13:53 +0300 Subject: [PATCH 1/3] Use hooks --- __test__/__snapshots__/index.test.js.snap | 2 + __test__/index.test.js | 75 +++-- dist/complex.js | 361 ++++++++++------------ dist/index.js | 24 +- package.json | 2 +- src/complex.js | 171 +++++----- 6 files changed, 291 insertions(+), 344 deletions(-) diff --git a/__test__/__snapshots__/index.test.js.snap b/__test__/__snapshots__/index.test.js.snap index 991f1ac..c6b23e6 100644 --- a/__test__/__snapshots__/index.test.js.snap +++ b/__test__/__snapshots__/index.test.js.snap @@ -113,6 +113,8 @@ exports[`Donuts should render a complex donut 1`] = ` `; +exports[`Donuts should render a complex donut 2`] = `null`; + exports[`Donuts should render a simple donut with custom props 1`] = `
{ }); it('should render a complex donut', () => { - const tree = renderer.create( - - ); + let tree; + + act(() => { + tree = renderer.create( + + ); + }); + + expect(tree).toMatchSnapshot(); + + tree.unmount(); expect(tree).toMatchSnapshot(); }); diff --git a/dist/complex.js b/dist/complex.js index 23d9411..a152d41 100644 --- a/dist/complex.js +++ b/dist/complex.js @@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = exports.ComplexDonut = void 0; +exports["default"] = exports.ComplexDonut = void 0; var _react = _interopRequireDefault(require("react")); @@ -11,233 +11,186 @@ var _propTypes = _interopRequireDefault(require("prop-types")); require("./complex.css"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } -function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } +function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } - -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; } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } var rotateAngle = 0; -var ComplexDonut = -/*#__PURE__*/ -function (_React$Component) { - _inherits(ComplexDonut, _React$Component); - - function ComplexDonut(props) { - var _this; - - _classCallCheck(this, ComplexDonut); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(ComplexDonut).call(this, props)); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "loadTimeout", 0); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "total", function (values) { - return values.reduce(function (acc, _ref) { - var value = _ref.value; - return acc + value; - }, 0); - }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "percent", function (value, total) { - return value / total; - }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "transforms", function () { - var rotations = []; - var textCoords = []; - var _this$props = _this.props, - startAngle = _this$props.startAngle, - segments = _this$props.segments; - - var total = _this.total(segments); - - rotateAngle = startAngle; - - _this.sortValues(segments).forEach(function (_ref2) { - var value = _ref2.value; - var data = rotateAngle; +var getTotal = function getTotal(values) { + return values.reduce(function (acc, _ref) { + var value = _ref.value; + return acc + value; + }, 0); +}; - var percent = _this.percent(value, total); +var getPercent = function getPercent(value, total) { + return value / total; +}; - var _this$textCoordinates = _this.textCoordinates(value, rotateAngle), - x = _this$textCoordinates.x, - y = _this$textCoordinates.y; +var sortValues = function sortValues(values) { + return values.sort(function (a, b) { + return b.value - a.value; + }); +}; - rotations.push(data); - textCoords.push({ - x: x, - y: y - }); - var result = rotations[rotations.length - 1] || startAngle; - rotateAngle = percent * 360 + result; - }); +var getCircumference = function getCircumference(radius) { + return 2 * Math.PI * radius; +}; - return { - rotations: rotations, - textCoords: textCoords - }; - }); +var convertDegreesToRadians = function convertDegreesToRadians(angle) { + return angle * (Math.PI / 180); +}; - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "sortValues", function (values) { - return values.sort(function (a, b) { - return b.value - a.value; +var ComplexDonut = function ComplexDonut(props) { + var loadTimeout; + var total = getTotal(props.segments); + + var getTextCoordinates = function getTextCoordinates(value, angleOffset) { + var size = props.size, + radius = props.radius, + segments = props.segments; + var total = getTotal(segments); + var angle = getPercent(value, total) * 360 / 2 + angleOffset; + var radians = convertDegreesToRadians(angle); + return { + x: radius * Math.cos(radians) + size / 2, + y: radius * Math.sin(radians) + size / 2 + }; + }; + + var getTransforms = function getTransforms() { + var rotations = []; + var textCoords = []; + var startAngle = props.startAngle, + segments = props.segments; + var total = getTotal(segments); + rotateAngle = startAngle; + sortValues(segments).forEach(function (_ref2) { + var value = _ref2.value; + var data = rotateAngle; + var percent = getPercent(value, total); + + var _getTextCoordinates = getTextCoordinates(value, rotateAngle), + x = _getTextCoordinates.x, + y = _getTextCoordinates.y; + + rotations.push(data); + textCoords.push({ + x: x, + y: y }); + var result = rotations[rotations.length - 1] || startAngle; + rotateAngle = percent * 360 + result; }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "circumference", function (radius) { - return 2 * Math.PI * radius; - }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "degreesToRadians", function (angle) { - return angle * (Math.PI / 180); - }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "strokeDashOffset", function (value, circumference) { - var diff = _this.percent(value, _this.state.total) * circumference; - return circumference - diff; - }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "textCoordinates", function (value, angleOffset) { - var _this$props2 = _this.props, - size = _this$props2.size, - radius = _this$props2.radius, - segments = _this$props2.segments; - - var total = _this.total(segments); - - var angle = _this.percent(value, total) * 360 / 2 + angleOffset; - - var radians = _this.degreesToRadians(angle); - + return { + rotations: rotations, + textCoords: textCoords + }; + }; + + var getStrokeDashOffset = function getStrokeDashOffset(value, circumference) { + var diff = getPercent(value, total) * circumference; + return circumference - diff; + }; + + var _React$useState = _react["default"].useState([]), + _React$useState2 = _slicedToArray(_React$useState, 2), + segments = _React$useState2[0], + setSegments = _React$useState2[1]; + + var _React$useState3 = _react["default"].useState(false), + _React$useState4 = _slicedToArray(_React$useState3, 2), + isLoaded = _React$useState4[0], + setIsLoaded = _React$useState4[1]; + + _react["default"].useEffect(function () { + var segments = props.segments, + size = props.size; + + var _getTransforms = getTransforms(), + rotations = _getTransforms.rotations, + textCoords = _getTransforms.textCoords; + + setSegments(sortValues(segments).map(function (_ref3, i) { + var value = _ref3.value, + color = _ref3.color; return { - x: radius * Math.cos(radians) + size / 2, - y: radius * Math.sin(radians) + size / 2 + value: value, + color: color, + percent: getPercent(value, total), + rotate: "rotate(".concat(rotations[i], ", ").concat(size / 2, ", ").concat(size / 2, ")"), + textCoords: textCoords[i] }; - }); - - _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "componentDidMount", function () { - var _this$props3 = _this.props, - segments = _this$props3.segments, - size = _this$props3.size; - var _this$state = _this.state, - total = _this$state.total, - _this$state$transform = _this$state.transforms, - rotations = _this$state$transform.rotations, - textCoords = _this$state$transform.textCoords; - - _this.setState({ - segments: _this.sortValues(segments).map(function (_ref3, i) { - var value = _ref3.value, - color = _ref3.color; - return { - value: value, - color: color, - percent: _this.percent(value, total), - rotate: "rotate(".concat(rotations[i], ", ").concat(size / 2, ", ").concat(size / 2, ")"), - textCoords: textCoords[i] - }; - }) - }); - - _this.loadTimeout = setTimeout(function () { - _this.setState({ - isLoaded: true - }); - }, 100); - }); - - _this.state = { - total: _this.total(props.segments), - segments: [], - transforms: _this.transforms(), - isLoaded: false + })); + loadTimeout = setTimeout(function () { + setIsLoaded(true); + }, 100); + return function () { + clearTimeout(loadTimeout); }; - return _this; - } - - _createClass(ComplexDonut, [{ - key: "componentWillUnmount", - value: function componentWillUnmount() { - this.clearTimeout(this.loadTimeout); - } - }, { - key: "render", - value: function render() { - var _this2 = this; - - var _this$props4 = this.props, - size = _this$props4.size, - radius = _this$props4.radius, - thickness = _this$props4.thickness, - className = _this$props4.className, - circleProps = _this$props4.circleProps, - textProps = _this$props4.textProps; - var halfSize = size / 2; - var circumference = this.circumference(radius); - return _react.default.createElement("div", { - className: "donut-complex".concat(this.state.isLoaded ? ' donut-complex--loaded ' : ' ').concat(className) - }, _react.default.createElement("svg", { - height: size, - width: size, - viewBox: "0 0 ".concat(size, " ").concat(size) - }, this.state.segments.map(function (segment, i) { - return _react.default.createElement("g", { - key: i - }, _react.default.createElement("circle", _extends({}, circleProps, { - r: radius, - cx: halfSize, - cy: halfSize, - transform: segment.rotate, - stroke: segment.color, - strokeWidth: thickness, - strokeDasharray: circumference, - strokeDashoffset: _this2.strokeDashOffset(segment.value, circumference) - })), _react.default.createElement("text", _extends({}, textProps, { - x: segment.textCoords.x, - y: segment.textCoords.y, - dy: "3px", - textAnchor: "middle" - }), "".concat(Math.round(segment.percent * 100), "%"))); - }))); - } - }]); - - return ComplexDonut; -}(_react.default.Component); + }, []); + + var size = props.size, + radius = props.radius, + thickness = props.thickness, + className = props.className, + circleProps = props.circleProps, + textProps = props.textProps; + var halfSize = size / 2; + var circumference = getCircumference(radius); + return /*#__PURE__*/_react["default"].createElement("div", { + className: "donut-complex".concat(isLoaded ? ' donut-complex--loaded ' : ' ').concat(className) + }, /*#__PURE__*/_react["default"].createElement("svg", { + height: size, + width: size, + viewBox: "0 0 ".concat(size, " ").concat(size) + }, segments.map(function (segment, i) { + return /*#__PURE__*/_react["default"].createElement("g", { + key: i + }, /*#__PURE__*/_react["default"].createElement("circle", _extends({}, circleProps, { + r: radius, + cx: halfSize, + cy: halfSize, + transform: segment.rotate, + stroke: segment.color, + strokeWidth: thickness, + strokeDasharray: circumference, + strokeDashoffset: getStrokeDashOffset(segment.value, circumference) + })), /*#__PURE__*/_react["default"].createElement("text", _extends({}, textProps, { + x: segment.textCoords.x, + y: segment.textCoords.y, + dy: "3px", + textAnchor: "middle" + }), "".concat(Math.round(segment.percent * 100), "%"))); + }))); +}; exports.ComplexDonut = ComplexDonut; ComplexDonut.propTypes = { - size: _propTypes.default.number.isRequired, - radius: _propTypes.default.number.isRequired, - segments: _propTypes.default.arrayOf(_propTypes.default.shape({ - color: _propTypes.default.string, - value: _propTypes.default.number + size: _propTypes["default"].number.isRequired, + radius: _propTypes["default"].number.isRequired, + segments: _propTypes["default"].arrayOf(_propTypes["default"].shape({ + color: _propTypes["default"].string, + value: _propTypes["default"].number })).isRequired, - thickness: _propTypes.default.number.isRequired, - startAngle: _propTypes.default.number, - className: _propTypes.default.string, - circleProps: _propTypes.default.object, - textProps: _propTypes.default.object + thickness: _propTypes["default"].number.isRequired, + startAngle: _propTypes["default"].number, + className: _propTypes["default"].string, + circleProps: _propTypes["default"].object, + textProps: _propTypes["default"].object }; ComplexDonut.defaultProps = { size: 160, @@ -250,4 +203,4 @@ ComplexDonut.defaultProps = { textProps: {} }; var _default = ComplexDonut; -exports.default = _default; \ No newline at end of file +exports["default"] = _default; \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 8e06a2b..88539f5 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = exports.Donut = void 0; +exports["default"] = exports.Donut = void 0; var _react = _interopRequireDefault(require("react")); @@ -11,7 +11,7 @@ var _propTypes = _interopRequireDefault(require("prop-types")); require("./index.css"); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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); } @@ -29,7 +29,7 @@ var getClassName = function getClassName(p, c) { }; var renderProgress = function renderProgress(progress) { - return _react.default.createElement("strong", null, progress); + return /*#__PURE__*/_react["default"].createElement("strong", null, progress); }; var Donut = function Donut(_ref) { @@ -39,29 +39,29 @@ var Donut = function Donut(_ref) { onRender = _ref$onRender === void 0 ? renderProgress : _ref$onRender, _ref$prefix = _ref.prefix, prefix = _ref$prefix === void 0 ? PREFIX : _ref$prefix; - return _react.default.createElement("div", { + return /*#__PURE__*/_react["default"].createElement("div", { className: getClassName(prefix, progress < 0 ? ' is--negative' : '') - }, _react.default.createElement("svg", { + }, /*#__PURE__*/_react["default"].createElement("svg", { className: getClassName(prefix, '__canvas'), width: SIZE, height: SIZE, viewBox: "0 0 ".concat(SIZE, " ").concat(SIZE), xmlns: "http://www.w3.org/2000/svg" - }, _react.default.createElement("circle", _extends({ + }, /*#__PURE__*/_react["default"].createElement("circle", _extends({ className: getClassName(prefix, '__frame') - }, circleProps)), _react.default.createElement("circle", _extends({ + }, circleProps)), /*#__PURE__*/_react["default"].createElement("circle", _extends({ className: getClassName(prefix, '__circle'), strokeDasharray: "".concat(Math.abs(progress), " 100") - }, circleProps))), typeof onRender === 'function' && _react.default.createElement("div", { + }, circleProps))), typeof onRender === 'function' && /*#__PURE__*/_react["default"].createElement("div", { className: getClassName(prefix, '__text') }, onRender(progress))); }; exports.Donut = Donut; Donut.propTypes = { - progress: _propTypes.default.number, - onRender: _propTypes.default.func, - prefix: _propTypes.default.string + progress: _propTypes["default"].number, + onRender: _propTypes["default"].func, + prefix: _propTypes["default"].string }; Donut.defaultProps = { progress: 0, @@ -69,4 +69,4 @@ Donut.defaultProps = { prefix: PREFIX }; var _default = Donut; -exports.default = _default; \ No newline at end of file +exports["default"] = _default; \ No newline at end of file diff --git a/package.json b/package.json index f1e1ccb..e6b0337 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-svg-donuts", - "version": "1.0.0", + "version": "2.0.0", "description": "A ReactJS component for simple SVG donut graphs.", "main": "dist/index.js", "style": "dist/index.css", diff --git a/src/complex.js b/src/complex.js index 0f92ca8..4726457 100644 --- a/src/complex.js +++ b/src/complex.js @@ -5,36 +5,41 @@ let rotateAngle = 0; import './complex.css'; -class ComplexDonut extends React.Component { - loadTimeout = 0; +const getTotal = values => values.reduce((acc, { value }) => acc + value, 0); +const getPercent = (value, total) => value / total; +const sortValues = values => values.sort((a, b) => b.value - a.value); +const getCircumference = radius => 2 * Math.PI * radius; +const convertDegreesToRadians = angle => angle * (Math.PI / 180); - constructor(props) { - super(props); +const ComplexDonut = props => { + let loadTimeout; - this.state = { - total: this.total(props.segments), - segments: [], - transforms: this.transforms(), - isLoaded: false - }; - } + const total = getTotal(props.segments); - total = values => values.reduce((acc, { value }) => acc + value, 0); + const getTextCoordinates = (value, angleOffset) => { + const { size, radius, segments } = props; + const total = getTotal(segments); + const angle = (getPercent(value, total) * 360) / 2 + angleOffset; + const radians = convertDegreesToRadians(angle); - percent = (value, total) => value / total; + return { + x: radius * Math.cos(radians) + size / 2, + y: radius * Math.sin(radians) + size / 2 + }; + }; - transforms = () => { + const getTransforms = () => { const rotations = []; const textCoords = []; - const { startAngle, segments } = this.props; - const total = this.total(segments); + const { startAngle, segments } = props; + const total = getTotal(segments); rotateAngle = startAngle; - this.sortValues(segments).forEach(({ value }) => { + sortValues(segments).forEach(({ value }) => { const data = rotateAngle; - const percent = this.percent(value, total); - const { x, y } = this.textCoordinates(value, rotateAngle); + const percent = getPercent(value, total); + const { x, y } = getTextCoordinates(value, rotateAngle); rotations.push(data); textCoords.push({ x, y }); @@ -47,94 +52,72 @@ class ComplexDonut extends React.Component { return { rotations, textCoords }; }; - sortValues = values => values.sort((a, b) => b.value - a.value); - - circumference = radius => 2 * Math.PI * radius; - - degreesToRadians = angle => angle * (Math.PI / 180); - - strokeDashOffset = (value, circumference) => { - const diff = this.percent(value, this.state.total) * circumference; + const getStrokeDashOffset = (value, circumference) => { + const diff = getPercent(value, total) * circumference; return circumference - diff; }; - textCoordinates = (value, angleOffset) => { - const { size, radius, segments } = this.props; - const total = this.total(segments); - const angle = (this.percent(value, total) * 360) / 2 + angleOffset; - const radians = this.degreesToRadians(angle); + const [segments, setSegments] = React.useState([]); + const [isLoaded, setIsLoaded] = React.useState(false); - return { - x: radius * Math.cos(radians) + size / 2, - y: radius * Math.sin(radians) + size / 2 - }; - }; + React.useEffect(() => { + const { segments, size } = props; + const { rotations, textCoords } = getTransforms(); - componentDidMount = () => { - const { segments, size } = this.props; - const { - total, - transforms: { rotations, textCoords } - } = this.state; - - this.setState({ - segments: this.sortValues(segments).map(({ value, color }, i) => ({ + setSegments( + sortValues(segments).map(({ value, color }, i) => ({ value, color, - percent: this.percent(value, total), + percent: getPercent(value, total), rotate: `rotate(${rotations[i]}, ${size / 2}, ${size / 2})`, textCoords: textCoords[i] })) - }); + ); - this.loadTimeout = setTimeout(() => { - this.setState({ - isLoaded: true - }); + loadTimeout = setTimeout(() => { + setIsLoaded(true); }, 100); - }; - componentWillUnmount() { - this.clearTimeout(this.loadTimeout); - } - - render() { - const { size, radius, thickness, className, circleProps, textProps } = this.props; - const halfSize = size / 2; - const circumference = this.circumference(radius); - - return ( -
- - {this.state.segments.map((segment, i) => ( - - - - {`${Math.round(segment.percent * 100)}%`} - - - ))} - -
- ); - } -} + return () => { + clearTimeout(loadTimeout); + }; + }, []); + + const { size, radius, thickness, className, circleProps, textProps } = props; + const halfSize = size / 2; + const circumference = getCircumference(radius); + + return ( +
+ + {segments.map((segment, i) => ( + + + + {`${Math.round(segment.percent * 100)}%`} + + + ))} + +
+ ); +}; ComplexDonut.propTypes = { size: PropTypes.number.isRequired, From 8925cd2dd5d4dd970e17840916e79e5afc3f28c8 Mon Sep 17 00:00:00 2001 From: Atanas Atanasov Date: Fri, 4 Sep 2020 09:15:03 +0300 Subject: [PATCH 2/3] Upgrade packages --- yarn.lock | 65 +++++++++++++++---------------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/yarn.lock b/yarn.lock index 540a7c8..b7ad30b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,7 +34,7 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@7.11.6": +"@babel/core@7.11.6", "@babel/core@^7.1.0", "@babel/core@^7.7.5": version "7.11.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== @@ -56,38 +56,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.7.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.5.tgz#6ad96e2f71899ea3f9b651f0a911e85205d1ff6d" - integrity sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.6.1" - -"@babel/generator@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.5.tgz#a5582773425a468e4ba269d9a1f701fbca6a7a82" - integrity sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g== - dependencies: - "@babel/types" "^7.11.5" - jsesc "^2.5.1" - source-map "^0.6.1" - -"@babel/generator@^7.11.6": +"@babel/generator@^7.11.5", "@babel/generator@^7.11.6": version "7.11.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== @@ -1283,9 +1252,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "14.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.2.tgz#264b44c5a28dfa80198fc2f7b6d3c8a054b9491f" - integrity sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A== + version "14.6.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.4.tgz#a145cc0bb14ef9c4777361b7bbafa5cf8e3acb5a" + integrity sha512-Wk7nG1JSaMfMpoMJDKUsWYugliB2Vy55pdjLpmLixeyMi7HizW2I/9QoxsPCkXl3dO+ZOVqPumKaDUv5zJu2uQ== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1329,9 +1298,9 @@ source-map "^0.7.3" "@types/webpack@^4.41.8": - version "4.41.21" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.21.tgz#cc685b332c33f153bb2f5fc1fa3ac8adeb592dee" - integrity sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA== + version "4.41.22" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.22.tgz#ff9758a17c6bd499e459b91e78539848c32d0731" + integrity sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -2158,9 +2127,9 @@ camelcase@^6.0.0: integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== caniuse-lite@^1.0.30001111: - version "1.0.30001122" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001122.tgz#2c8ff631330d986a07a7ba7125cce77a1373b475" - integrity sha512-pxjw28CThdrqfz06nJkpAc5SXM404TXB/h5f4UJX+rrXJKE/1bu/KAILc2AY+O6cQIFtRjV9qOR2vaEp9LDGUA== + version "1.0.30001124" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001124.tgz#5d9998190258e11630d674fc50ea8e579ae0ced2" + integrity sha512-zQW8V3CdND7GHRH6rxm6s59Ww4g/qGWTheoboW9nfeMg7sUoopIfKCcNZUjwYRCOrvereh3kwDpZj4VLQ7zGtA== capture-exit@^2.0.0: version "2.0.0" @@ -2884,9 +2853,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.523: - version "1.3.556" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.556.tgz#d2a8fed6b93051c5c27d182c43c7bc4d88b77afb" - integrity sha512-g5cGpg6rOCXxyfaLCQIWz9Fx+raFfbZ6sc4QLfvvaiCERBzY6YD6rh5d12QN++bEF1Tm9osYnxP37lbN/92j4A== + version "1.3.562" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.562.tgz#79c20277ee1c8d0173a22af00e38433b752bc70f" + integrity sha512-WhRe6liQ2q/w1MZc8mD8INkenHivuHdrr4r5EQHNomy3NJux+incP6M6lDMd0paShP3MD0WGe5R1TWmEClf+Bg== elliptic@^6.5.3: version "6.5.3" @@ -4694,9 +4663,9 @@ json-parse-better-errors@^1.0.2: integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.0.tgz#371873c5ffa44304a6ba12419bcfa95f404ae081" - integrity sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q== + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" From 9b730631a3749cf6c7ce6a7dfe9ffe1b537a4bf2 Mon Sep 17 00:00:00 2001 From: Atanas Atanasov Date: Thu, 10 Sep 2020 14:45:25 +0300 Subject: [PATCH 3/3] Update README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c904ed..cd5afa1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ # React SVG Donuts -A ReactJS component for simple (and complex) SVG donuts. +> A ReactJS component for simple (and complex) SVG donuts. + +**The current version depends on the Hooks API introduced with React 16. If you need legacy React support, please use a 1.x.x version.** ## Demo