react-liquid-gauge
Advanced tools
Comparing version 0.5.1 to 1.0.0
400
lib/index.js
@@ -17,6 +17,4 @@ 'use strict'; | ||
var _d3Timer = require('d3-timer'); | ||
var _d3Color = require('d3-color'); | ||
var _d3Shape = require('d3-shape'); | ||
var _d3Ease = require('d3-ease'); | ||
@@ -26,8 +24,18 @@ | ||
var _d3Selection = require('d3-selection'); | ||
var _d3Interpolate = require('d3-interpolate'); | ||
var _d3Scale = require('d3-scale'); | ||
var _d3Interpolate = require('d3-interpolate'); | ||
var _d3Selection = require('d3-selection'); | ||
var _d3Shape = require('d3-shape'); | ||
var _d3Timer = require('d3-timer'); | ||
require('d3-transition'); | ||
var _Gradient = require('./Gradient'); | ||
var _Gradient2 = _interopRequireDefault(_Gradient); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
@@ -51,2 +59,6 @@ | ||
var ucfirst = function ucfirst(s) { | ||
return s && s[0].toUpperCase() + s.slice(1); | ||
}; | ||
var LiquidFillGauge = (_temp = _class = function (_Component) { | ||
@@ -64,6 +76,2 @@ _inherits(LiquidFillGauge, _Component); | ||
value: function componentDidMount() { | ||
if (this.props.animate) { | ||
this.animate(); | ||
return; | ||
} | ||
this.draw(); | ||
@@ -74,6 +82,2 @@ } | ||
value: function componentDidUpdate(prevProps, prevState) { | ||
if (this.props.animate) { | ||
this.animate(); | ||
return; | ||
} | ||
this.draw(); | ||
@@ -87,14 +91,2 @@ } | ||
}, { | ||
key: 'setRes', | ||
value: function setRes() { | ||
var width = this.props.width * this.props.innerRadius / 2; | ||
var height = this.props.height * (this.props.innerRadius - this.props.margin) / 2; | ||
this.arr = new Array(100); | ||
this.wave = (0, _d3Selection.select)(this.clipPath).datum([this.props.value]); | ||
this.text = (0, _d3Selection.select)(this.container).selectAll('text').selectAll('tspan.value'); | ||
this.x = (0, _d3Scale.scaleLinear)().range([-width, width]).domain([0, 100]); | ||
this.y = (0, _d3Scale.scaleLinear)().range([height, -height]).domain([0, 100]); | ||
} | ||
}, { | ||
key: 'draw', | ||
@@ -104,69 +96,110 @@ value: function draw() { | ||
this.setRes(); | ||
var data = []; | ||
var samplePoints = 40; | ||
for (var i = 0; i <= samplePoints * this.props.waveFrequency; ++i) { | ||
data.push({ | ||
x: i / (samplePoints * this.props.waveFrequency), | ||
y: i / samplePoints | ||
}); | ||
} | ||
var val = (0, _d3Shape.area)().x(function (d, i) { | ||
return _this2.x(i); | ||
}).y0(function (d, i) { | ||
return _this2.y(_this2.props.amplitude * Math.sin(i / 4) + _this2.props.value); | ||
}).y1(function (d) { | ||
return _this2.props.height / 2; | ||
}); | ||
this.wave = (0, _d3Selection.select)(this.clipPath).datum(data).attr('T', '0'); | ||
this.wave.attr('d', val(this.arr)); | ||
this.text.text(Math.round(this.props.value)); | ||
} | ||
}, { | ||
key: 'animate', | ||
value: function animate() { | ||
var _this3 = this; | ||
var textElement = (0, _d3Selection.select)(this.container).selectAll('text').selectAll('tspan.value'); | ||
this.setRes(); | ||
var waveHeightScale = (0, _d3Scale.scaleLinear)().range([0, this.props.waveAmplitude, 0]).domain([0, 50, 100]); | ||
var val = (0, _d3Shape.area)().x(function (d, i) { | ||
return _this3.x(i); | ||
}).y0(function (d, i) { | ||
return _this3.y(Math.sin(i / 4)); | ||
}).y1(function (d) { | ||
return _this3.props.height / 2; | ||
}); | ||
var time = (0, _d3Scale.scaleLinear)().range([0, 1]).domain([0, this.props.animationTime]); | ||
var interpolateValue = (0, _d3Interpolate.interpolate)(this.wave.node().old || 0, this.props.value); | ||
var _props = this.props, | ||
onAnimationProgress = _props.onAnimationProgress, | ||
onAnimationEnd = _props.onAnimationEnd; | ||
var fillWidth = this.props.width * (this.props.innerRadius - this.props.margin); | ||
var waveScaleX = (0, _d3Scale.scaleLinear)().range([-fillWidth, fillWidth]).domain([0, 1]); | ||
var animationTimer = (0, _d3Timer.timer)(function (t) { | ||
var animate = _this3.props.ease(time(t)); | ||
var fillHeight = this.props.height * (this.props.innerRadius - this.props.margin); | ||
var waveScaleY = (0, _d3Scale.scaleLinear)().range([fillHeight / 2, -fillHeight / 2]).domain([0, 100]); | ||
val.y0(function (d, i) { | ||
return _this3.y(_this3.props.amplitude * Math.sin(i / _this3.props.frequency) + interpolateValue(animate)); | ||
}); | ||
if (this.props.waveAnimation) { | ||
this.animateWave(); | ||
} | ||
var value = Math.round(interpolateValue(animate)); | ||
_this3.text.text(value); | ||
onAnimationProgress({ | ||
value: value, | ||
outerArc: (0, _d3Selection.select)(_this3.container).select('.outerArc'), | ||
liquid: (0, _d3Selection.select)(_this3.container).select('.liquid'), | ||
liquidNumber: (0, _d3Selection.select)(_this3.container).select('.liquidNumber'), | ||
number: (0, _d3Selection.select)(_this3.container).select('.number') | ||
}); | ||
if (this.props.riseAnimation) { | ||
(function () { | ||
var clipArea = (0, _d3Shape.area)().x(function (d, i) { | ||
return waveScaleX(d.x); | ||
}).y1(function (d) { | ||
return _this2.props.height / 2; | ||
}); | ||
var timeScale = (0, _d3Scale.scaleLinear)().range([0, 1]).domain([0, _this2.props.riseAnimationTime]); | ||
// Use the old value if available | ||
var interpolate = (0, _d3Interpolate.interpolateNumber)(_this2.wave.node().oldValue || 0, _this2.props.value); | ||
var easing = 'ease' + ucfirst(_this2.props.riseAnimationEasing); | ||
var easingFn = ease[easing] ? ease[easing] : ease.easeCubicInOut; | ||
var riseAnimationTimer = (0, _d3Timer.timer)(function (t) { | ||
var value = interpolate(easingFn(timeScale(t))); | ||
clipArea.y0(function (d, i) { | ||
var radians = Math.PI * 2 * (d.y * 2); // double width | ||
return waveScaleY(waveHeightScale(value) * Math.sin(radians) + value); | ||
}); | ||
textElement.text(Math.round(value)); | ||
_this2.wave.attr('d', clipArea); | ||
_this3.wave.attr('d', val(_this3.arr)); | ||
_this2.props.riseAnimationOnProgress({ | ||
value: value, | ||
container: (0, _d3Selection.select)(_this2.container) | ||
}); | ||
if (t > _this3.props.animationTime) { | ||
animationTimer.stop(); | ||
var _value = Math.round(_this3.props.value); | ||
_this3.text.text(_value); | ||
onAnimationEnd({ | ||
value: _value, | ||
outerArc: (0, _d3Selection.select)(_this3.container).select('.outerArc'), | ||
liquid: (0, _d3Selection.select)(_this3.container).select('.liquid'), | ||
liquidNumber: (0, _d3Selection.select)(_this3.container).select('.liquidNumber'), | ||
number: (0, _d3Selection.select)(_this3.container).select('.number') | ||
if (t >= _this2.props.riseAnimationTime) { | ||
(function () { | ||
riseAnimationTimer.stop(); | ||
var value = interpolate(1); | ||
clipArea.y0(function (d, i) { | ||
var radians = Math.PI * 2 * (d.y * 2); // double width | ||
return waveScaleY(waveHeightScale(value) * Math.sin(radians) + value); | ||
}); | ||
textElement.text(Math.round(value)); | ||
_this2.wave.attr('d', clipArea); | ||
_this2.props.riseAnimationOnComplete({ | ||
value: value, | ||
container: (0, _d3Selection.select)(_this2.container) | ||
}); | ||
})(); | ||
} | ||
}); | ||
// Store the old value that can be used for the next animation | ||
_this2.wave.node().oldValue = _this2.props.value; | ||
})(); | ||
} else { | ||
(function () { | ||
var value = _this2.props.value; | ||
var clipArea = (0, _d3Shape.area)().x(function (d, i) { | ||
return waveScaleX(d.x); | ||
}).y0(function (d, i) { | ||
var radians = Math.PI * 2 * (d.y * 2); // double width | ||
return waveScaleY(waveHeightScale(value) * Math.sin(radians) + value); | ||
}).y1(function (d) { | ||
return _this2.props.height / 2; | ||
}); | ||
_this2.wave.attr('d', clipArea); | ||
textElement.text(Math.round(_this2.props.value)); | ||
})(); | ||
} | ||
} | ||
}, { | ||
key: 'animateWave', | ||
value: function animateWave() { | ||
var _this3 = this; | ||
var width = this.props.width * (this.props.innerRadius - this.props.margin) / 2; | ||
var waveAnimationScale = (0, _d3Scale.scaleLinear)().range([-width, width]).domain([0, 1]); | ||
var easing = 'ease' + ucfirst(this.props.waveAnimationEasing); | ||
var easingFn = ease[easing] ? ease[easing] : ease.easeLinear; | ||
this.wave.attr('transform', 'translate(' + waveAnimationScale(this.wave.attr('T')) + ', 0)').transition().duration(this.props.waveAnimationTime * (1 - this.wave.attr('T'))).ease(easingFn).attr('transform', 'translate(' + waveAnimationScale(1) + ', 0)').attr('T', '1').on('end', function () { | ||
_this3.wave.attr('T', '0'); | ||
if (_this3.props.waveAnimation) { | ||
_this3.animateWave(); | ||
} | ||
}); | ||
this.wave.node().old = this.props.value; | ||
} | ||
@@ -181,7 +214,24 @@ }, { | ||
var radius = Math.min(this.props.height / 2, this.props.width / 2); | ||
var liquidRadius = radius * (this.props.innerRadius - this.props.margin); | ||
var outerArc = (0, _d3Shape.arc)().outerRadius(this.props.outerRadius * radius).innerRadius(this.props.innerRadius * radius).startAngle(0).endAngle(Math.PI * 2); | ||
var cX = this.props.width * this.props.offsetX / 2; | ||
var cY = this.props.height * this.props.offsetY / 2; | ||
var fillCircleRadius = radius * (this.props.innerRadius - this.props.margin); | ||
var circle = (0, _d3Shape.arc)().outerRadius(this.props.outerRadius * radius).innerRadius(this.props.innerRadius * radius).startAngle(0).endAngle(Math.PI * 2); | ||
var cX = this.props.width / 2; | ||
var cY = this.props.height / 2; | ||
var textPixels = this.props.textSize * radius / 2; | ||
var fillColor = this.props.waveStyle.fill; | ||
var gradientStops = this.props.gradientStops || [{ | ||
key: '0%', | ||
stopColor: (0, _d3Color.color)(fillColor).darker(0.5).toString(), | ||
stopOpacity: 1, | ||
offset: '0%' | ||
}, { | ||
key: '50%', | ||
stopColor: fillColor, | ||
stopOpacity: 0.75, | ||
offset: '50%' | ||
}, { | ||
key: '100%', | ||
stopColor: (0, _d3Color.color)(fillColor).brighter(0.5).toString(), | ||
stopOpacity: 0.5, | ||
offset: '100%' | ||
}]; | ||
@@ -223,3 +273,3 @@ return _react2.default.createElement( | ||
{ | ||
className: 'number', | ||
className: 'text', | ||
style: { | ||
@@ -229,4 +279,4 @@ textAnchor: 'middle', | ||
}, | ||
fill: this.props.numberStyle.fill, | ||
stroke: this.props.numberStyle.stroke, | ||
fill: this.props.textStyle.fill, | ||
stroke: this.props.textStyle.stroke, | ||
transform: 'translate(' + this.props.textOffsetX + ',' + this.props.textOffsetY + ')' | ||
@@ -249,5 +299,5 @@ }, | ||
_react2.default.createElement('circle', { | ||
className: 'liquid', | ||
r: liquidRadius, | ||
fill: this.props.liquidStyle.fill | ||
className: 'wave', | ||
r: fillCircleRadius, | ||
fill: this.props.gradient ? 'url(#gradient)' : this.props.waveStyle.fill | ||
}), | ||
@@ -257,3 +307,3 @@ _react2.default.createElement( | ||
{ | ||
className: 'liquidNumber', | ||
className: 'waveText', | ||
style: { | ||
@@ -263,4 +313,4 @@ textAnchor: 'middle', | ||
}, | ||
fill: this.props.liquidNumberStyle.fill, | ||
stroke: this.props.liquidNumberStyle.stroke, | ||
fill: this.props.waveTextStyle.fill, | ||
stroke: this.props.waveTextStyle.stroke, | ||
transform: 'translate(' + this.props.textOffsetX + ',' + this.props.textOffsetY + ')' | ||
@@ -281,6 +331,6 @@ }, | ||
_react2.default.createElement('path', { | ||
className: 'outerArc', | ||
d: outerArc(), | ||
fill: this.props.outerArcStyle.fill, | ||
stroke: this.props.outerArcStyle.stroke | ||
className: 'circle', | ||
d: circle(), | ||
fill: this.props.circleStyle.fill, | ||
stroke: this.props.circleStyle.stroke | ||
}), | ||
@@ -296,2 +346,13 @@ _react2.default.createElement('circle', { | ||
}) | ||
), | ||
_react2.default.createElement( | ||
_Gradient2.default, | ||
{ id: 'gradient' }, | ||
gradientStops.map(function (stop, index) { | ||
if (!_react2.default.isValidElement(stop)) { | ||
var key = stop.key || index; | ||
return _react2.default.createElement('stop', _extends({ key: key }, stop)); | ||
} | ||
return stop; | ||
}) | ||
) | ||
@@ -305,76 +366,101 @@ ) | ||
}(_react.Component), _class.propTypes = { | ||
// a percentage from 0 to 100 | ||
// The width of the component. | ||
width: _react.PropTypes.number, | ||
// The height of the component. | ||
height: _react.PropTypes.number, | ||
// The percentage value (0-100). | ||
value: _react.PropTypes.number, | ||
// boolean if true then animate | ||
animate: _react.PropTypes.bool, | ||
// callback function called when animation is in progress | ||
onAnimationProgress: _react.PropTypes.func, | ||
// callback function called when animation is done | ||
onAnimationEnd: _react.PropTypes.func, | ||
// The percentage symbol (%). | ||
percentageSymbol: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.bool]), | ||
// The relative height of the text to display in the wave circle. 1 = 50%. | ||
textSize: _react.PropTypes.number, | ||
textOffsetX: _react.PropTypes.number, | ||
textOffsetY: _react.PropTypes.number, | ||
// Controls if the wave should rise from 0 to it's full height, or start at it's full height. | ||
riseAnimation: _react.PropTypes.bool, | ||
// The amount of time in milliseconds for the wave to rise from 0 to it's final height. | ||
riseAnimationTime: _react.PropTypes.number, | ||
// [d3-ease](https://github.com/d3/d3-ease) options: | ||
// See the [easing explorer](http://bl.ocks.org/mbostock/248bac3b8e354a9103c4) for a visual demostration. | ||
riseAnimationEasing: _react.PropTypes.string, | ||
// Progress callback function. | ||
riseAnimationOnProgress: _react.PropTypes.func, | ||
// Complete callback function. | ||
riseAnimationOnComplete: _react.PropTypes.func, | ||
// Controls if the wave scrolls or is static. | ||
waveAnimation: _react.PropTypes.bool, | ||
// The amount of time in milliseconds for a full wave to enter the wave circle. | ||
waveAnimationTime: _react.PropTypes.number, | ||
// [d3-ease](https://github.com/d3/d3-ease) options: | ||
// See the [easing explorer](http://bl.ocks.org/mbostock/248bac3b8e354a9103c4) for a visual demostration. | ||
waveAnimationEasing: _react.PropTypes.string, | ||
// The wave amplitude. | ||
waveAmplitude: _react.PropTypes.number, | ||
// The number of full waves per width of the wave circle. | ||
waveFrequency: _react.PropTypes.number, | ||
// Whether to apply linear gradients to fill the wave circle. | ||
gradient: _react.PropTypes.bool, | ||
// An array of the <stop> SVG element defines the ramp of colors to use on a gradient, which is a child element to either the <linearGradient> or the <radialGradient> element. | ||
gradientStops: _react.PropTypes.oneOfType([_react.PropTypes.arrayOf(_react.PropTypes.object), _react.PropTypes.arrayOf(_react.PropTypes.node), _react.PropTypes.node]), | ||
// onClick event handler. | ||
onClick: _react.PropTypes.func, | ||
// comes from Chart parent | ||
width: _react.PropTypes.number, | ||
// comes from Chart parent | ||
height: _react.PropTypes.number, | ||
// innerRadius | ||
// The radius of the inner circle. | ||
innerRadius: _react.PropTypes.number, | ||
// outer radius | ||
// The radius of the outer circle. | ||
outerRadius: _react.PropTypes.number, | ||
// margin between inner liquid and innerRadius | ||
// The size of the gap between the outer circle and wave circle as a percentage of the outer circle's radius. | ||
margin: _react.PropTypes.number, | ||
// d3 easing functions | ||
ease: _react.PropTypes.func, | ||
// animation Time | ||
animationTime: _react.PropTypes.number, | ||
// the wave amplitude | ||
amplitude: _react.PropTypes.number, | ||
// the wave frequency inverse, the higer the number the fewer the waves | ||
frequency: _react.PropTypes.number, | ||
// on click | ||
// The fill and stroke for the outer arc | ||
outerArcStyle: fillStroke, | ||
// The fill and stroke for the liquid | ||
liquidStyle: fillStroke, | ||
// The fill and stroke for the number part that is drenched in liquid | ||
liquidNumberStyle: fillStroke, | ||
// the fill and stroke of the number that is not drenched in liquid | ||
numberStyle: fillStroke, | ||
offsetY: _react.PropTypes.number, | ||
offsetX: _react.PropTypes.number, | ||
// The relative height of the text to display in the wave circle. 1 = 50% | ||
textSize: _react.PropTypes.number, | ||
textOffsetX: _react.PropTypes.number, | ||
textOffsetY: _react.PropTypes.number, | ||
percentageSymbol: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.bool]) | ||
// The fill and stroke of the outer circle. | ||
circleStyle: fillStroke, | ||
// The fill and stroke of the fill wave. | ||
waveStyle: fillStroke, | ||
// The fill and stroke of the value text when the wave does not overlap it. | ||
textStyle: fillStroke, | ||
// The fill and stroke of the value text when the wave overlaps it. | ||
waveTextStyle: fillStroke | ||
}, _class.defaultProps = { | ||
value: 100, | ||
animate: false, | ||
onAnimationProgress: function onAnimationProgress() {}, | ||
onAnimationEnd: function onAnimationEnd() {}, | ||
width: 400, | ||
height: 400, | ||
value: 0, | ||
percentageSymbol: '%', | ||
textSize: 1, | ||
textOffsetX: 0, | ||
textOffsetY: 0, | ||
riseAnimation: false, | ||
riseAnimationTime: 2000, | ||
riseAnimationEasing: 'cubicInOut', | ||
riseAnimationOnProgress: function riseAnimationOnProgress() {}, | ||
riseAnimationOnComplete: function riseAnimationOnComplete() {}, | ||
waveAnimation: false, | ||
waveAnimationTime: 2000, | ||
waveAnimationEasing: 'linear', | ||
waveAmplitude: 1, | ||
waveFrequency: 2, | ||
gradient: false, | ||
gradientStops: null, | ||
onClick: function onClick() {}, | ||
innerRadius: 0.9, | ||
outerRadius: 1.0, | ||
innerRadius: 0.9, | ||
margin: 0.025, | ||
ease: ease.easeCubicInOut, | ||
animationTime: 2000, | ||
amplitude: 1, | ||
frequency: 5, | ||
outerArcStyle: { | ||
circleStyle: { | ||
fill: 'rgb(23, 139, 202)' | ||
}, | ||
liquidStyle: { | ||
waveStyle: { | ||
fill: 'rgb(23, 139, 202)' | ||
}, | ||
liquidNumberStyle: { | ||
fill: 'rgb(164, 219, 248)' | ||
textStyle: { | ||
fill: 'rgb(0, 0, 0)' | ||
}, | ||
numberStyle: { | ||
fill: 'rgb(4, 86, 129)' | ||
}, | ||
offsetX: 1, | ||
offsetY: 1, | ||
textSize: 1, | ||
textOffsetX: 0, | ||
textOffsetY: 0, | ||
percentageSymbol: '%' | ||
waveTextStyle: { | ||
fill: 'rgb(255, 255, 255)' | ||
} | ||
}, _temp); | ||
@@ -381,0 +467,0 @@ |
{ | ||
"name": "react-liquid-gauge", | ||
"version": "0.5.1", | ||
"version": "1.0.0", | ||
"description": "React Liquid Gauge component", | ||
@@ -12,3 +12,3 @@ "main": "lib/index.js", | ||
"build": "babel --out-dir ./lib ./src", | ||
"build-examples": "cd examples; webpack; cp -af index.html ../docs/index.html", | ||
"build-examples": "cd examples; webpack", | ||
"clean": "rm -f lib/*", | ||
@@ -18,10 +18,6 @@ "demo": "http-server -p 8000 docs/", | ||
"lint:fix": "eslint --fix ./src", | ||
"precommit-check": "npm run lint", | ||
"test": "./babel-tap --coverage test/*.js", | ||
"coveralls": "./babel-tap --coverage --coverage-report=text-lcov test/*.js | node_modules/.bin/coveralls", | ||
"webpack-dev-server": "cd examples; webpack-dev-server --hot --inline --host 0.0.0.0 --port 8000" | ||
"dev": "cd examples; webpack-dev-server --hot --inline --host 0.0.0.0 --port 8000" | ||
}, | ||
"pre-commit": [ | ||
"precommit-check" | ||
], | ||
"repository": { | ||
@@ -42,3 +38,4 @@ "type": "git", | ||
"liquid", | ||
"gauge" | ||
"gauge", | ||
"chart" | ||
], | ||
@@ -49,2 +46,3 @@ "peerDependencies": { | ||
"dependencies": { | ||
"d3-color": "^1.0.2", | ||
"d3-ease": "^1.0.2", | ||
@@ -56,2 +54,3 @@ "d3-interpolate": "^1.1.2", | ||
"d3-timer": "^1.0.3", | ||
"d3-transition": "^1.0.3", | ||
"react-addons-shallow-compare": "^0.14.0 || ^15.0.0" | ||
@@ -69,7 +68,9 @@ }, | ||
"coveralls": "^2.11.15", | ||
"eslint": "^3.11.0", | ||
"eslint-config-trendmicro": "^0.5.0", | ||
"eslint": "^3.12.2", | ||
"eslint-config-trendmicro": "^0.5.1", | ||
"eslint-loader": "^1.6.1", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-plugin-jsx-a11y": "^3.0.1", | ||
"eslint-plugin-react": "^6.7.1", | ||
"eslint-plugin-jsx-a11y": "^2.2.3", | ||
"eslint-plugin-react": "^6.8.0", | ||
"html-webpack-plugin": "^2.24.1", | ||
"react": "^0.14.0 || ^15.0.0", | ||
@@ -76,0 +77,0 @@ "react-dom": "^0.14.0 || ^15.0.0", |
288
README.md
@@ -16,3 +16,3 @@ # react-liquid-gauge [![build status](https://travis-ci.org/trendmicro-frontend/react-liquid-gauge.svg?branch=master)](https://travis-ci.org/trendmicro-frontend/react-liquid-gauge) [![Coverage Status](https://coveralls.io/repos/github/trendmicro-frontend/react-liquid-gauge/badge.svg?branch=master)](https://coveralls.io/github/trendmicro-frontend/react-liquid-gauge?branch=master) | ||
``` | ||
npm install --save react react-dom react-liquid-gauge | ||
npm install --save react react-liquid-gauge | ||
``` | ||
@@ -23,2 +23,4 @@ | ||
```js | ||
import { color } from 'd3-color'; | ||
import { interpolateRgb } from 'd3-interpolate'; | ||
import React, { Component } from 'react'; | ||
@@ -28,33 +30,32 @@ import ReactDOM from 'react-dom'; | ||
const rgbcolor = (value) => { | ||
const startColor = { | ||
red: 0x64, | ||
green: 0x95, | ||
blue: 0xed | ||
}; | ||
const endColor = { | ||
red: 0xdc, | ||
green: 0x14, | ||
blue: 0x3c | ||
}; | ||
const diffRed = endColor.red - startColor.red; | ||
const diffGreen = endColor.green - startColor.green; | ||
const diffBlue = endColor.blue - startColor.blue; | ||
const percentFade = value / 100; | ||
return [ | ||
Math.floor(diffRed * percentFade) + startColor.red, | ||
Math.floor(diffGreen * percentFade) + startColor.green, | ||
Math.floor(diffBlue * percentFade) + startColor.blue | ||
]; | ||
}; | ||
class App extends Component { | ||
state = { | ||
value: Math.round(Math.random() * 100) | ||
value: 50 | ||
}; | ||
startColor = '#6495ed'; // cornflowerblue | ||
endColor = '#dc143c'; // crimson | ||
render() { | ||
const fillColor = `rgb(${rgbcolor(this.state.value).join(',')})`; | ||
const interpolate = interpolateRgb(this.startColor, this.endColor); | ||
const fillColor = interpolate(this.state.value / 100); | ||
const gradientStops = [ | ||
{ | ||
key: '0%', | ||
stopColor: color(fillColor).darker(0.5).toString(), | ||
stopOpacity: 1, | ||
offset: '0%' | ||
}, | ||
{ | ||
key: '50%', | ||
stopColor: fillColor, | ||
stopOpacity: 0.75, | ||
offset: '50%' | ||
}, | ||
{ | ||
key: '100%', | ||
stopColor: color(fillColor).brighter(0.5).toString(), | ||
stopOpacity: 0.5, | ||
offset: '100%' | ||
} | ||
]; | ||
@@ -64,27 +65,18 @@ return ( | ||
<LiquidFillGauge | ||
animate | ||
onAnimationProgress={(options) => { | ||
const { value, outerArc, liquid } = options; | ||
const fillColor = `rgb(${rgbcolor(value).join(',')})`; | ||
outerArc.attr('fill', fillColor); | ||
liquid.attr('fill', fillColor); | ||
}} | ||
outerArcStyle={{ | ||
fill: fillColor | ||
}} | ||
liquidStyle={{ | ||
fill: fillColor | ||
}} | ||
liquidNumberStyle={{ | ||
fill: 'rgb(255, 255, 255)' | ||
}} | ||
numberStyle={{ | ||
fill: 'rgb(0, 0, 0)' | ||
}} | ||
width={240} | ||
height={240} | ||
style={{ margin: '0 auto' }} | ||
width={400} | ||
height={400} | ||
value={this.state.value} | ||
textOffsetX={0} | ||
textOffsetY={0} | ||
riseAnimation | ||
waveAnimation | ||
waveFrequency={2} | ||
waveAmplitude={1} | ||
gradient | ||
gradientStops={gradientStops} | ||
circleStyle={{ fill: fillColor }} | ||
waveStyle={{ fill: fillColor }} | ||
textStyle={{ fill: 'rgb(0, 0, 0)' }} | ||
waveTextStyle={{ fill: 'rgb(255, 255, 255)' }} | ||
onClick={() => { | ||
@@ -125,9 +117,9 @@ this.setState({ value: Math.random() * 100 }); | ||
<table class="table table-bordered table-striped"> | ||
<table> | ||
<thead> | ||
<tr> | ||
<th style="width: 100px;">Name</th> | ||
<th style="width: 50px;">Type</th> | ||
<th>Default</th> | ||
<th>Description</th> | ||
<th align="left">Name</th> | ||
<th align="left">Type</th> | ||
<th align="left">Default</th> | ||
<th align="left">Description</th> | ||
</tr> | ||
@@ -137,134 +129,184 @@ </thead> | ||
<tr> | ||
<td>value</td> | ||
<td>width</td> | ||
<td>Number</td> | ||
<td>100</td> | ||
<td></td> | ||
<td>400</td> | ||
<td>The width of the component.</td> | ||
</tr> | ||
<tr> | ||
<td>animate</td> | ||
<td>Boolean</td> | ||
<td>false</td> | ||
<td></td> | ||
<td>height</td> | ||
<td>Number</td> | ||
<td>400</td> | ||
<td>The height of the component.</td> | ||
</tr> | ||
<tr> | ||
<td>onAnimationProgress</td> | ||
<td>Function(options)</td> | ||
<td></td> | ||
<td></td> | ||
<td>value</td> | ||
<td>Number</td> | ||
<td>0</td> | ||
<td>The percentage value (0-100).</td> | ||
</tr> | ||
<tr> | ||
<td>onAnimationEnd</td> | ||
<td>Function(options)</td> | ||
<td></td> | ||
<td></td> | ||
<td>percentageSymbol</td> | ||
<td>String</td> | ||
<td>'%'</td> | ||
<td>The percentage symbol (%).</td> | ||
</tr> | ||
<tr> | ||
<td>onClick</td> | ||
<td>Function(event)</td> | ||
<td></td> | ||
<td></td> | ||
<td>textSize</td> | ||
<td>Number</td> | ||
<td>1</td> | ||
<td>The relative height of the text to display in the wave circle. 1 = 50%.</td> | ||
</tr> | ||
<tr> | ||
<td>outerRadius</td> | ||
<td>textOffsetX</td> | ||
<td>Number</td> | ||
<td>1.0</td> | ||
<td>0</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td>innerRadius</td> | ||
<td>textOffsetY</td> | ||
<td>Number</td> | ||
<td>0.9</td> | ||
<td>0</td> | ||
<td></td> | ||
</tr> | ||
<tr> | ||
<td>margin</td> | ||
<td>riseAnimation</td> | ||
<td>Boolean</td> | ||
<td>false</td> | ||
<td>Controls if the wave should rise from 0 to it's full height, or start at it's full height.</td> | ||
</tr> | ||
<tr> | ||
<td>riseAnimationTime</td> | ||
<td>Number</td> | ||
<td>0.025</td> | ||
<td>2000</td> | ||
<td>The amount of time in milliseconds for the wave to rise from 0 to it's final height.</td> | ||
</tr> | ||
<tr> | ||
<td>riseAnimationEasing</td> | ||
<td>String</td> | ||
<td>'cubicInOut'</td> | ||
<td><a href="https://github.com/d3/d3-ease">d3-ease</a> options. See the <a href="http://bl.ocks.org/mbostock/248bac3b8e354a9103c4">easing explorer</a> for a visual demostration.</td> | ||
</tr> | ||
<tr> | ||
<td>riseAnimationOnProgress</td> | ||
<td>Function</td> | ||
<td></td> | ||
<td>Progress callback function.</td> | ||
</tr> | ||
<tr> | ||
<td>ease</td> | ||
<td>riseAnimationOnComplete</td> | ||
<td>Function</td> | ||
<td></td> | ||
<td></td> | ||
<td>Complete callback function.</td> | ||
</tr> | ||
<tr> | ||
<td>animationTime</td> | ||
<td>waveAnimation</td> | ||
<td>Boolean</td> | ||
<td>false</td> | ||
<td>Controls if the wave scrolls or is static.</td> | ||
</tr> | ||
<tr> | ||
<td>waveAnimationTime</td> | ||
<td>Number</td> | ||
<td>2000</td> | ||
<td></td> | ||
<td>The amount of time in milliseconds for a full wave to enter the wave circle.</td> | ||
</tr> | ||
<tr> | ||
<td>amplitude</td> | ||
<td>waveAnimationEasing</td> | ||
<td>String</td> | ||
<td>'linear'</td> | ||
<td><a href="https://github.com/d3/d3-ease">d3-ease</a> options. See the <a href="http://bl.ocks.org/mbostock/248bac3b8e354a9103c4">easing explorer</a> for a visual demostration.</td> | ||
</tr> | ||
<tr> | ||
<td>waveAmplitude</td> | ||
<td>Number</td> | ||
<td>1</td> | ||
<td></td> | ||
<td>The wave height as a percentage of the radius of the wave circle.</td> | ||
</tr> | ||
<tr> | ||
<td>frequency</td> | ||
<td>waveFrequency</td> | ||
<td>Number</td> | ||
<td>5</td> | ||
<td></td> | ||
<td>2</td> | ||
<td>The number of full waves per width of the wave circle.</td> | ||
</tr> | ||
<tr> | ||
<td>outerArcStyle</td> | ||
<td>Shape</td> | ||
<td>{ fill: 'rgb(23, 139, 202)' }</td> | ||
<td></td> | ||
<td>gradient</td> | ||
<td>Boolean</td> | ||
<td>false</td> | ||
<td>Whether to apply linear gradients to fill the wave circle.</td> | ||
</tr> | ||
<tr> | ||
<td>liquidStyle</td> | ||
<td>Shape</td> | ||
<td>{ fill: 'rgb(23, 139, 202)' }</td> | ||
<td>gradientStops</td> | ||
<td>Node|Array</td> | ||
<td></td> | ||
<td>An array of the <stop> SVG element defines the ramp of colors to use on a gradient, which is a child element to either the <linearGradient> or the <radialGradient> element.</td> | ||
</tr> | ||
<tr> | ||
<td>liquidNumberStyle</td> | ||
<td>Shape</td> | ||
<td>{ fill: 'rgb(164, 219, 248)' }</td> | ||
<td>onClick</td> | ||
<td>Function</td> | ||
<td></td> | ||
<td>onClick event handler.</td> | ||
</tr> | ||
<tr> | ||
<td>numberStyle</td> | ||
<td>Shape</td> | ||
<td>{ fill: 'rgb(4, 86, 129)' }</td> | ||
<td></td> | ||
<td>innerRadius</td> | ||
<td>Number</td> | ||
<td>0.9</td> | ||
<td>The radius of the inner circle. A value of 0.9 equals 90% of the radius of the outer circle.</td> | ||
</tr> | ||
<tr> | ||
<td>offsetX</td> | ||
<td>outerRadius</td> | ||
<td>Number</td> | ||
<td>1</td> | ||
<td></td> | ||
<td>1.0</td> | ||
<td>The radius of the outer circle. A value of 1 equals 100% of the radius of the outer circle.</td> | ||
</tr> | ||
<tr> | ||
<td>offsetY</td> | ||
<td>margin</td> | ||
<td>Number</td> | ||
<td>1</td> | ||
<td></td> | ||
<td>0.025</td> | ||
<td>The size of the gap between the outer circle and wave circle as a percentage of the radius of the outer circle. A value of 0.025 equals 2.5% of the radius of the outer circle.</td> | ||
</tr> | ||
<tr> | ||
<td>textSize</td> | ||
<td>Number</td> | ||
<td>1</td> | ||
<td></td> | ||
<td>circleStyle</td> | ||
<td>Object</td> | ||
<td> | ||
<pre>{ | ||
fill: 'rgb(23, 139, 202)' | ||
}</pre> | ||
</td> | ||
<td>The fill and stroke of the outer circle.</td> | ||
</tr> | ||
<tr> | ||
<td>textOffsetX</td> | ||
<td>Number</td> | ||
<td>0</td> | ||
<td></td> | ||
<td>waveStyle</td> | ||
<td>Object</td> | ||
<td> | ||
<pre>{ | ||
fill: 'rgb(23, 139, 202)' | ||
}</pre> | ||
</td> | ||
<td>The fill and stroke of the fill wave.</td> | ||
</tr> | ||
<tr> | ||
<td>textOffsetY</td> | ||
<td>Number</td> | ||
<td>0</td> | ||
<td></td> | ||
<td>textStyle</td> | ||
<td>Object</td> | ||
<td> | ||
<pre>{ | ||
fill: 'rgb(0, 0, 0)' | ||
}</pre> | ||
</td> | ||
<td>The fill and stroke of the value text when the wave does not overlap it.</td> | ||
</tr> | ||
<tr> | ||
<td>percentageSymbol</td> | ||
<td>String</td> | ||
<td>%</td> | ||
<td></td> | ||
<td>waveTextStyle</td> | ||
<td>Object</td> | ||
<td> | ||
<pre>{ | ||
fill: 'rgb(255, 255, 255)' | ||
}</pre> | ||
</td> | ||
<td>The fill and stroke of the value text when the wave overlaps it.</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
## License | ||
MIT |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
33856
5
421
0
307
10
21
1
+ Addedd3-color@^1.0.2
+ Addedd3-transition@^1.0.3
+ Addedd3-dispatch@1.0.6(transitive)
+ Addedd3-transition@1.3.2(transitive)