diff --git a/README.md b/README.md index 95615e1..dbce951 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ The props for the chart: | animate | PropTypes.bool | Whether or not to animate the needle when loaded | true | | animDelay | PropTypes.number | Delay in ms before start the needle animation | 500 | | formatTextValue | PropTypes.func | Format you own text value (example: value => value+'%') | null | +| stopNeedleAtMax | PropTypes.bool | Whether or not the needle should stop rotating at max | false | ##### Colors for the chart diff --git a/dist/GaugeChart/index.js b/dist/GaugeChart/index.js index 3b55916..9dabc7d 100644 --- a/dist/GaugeChart/index.js +++ b/dist/GaugeChart/index.js @@ -143,7 +143,9 @@ GaugeChart.defaultProps = { hideText: false, animate: true, animDelay: 500, - formatTextValue: null + formatTextValue: null, + fontSize: null, + stopNeedleAtMax: false }; GaugeChart.propTypes = { id: _propTypes.default.string.isRequired, @@ -162,7 +164,9 @@ GaugeChart.propTypes = { needleBaseColor: _propTypes.default.string, hideText: _propTypes.default.bool, animate: _propTypes.default.bool, - formatTextValue: _propTypes.default.func + formatTextValue: _propTypes.default.func, + fontSize: _propTypes.default.string, + stopNeedleAtMax: _propTypes.default.bool }; // This function update arc's datas when component is mounting or when one of arc's props is updated var setArcData = function setArcData(props, nbArcsToDisplay, colorArray, arcData) { @@ -237,14 +241,15 @@ var drawNeedle = function drawNeedle(resize, prevProps, props, width, needle, co needleColor = props.needleColor, needleBaseColor = props.needleBaseColor, hideText = props.hideText, - animate = props.animate; + animate = props.animate, + stopNeedleAtMax = props.stopNeedleAtMax; var needleRadius = 15 * (width.current / 500), // Make the needle radius responsive centerPoint = [0, -needleRadius / 2]; //Draw the triangle //var pathStr = `M ${leftPoint[0]} ${leftPoint[1]} L ${topPoint[0]} ${topPoint[1]} L ${rightPoint[0]} ${rightPoint[1]}`; var prevPercent = prevProps ? prevProps.percent : 0; - var pathStr = calculateRotation(prevPercent || percent, outerRadius, width); + var pathStr = calculateRotation(prevPercent || percent, outerRadius, width, stopNeedleAtMax); needle.current.append("path").attr("d", pathStr).attr("fill", needleColor); //Add a circle at the bottom of needle needle.current.append('circle').attr('cx', centerPoint[0]).attr('cy', centerPoint[1]).attr('r', needleRadius).attr('fill', needleBaseColor); @@ -259,15 +264,24 @@ var drawNeedle = function drawNeedle(resize, prevProps, props, width, needle, co var currentPercent = (0, _d.interpolateNumber)(prevPercent, percent); return function (percentOfPercent) { var progress = currentPercent(percentOfPercent); + + if (stopNeedleAtMax && progress > 1.0) { + progress = 1.05; // just above 1.0 to indicate that it is out of bounds + } + return container.current.select(".needle path").attr("d", calculateRotation(progress, outerRadius, width)); }; }); } else { - container.current.select(".needle path").attr("d", calculateRotation(percent, outerRadius, width)); + container.current.select(".needle path").attr("d", calculateRotation(percent, outerRadius, width, stopNeedleAtMax)); } }; -var calculateRotation = function calculateRotation(percent, outerRadius, width) { +var calculateRotation = function calculateRotation(percent, outerRadius, width, stopNeedleAtMax) { + if (stopNeedleAtMax && percent > 1.0) { + percent = 1.05; // just above 1.0 to indicate that it is out of bounds + } + var needleLength = outerRadius.current * 0.55, //TODO: Maybe it should be specified as a percentage of the arc radius? needleRadius = 15 * (width.current / 500), @@ -287,12 +301,13 @@ var percentToRad = function percentToRad(percent) { var addText = function addText(percentage, props, outerRadius, width, g) { - var formatTextValue = props.formatTextValue; + var formatTextValue = props.formatTextValue, + fontSize = props.fontSize; var textPadding = 20; var text = formatTextValue ? formatTextValue(floatingNumber(percentage)) : floatingNumber(percentage) + '%'; g.current.append('g').attr('class', 'text-group').attr('transform', "translate(".concat(outerRadius.current, ", ").concat(outerRadius.current / 2 + textPadding, ")")).append('text').text(text) // this computation avoid text overflow. When formatted value is over 10 characters, we should reduce font size .style('font-size', function () { - return "".concat(width.current / 11 / (text.length > 10 ? text.length / 10 : 1), "px"); + return fontSize ? fontSize : "".concat(width.current / 11 / (text.length > 10 ? text.length / 10 : 1), "px"); }).style('fill', props.textColor).attr('class', 'percent-text'); }; diff --git a/package.json b/package.json index 573c015..38118e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-gauge-chart", - "version": "0.2.5", + "version": "0.2.6", "main": "dist/index", "module": "dist/index", "typings": "dist/index", diff --git a/src/App.js b/src/App.js index 0b34d36..35b42cc 100644 --- a/src/App.js +++ b/src/App.js @@ -128,7 +128,6 @@ const App = () => { nrOfLevels={420} arcsLength={arcs} colors={['#5BE12C', '#F5CD19', '#EA4228']} - percent={0.37} arcPadding={0.02} /> diff --git a/src/lib/GaugeChart/index.js b/src/lib/GaugeChart/index.js index a2a7763..6a65236 100644 --- a/src/lib/GaugeChart/index.js +++ b/src/lib/GaugeChart/index.js @@ -122,6 +122,7 @@ GaugeChart.defaultProps = { animate: true, animDelay: 500, formatTextValue: null, + stopNeedleAtMax: false, fontSize: null, animateDuration: 3000 } @@ -145,6 +146,7 @@ GaugeChart.propTypes = { animate: PropTypes.bool, formatTextValue: PropTypes.func, fontSize: PropTypes.string, + stopNeedleAtMax: PropTypes.bool, animateDuration: PropTypes.number, } @@ -231,13 +233,13 @@ const getColors = (props, nbArcsToDisplay) => { //If 'resize' is true then the animation does not play const drawNeedle = (resize, prevProps, props, width, needle, container, outerRadius, g) => { - const { percent, needleColor, needleBaseColor, hideText, animate } = props; + const { percent, needleColor, needleBaseColor, hideText, animate, stopNeedleAtMax } = props; var needleRadius = 15*(width.current / 500) , // Make the needle radius responsive centerPoint = [0, -needleRadius/2]; //Draw the triangle //var pathStr = `M ${leftPoint[0]} ${leftPoint[1]} L ${topPoint[0]} ${topPoint[1]} L ${rightPoint[0]} ${rightPoint[1]}`; const prevPercent = prevProps ? prevProps.percent : 0; - var pathStr = calculateRotation(prevPercent || percent, outerRadius, width); + var pathStr = calculateRotation(prevPercent || percent, outerRadius, width, stopNeedleAtMax); needle.current.append("path") .attr("d", pathStr) .attr("fill", needleColor); @@ -260,17 +262,23 @@ const drawNeedle = (resize, prevProps, props, width, needle, container, outerRad .tween('progress', function(){ const currentPercent = interpolateNumber(prevPercent, percent); return function(percentOfPercent){ - const progress = currentPercent(percentOfPercent); + var progress = currentPercent(percentOfPercent); + if (stopNeedleAtMax && progress > 1.0) { + progress = 1.05; // just above 1.0 to indicate that it is out of bounds + } return container.current.select(`.needle path`).attr("d", calculateRotation(progress, outerRadius, width)); } }); } else{ - container.current.select(`.needle path`).attr("d", calculateRotation(percent, outerRadius, width)); + container.current.select(`.needle path`).attr("d", calculateRotation(percent, outerRadius, width, stopNeedleAtMax)); } } -const calculateRotation = (percent, outerRadius, width) => { +const calculateRotation = (percent, outerRadius, width, stopNeedleAtMax) => { + if (stopNeedleAtMax && percent > 1.0) { + percent = 1.05; // just above 1.0 to indicate that it is out of bounds + } var needleLength = outerRadius.current * 0.55, //TODO: Maybe it should be specified as a percentage of the arc radius? needleRadius = 15 * (width.current / 500), theta = percentToRad(percent),