2017-03-31 14:53:19 +02:00
|
|
|
/**
|
|
|
|
* File: widget-gauge.js
|
|
|
|
* Author: Ricardo Hernandez-Montoya <rhernandez@gridhound.de>
|
|
|
|
* Date: 31.03.2017
|
|
|
|
* Copyright: 2017, Institute for Automation of Complex Power Systems, EONERC
|
|
|
|
* This file is part of VILLASweb. All Rights Reserved. Proprietary and confidential.
|
|
|
|
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
|
|
|
**********************************************************************************/
|
|
|
|
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
import { Gauge } from 'gaugeJS';
|
|
|
|
|
|
|
|
class WidgetGauge extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.gaugeCanvas = null;
|
|
|
|
this.gauge = null;
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
value: 0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-05 17:17:58 +02:00
|
|
|
staticLabels(widget_height) {
|
2017-04-20 15:06:17 +02:00
|
|
|
let label_font_size = Math.floor(widget_height * 0.055); // font scaling factor, integer for performance
|
2017-04-03 13:52:39 +02:00
|
|
|
return {
|
|
|
|
font: label_font_size + 'px "Helvetica Neue"',
|
|
|
|
labels: [0.0, 0.1, 0.5, 0.9, 1.0],
|
|
|
|
color: "#000000",
|
|
|
|
fractionDigits: 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-05 17:17:58 +02:00
|
|
|
computeGaugeOptions(widget_height) {
|
2017-04-03 13:52:39 +02:00
|
|
|
return {
|
2017-03-31 14:53:19 +02:00
|
|
|
angle: -0.25,
|
|
|
|
lineWidth: 0.2,
|
|
|
|
pointer: {
|
|
|
|
length: 0.6,
|
|
|
|
strokeWidth: 0.035
|
|
|
|
},
|
2017-04-03 13:52:39 +02:00
|
|
|
radiusScale: 0.9,
|
2017-03-31 14:53:19 +02:00
|
|
|
colorStart: '#6EA2B0',
|
|
|
|
colorStop: '#6EA2B0',
|
|
|
|
strokeColor: '#E0E0E0',
|
2017-04-03 13:52:39 +02:00
|
|
|
highDpiSupport: true,
|
2017-04-05 17:17:58 +02:00
|
|
|
staticLabels: this.staticLabels(widget_height)
|
2017-03-31 14:53:19 +02:00
|
|
|
};
|
2017-04-03 13:52:39 +02:00
|
|
|
}
|
2017-03-31 14:53:19 +02:00
|
|
|
|
2017-04-03 13:52:39 +02:00
|
|
|
componentDidMount() {
|
2017-04-05 17:17:58 +02:00
|
|
|
const opts = this.computeGaugeOptions(this.props.widget.height);
|
2017-03-31 14:53:19 +02:00
|
|
|
this.gauge = new Gauge(this.gaugeCanvas).setOptions(opts);
|
|
|
|
this.gauge.maxValue = 1;
|
|
|
|
this.gauge.setMinValue(0);
|
|
|
|
this.gauge.animationSpeed = 30;
|
|
|
|
this.gauge.set(this.state.value);
|
|
|
|
}
|
|
|
|
|
2017-04-20 15:06:17 +02:00
|
|
|
shouldComponentUpdate(nextProps, nextState) {
|
2017-04-03 13:52:39 +02:00
|
|
|
|
2017-04-20 15:06:17 +02:00
|
|
|
// Check if size changed, resize labels if it did (the canvas itself is scaled with css)
|
|
|
|
if (this.props.widget.height !== nextProps.widget.height) {
|
|
|
|
this.updateAfterResize(nextProps.widget.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
// signal component update only if the value changed
|
|
|
|
return this.state.value !== nextState.value;
|
2017-03-31 14:53:19 +02:00
|
|
|
}
|
|
|
|
|
2017-07-12 12:25:09 +02:00
|
|
|
componentWillReceiveProps(nextProps) {
|
2017-03-31 14:53:19 +02:00
|
|
|
// update value
|
|
|
|
const simulator = nextProps.widget.simulator;
|
|
|
|
|
2017-07-12 12:25:09 +02:00
|
|
|
if (nextProps.data == null || nextProps.data[simulator.node][simulator.simulator] == null || nextProps.data[simulator.node][simulator.simulator].values == null) {
|
2017-03-31 14:53:19 +02:00
|
|
|
this.setState({ value: 0 });
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if value has changed
|
2017-07-12 12:25:09 +02:00
|
|
|
const signal = nextProps.data[simulator.node][simulator.simulator].values[nextProps.widget.signal];
|
2017-04-03 13:52:39 +02:00
|
|
|
// Take just 3 decimal positions
|
|
|
|
// Note: Favor this method over Number.toFixed(n) in order to avoid a type conversion, since it returns a String
|
2017-07-12 12:50:38 +02:00
|
|
|
if (signal != null) {
|
|
|
|
const new_value = Math.round( signal[signal.length - 1].y * 1e3 ) / 1e3;
|
|
|
|
if (this.state.value !== new_value) {
|
|
|
|
this.setState({ value: new_value });
|
|
|
|
|
|
|
|
// update gauge's value
|
|
|
|
this.gauge.set(new_value);
|
|
|
|
}
|
2017-03-31 14:53:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-20 15:06:17 +02:00
|
|
|
updateAfterResize(newHeight) {
|
|
|
|
// Update labels after resize
|
|
|
|
this.gauge.setOptions({ staticLabels: this.staticLabels(newHeight) });
|
|
|
|
}
|
|
|
|
|
2017-03-31 14:53:19 +02:00
|
|
|
render() {
|
2017-04-03 13:52:39 +02:00
|
|
|
var componentClass = this.props.editing ? "gauge-widget editing" : "gauge-widget";
|
2017-04-03 15:56:48 +02:00
|
|
|
var signalType = null;
|
|
|
|
|
|
|
|
if (this.props.simulation) {
|
2017-07-12 12:25:09 +02:00
|
|
|
var simulationModel = this.props.simulation.models.filter((model) => model.simulator.node === this.props.widget.simulator.node && model.simulator.simulator === this.props.widget.simulator.simulator)[0];
|
2017-07-12 12:50:38 +02:00
|
|
|
signalType = (simulationModel != null && simulationModel.length > 0) ? simulationModel.mapping[this.props.widget.signal].type : '';
|
2017-04-03 15:56:48 +02:00
|
|
|
}
|
2017-04-03 13:52:39 +02:00
|
|
|
|
2017-03-31 14:53:19 +02:00
|
|
|
return (
|
2017-04-03 13:52:39 +02:00
|
|
|
<div className={ componentClass }>
|
2017-03-31 14:53:19 +02:00
|
|
|
<div className="gauge-name">{ this.props.widget.name }</div>
|
|
|
|
<canvas ref={ (node) => this.gaugeCanvas = node } />
|
2017-04-03 15:56:48 +02:00
|
|
|
<div className="gauge-unit">{ signalType }</div>
|
2017-03-31 14:53:19 +02:00
|
|
|
<div className="gauge-value">{ this.state.value }</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default WidgetGauge;
|