X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=skyquake%2Fframework%2Fwidgets%2Fgauge%2Fgauge.js;fp=skyquake%2Fframework%2Fwidgets%2Fgauge%2Fgauge.js;h=dc1a0839e496835de49f48e7649f8e097723e9ff;hb=e29efc315df33d546237e270470916e26df391d6;hp=0000000000000000000000000000000000000000;hpb=9c5e457509ba5a1822c316635c6308874e61b4b9;p=osm%2FUI.git diff --git a/skyquake/framework/widgets/gauge/gauge.js b/skyquake/framework/widgets/gauge/gauge.js new file mode 100644 index 000000000..dc1a0839e --- /dev/null +++ b/skyquake/framework/widgets/gauge/gauge.js @@ -0,0 +1,275 @@ + +/* + * + * Copyright 2016 RIFT.IO Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +var React = require("react"); +var ReactDOM = require('react-dom'); +var MIXINS = require("../mixins/ButtonEventListener.js"); +var Gauge = require("../../js/gauge-modified.js"); +var GUID = require("utils/guid"); +import _ from 'underscore' + + + + +/** + * Gauge Component + * It's props values and a brief description below + * + * min: minimum value expected + * max: maximum value expected + * width: width of gauge in px + * height: height of gauge in px + * value: the number displayed on the gauge + * resize: should the gauge resize with container + * unit: the units displayed on the gauge + * valueFormat: An object with an 'int' and 'dec' property. The 'int' is the min number of integer digits displayed + * and the 'dec' object is the min number of fractional digits displayed. + * + * + **/ +module.exports = React.createClass({ + displayName: 'Gauge', + mixins:MIXINS, + propTypes: { + min: React.PropTypes.number, + max: React.PropTypes.number, + width: React.PropTypes.number, + height: React.PropTypes.string, + value: React.PropTypes.number, + resize: React.PropTypes.bool, + isAggregate: React.PropTypes.bool, + units: React.PropTypes.string, + valueFormat: React.PropTypes.shape({ + 'int': React.PropTypes.number, + 'dec': React.PropTypes.number + }) + }, + clone: function(obj) { + if (null == obj || "object" != typeof obj) return obj; + var copy = obj.constructor(); + for (var attr in obj) { + if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr]; + } + return copy; + }, + + /** + * Defines default state. + * + * min: minimum value expected + * max: maximum value expected + * nSteps: fixed number for now. The number of ticks in the gauge. + * width: width of gauge in px + * height: height of gauge in px + * value: the number displayed on the gauge + * resize: should the gauge resize with container + * unit: the units displayed on the gauge + * valueFormat: An object with an 'int' and 'dec' property. The 'int' is the min number of integer digits displayed + * and the 'dec' object is the min number of fractional digits displayed. + */ + getInitialState: function() { + var valueFormatState = null + this.gauge = null; + this.gaugeID = GUID(); + if (!this.props.valueFormat) { + if ((this.props.max && this.props.max > 1000) || this.props.value) { + valueFormatState = { + "int": 1, + "dec": 0 + }; + } else { + valueFormatState = { + "int": 1, + "dec": 2 + }; + } + } else { + valueFormatState = this.props.valueFormat; + } + return { + //sizeOfButton: this.props.size || '', //There is no Medium value in CSS, default size is the absence of a value + min: this.props.min || 0, + max: this.props.max || 0, + nSteps: 14, + height: this.props.height || 200, + width: this.props.width || 200, + color: this.props.color || 'hsla(212, 57%, 50%, 1)', + value: this.props.value || 0, + valueFormat: valueFormatState, + isAggregate: this.props.isAggregate || false, + units: this.props.units || '', + resize:this.props.resize || false + + } + }, + + + /** + * Called when props are changed. Syncs props with state. + */ + componentWillReceiveProps: function(nextProps) { + this.setState({ + max:nextProps.max || this.state.max, + value:nextProps.value || 0, + valueFormat:nextProps.valueFormat || this.state.valueFormat + }); + }, + + /** + * Calls the render on the gauge object once the component first mounts + */ + componentDidMount: function() { + this.canvasRender(this.state); + }, + + /** + * If any of the state variables have changed, the component should update. + * Note, this is where the render step occures for the gauge object. + */ + shouldComponentUpdate: function(nextProps, nextState) { + var currentStateString = String(this.state.max) + String(this.state.valueFormat.int) + String(this.state.valueFormat.dec) + String(this.state.value); + var nextStateString = String(nextState.max) + String(nextState.valueFormat.int) + String(nextState.valueFormat.dec) + String(nextState.value); + if (currentStateString == nextStateString) { + return false; + } + this.state.valueFormat = this.determineValueFormat(nextState.value); + this.canvasRender(nextState); + return true; + }, + + /** + * Default value format based on units. + */ + determineValueFormat: function(value) { + if (value > 999 || this.state.units == "%") { + return { + "int": 1, + "dec": 0 + } + } + + return { + "int": 1, + "dec": 2 + } + }, + + + /** + * Render step for the gauge object. Sets some defaults, passes some of the component's state down. + */ + canvasRender: function(state) { + if (state.max == state.min) { + state.max = 14; + } + var range = state.max - state.min; + var step = Math.round(range / state.nSteps); + var majorTicks = []; + for (var i = 0; i <= state.nSteps; i++) { + majorTicks.push(state.min + (i * step)); + } + var redLine = state.min + (range * 0.9); + var config = { + isAggregate: state.isAggregate, + renderTo: ReactDOM.findDOMNode(document.getElementById(this.gaugeID)), + width: state.width, + height: state.height, + glow: false, + units: state.units, + title: false, + minValue: state.min, + maxValue: state.max, + majorTicks: majorTicks, + valueFormat: this.determineValueFormat(self.value), + minorTicks: 0, + strokeTicks: false, + highlights: [], + colors: { + plate: 'rgba(0,0,0,0)', + majorTicks: 'rgba(15, 123, 182, .84)', + minorTicks: '#ccc', + title: 'rgba(50,50,50,100)', + units: 'rgba(50,50,50,100)', + numbers: '#fff', + needle: { + start: 'rgba(255, 255, 255, 1)', + end: 'rgba(255, 255, 255, 1)' + } + } + }; + + var min = config.minValue; + var max = config.maxValue; + var N = 1000; + var increment = (max - min) / N; + for (i = 0; i < N; i++) { + var temp_color = 'rgb(0, 172, 238)'; + if (i > 0.5714 * N && i <= 0.6428 * N) { + temp_color = 'rgb(0,157,217)'; + } else if (i >= 0.6428 * N && i < 0.7142 * N) { + temp_color = 'rgb(0,142,196)'; + } else if (i >= 0.7142 * N && i < 0.7857 * N) { + temp_color = 'rgb(0,126,175)'; + } else if (i >= 0.7857 * N && i < 0.8571 * N) { + temp_color = 'rgb(0,122,154)'; + } else if (i >= 0.8571 * N && i < 0.9285 * N) { + temp_color = 'rgb(0,96,133)'; + } else if (i >= 0.9285 * N) { + temp_color = 'rgb(0,80,112)'; + } + config.highlights.push({ + from: i * increment, + to: increment * (i + 2), + color: temp_color + }) + } + var updateSize = _.debounce(function() { + config.maxValue = state.max; + }, 500); + if (state.resize) $(window).resize(updateSize) + + if (this.gauge) { + this.gauge.setValue(Math.ceil(state.value* 100) / 100) + this.gauge.updateConfig(config); + } else { + this.gauge = new Gauge(config); + this.gauge.setValue(Math.ceil(state.value* 100) / 100) + this.gauge.draw(); + } + }, + + /** + * Renders the Gauge Component + * Returns the canvas element the gauge will be housed in. + * @returns {*} + */ + render: function() { + var gaugeDOM = React.createElement("div", null, + React.createElement("canvas", + {className: "rwgauge", style: + {width:'100%','maxWidth':this.state.width + 'px','maxHeight':this.state.width}, + id:this.gaugeID + } + ) + ) + + + + return gaugeDOM; + } +});