node-red-dashboard
Version:
A set of dashboard nodes for Node-RED
292 lines (285 loc) • 15.1 kB
HTML
<style>
input.series-color {
width: 100px;
text-align: center;
}
input.series-color::-webkit-color-swatch {
border: none;
}
</style>
<script type="text/javascript">
RED.nodes.registerType('ui_chart',{
category: 'dashboard',
color: 'rgb(119, 198, 204)',
defaults: {
name: {value: ''},
group: {type: 'ui_group', required: true},
order: {value: 0},
width: {value: 0, validate: function(v) {
var width = v||0;
var currentGroup = $('#node-input-group').val()||this.group;
var groupNode = RED.nodes.node(currentGroup);
var valid = !groupNode || +width <= +groupNode.width;
$("#node-input-size").toggleClass("input-error",!valid);
return valid;
}},
height: {value: 0},
label: {value: 'chart'},
chartType: {value: 'line'},
legend: {value: 'false'},
xformat: {value: 'HH:mm:ss'},
interpolate: {value: 'linear', required:true},
nodata: {value: ''},
dot: {value: false},
ymin: {value: '', validate:function(value) { return value === '' || RED.validators.number(); }},
ymax: {value: '', validate:function(value) { return value === '' || RED.validators.number(); }},
removeOlder: {value: 1, validate:RED.validators.number(), required:true},
removeOlderPoints: {value: '', validate:function(value) { return value === '' || RED.validators.number(); }},
removeOlderUnit: {value: '3600', required:true},
cutout: {value: 0},
useOneColor: {value: false},
colors: {value: ['#1F77B4', '#AEC7E8', '#FF7F0E', '#2CA02C', '#98DF8A', '#D62728', '#FF9896', '#9467BD', '#C5B0D5']},
useOldStyle: {value: false}
},
inputs:1,
outputs:2,
outputLabels: ["chart state","(deprecated)"],
align: "right",
icon: "ui_chart.png",
paletteLabel: 'chart',
label: function() { return this.name || (~this.label.indexOf("{{") ? null : this.label) || 'chart'; },
oneditprepare: function() {
if (!$("#node-input-chartType").val()) {
$("#node-input-chartType").val("line");
}
if (this.useOldStyle === undefined) {
$("#node-input-useOldStyle").prop('checked', true);
}
$("#node-input-size").elementSizer({
width: "#node-input-width",
height: "#node-input-height",
group: "#node-input-group"
});
$("#node-input-chartType").change(function() {
$("#legend-show").hide();
if ($(this).val() === "horizontalBar") {
$("#y-label-show").hide();
$("#x-label-show").show();
}
else {
$("#y-label-show").show();
$("#x-label-show").hide();
}
if ($(this).val() === "line") {
$("#x-axis-show").show();
$("#x-axis-label-show").show();
$("#interpolate-show").show();
$("#legend-show").show();
$("#y-axis-show").show();
$("#hole-size-show").hide();
$("#show-dot-field").show();
$("#show-useOneColor").hide();
}
else {
$("#x-axis-show").hide();
$("#x-axis-label-show").hide();
$("#interpolate-show").hide();
$("#show-dot-field").hide();
if (($(this).val() === "bar")||($(this).val() === "horizontalBar")) {
$("#show-useOneColor").show();
$("#legend-show").show();
}
else {
$("#show-useOneColor").hide();
}
if ($(this).val() === "pie") {
$("#y-axis-show").hide();
$("#legend-show").show();
$("#hole-size-show").show();
}
else {
$("#y-axis-show").show();
$("#hole-size-show").hide();
}
}
});
var setColour = function(id, value) {
$(id).val(value);
$(id).css("background-color", value);
var rgb = tinycolor(value).toRgb();
var level = ((rgb.r*299) + (rgb.g*587) + (rgb.b*114))/1000;
var textColor = (level >= 128) ? '#111111' : '#eeeeee';
$(id).css("color", textColor);
}
$(".series-color").change(function() {
setColour("#"+$(this).attr("id"), $(this).val());
});
var oval = $("#node-input-xformat").val();
if (!oval) { $("#node-input-xformat").val("HH:mm:ss"); }
var odef = 'custom';
if (oval === "HH:mm:ss") { odef = oval; }
if (oval === "HH:mm") { odef = oval; }
if (oval === "Y-M-D") { odef = oval; }
if (oval === "D/M") { odef = oval; }
if (oval === "dd HH:mm") { odef = oval; }
if (oval === "auto") { odef = oval; }
var ohms = {value:"HH:mm:ss", label:"HH:mm:ss", hasValue:false};
var ohm = {value:"HH:mm", label:"HH:mm", hasValue:false};
var oymd = {value:"Y-M-D", label:"Year-Month-Date", hasValue:false};
var odm = {value:"D/M", label:"Date/Month", hasValue:false};
var oahm = {value:"dd HH:mm", label:"Day HH:mm", hasValue:false};
var ocus = {value:"custom", label:"custom", icon:"red/images/typedInput/az.png"};
var oaut = {value:"auto", label:"automatic", hasValue:false};
$("#node-input-xformat").typedInput({
default: odef,
types:[ ohms, ohm, oahm, odm, oymd, ocus, oaut ]
});
var defaultColors = ['#1F77B4', '#AEC7E8', '#FF7F0E', '#2CA02C', '#98DF8A', '#D62728', '#FF9896', '#9467BD', '#C5B0D5'];
if (this.colors) {
for (var i=0; i<this.colors.length; i++) {
var value = this.colors[i] || defaultColors[i];
setColour("#node-input-color"+(i+1), value);
}
}
else {
for (var c=0; c<defaultColors.length; c++) {
setColour("#node-input-color"+(c+1), defaultColors[c]);
}
}
},
oneditsave: function() {
if ($("#node-input-xformat").typedInput('type') !== 'custom') {
$("#node-input-xformat").val($("#node-input-xformat").typedInput('type'));
}
this.colors = [$("#node-input-color1").val(),$("#node-input-color2").val(),$("#node-input-color3").val(),
$("#node-input-color4").val(),$("#node-input-color5").val(),$("#node-input-color6").val(),
$("#node-input-color7").val(),$("#node-input-color8").val(),$("#node-input-color9").val()];
}
});
</script>
<script type="text/x-red" data-template-name="ui_chart">
<div class="form-row">
<label for="node-input-group"><i class="fa fa-table"></i> Group</label>
<input type="text" id="node-input-group">
</div>
<div class="form-row">
<label><i class="fa fa-object-group"></i> Size</label>
<input type="hidden" id="node-input-width">
<input type="hidden" id="node-input-height">
<button class="editor-button" id="node-input-size"></button>
</div>
<div class="form-row">
<label for="node-input-label"><i class="fa fa-i-cursor"></i> Label</label>
<input type="text" id="node-input-label" placeholder="optional chart title">
</div>
<div class="form-row">
<label for="node-input-removeOlder"><i class="fa fa-line-chart"></i> Type</label>
<select id="node-input-chartType" style="width:159px; font-family:'FontAwesome','Helvetica Neue', Helvetica, Arial, sans-serif">
<option value="line">  Line chart</option>
<option value="bar">  Bar chart</option>
<option value="horizontalBar">  Bar chart (H)</option>
<option value="pie">  Pie chart</option>
<option value="polar-area">  Polar area chart</option>
<option value="radar">  Radar chart</option>
</select>
<div id="show-dot-field" style="display:inline-block;">
<input type="checkbox" id="node-input-dot" style="display:inline-block; width:auto; vertical-align:baseline; margin-left:40px; margin-right:5px;">enlarge points
</div>
</div>
<div class="form-row" id="x-axis-show">
<label for="node-input-removeOlder">X-axis</label>
<label for="node-input-removeOlder" style="width:auto">last</label>
<input type="text" id="node-input-removeOlder" style="width:50px;">
<select id="node-input-removeOlderUnit" style="width:80px;">
<option value="1">seconds</option>
<option value="60">minutes</option>
<option value="3600">hours</option>
<option value="86400">days</option>
<option value="604800">weeks</option>
</select>
<label for="node-input-removeOlderPoints" style="width:auto; margin-left:10px; margin-right:10px;">OR</label>
<input type="text" id="node-input-removeOlderPoints" style="width:60px;" placeholder="1000">
<span style="margin-left:5px;">points</span>
</div>
<div class="form-row" id="x-axis-label-show">
<label for="node-input-xformat">X-axis Label</label>
<input type="text" id="node-input-xformat" style="width:268px;">
</div>
<div class="form-row" id="y-axis-show">
<label id="y-label-show" for="node-input-ymin">Y-axis</label>
<label id="x-label-show" for="node-input-ymin">X-axis</label>
<label for="node-input-ymin" style="width:auto">min</label>
<input type="text" id="node-input-ymin" style="width:92px">
<label for="not-input-ymax" style="width:auto; margin-left:20px;">max</label>
<input type="text" id="node-input-ymax" style="width:92px">
</div>
<div class="form-row" id="legend-show">
<label for="node-input-legend">Legend</label>
<select id="node-input-legend" style="width:120px;">
<option value="false">None</option>
<option value="true">Show</option>
</select>
<span id="interpolate-show"> Interpolate
<select id="node-input-interpolate" style="width:120px;">
<option value="linear">linear</option>
<option value="step">step</option>
<option value="bezier">bezier</option>
</select>
</span>
<span id="hole-size-show"> Cutout
<input type="text" id="node-input-cutout" style="width:35px"> %
</span>
</div>
<div id="show-useOneColor" style="display:none;">
<input type="checkbox" id="node-input-useOneColor" style="display:inline-block; width:auto; vertical-align:baseline; margin-left:105px; margin-right:5px;">Use first colour for all bars
</div>
<div class="form-row" id="ui-chart-colours">
<label for="node-input-color1">Series Colours</label>
<input type="color" id="node-input-color1" class="series-color"/>
<input type="color" id="node-input-color2" class="series-color"/>
<input type="color" id="node-input-color3" class="series-color"/>
<div style="margin-top:5px; margin-left:104px;">
<input type="color" id="node-input-color4" class="series-color"/>
<input type="color" id="node-input-color5" class="series-color"/>
<input type="color" id="node-input-color6" class="series-color"/>
</div>
<div style="margin-top:5px; margin-left:104px;">
<input type="color" id="node-input-color7" class="series-color"/>
<input type="color" id="node-input-color8" class="series-color"/>
<input type="color" id="node-input-color9" class="series-color"/>
</div>
</div>
<div class="form-row">
<label for="node-input-nodata">Blank label</label>
<input type="text" id="node-input-nodata" placeholder="display this text before valid data arrives">
</div>
<div class="form-row">
<input type="checkbox" id="node-input-useOldStyle" style="display:inline-block; width:auto; vertical-align:baseline; margin-left:105px; margin-right:5px;">Use deprecated (pre 2.5.0) data format.
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name">
</div>
</script>
<script type="text/x-red" data-help-name="ui_chart">
<p>Plots the input values on a chart. This can either be a time based line chart, a bar chart (vertical or horizontal),
or a pie chart.</p>
<p>Each input <code>msg.payload</code> value will be converted to a number. If the
conversion fails, the message is ignored.</p>
<p>Minimum and Maximum <b>Y</b> axis values are optional. The graph will auto-scale to any values received.</p>
<p>Multiple series can be shown on the same chart by using a different <code>msg.topic</code>
value on each input message. Multiple bars of the same series can be shown by using the <code>msg.label</code> property.</p>
<p>The <b>X</b> axis defines a time window or a maximum number of points to display. Older data will be automatically removed from the graph.
The axis labels can be formatted using a <a href="https://momentjs.com/docs/#/displaying/format/" target="_blank">
Moment.js time formatted</a> string.</p>
<p>Inputting a <code>msg.payload</code> containing a blank array <code>[]</code> will clear the chart.</p>
<p>See <b><a href="https://github.com/node-red/node-red-dashboard/blob/master/Charts.md" target="_new">this information</a></b>
for how to pre-format data to be passed in as a complete chart.</p>
<p>The <b>Blank label</b> field can be used to display some text before any valid data is received.</p>
<p>The label can also be set by a message property by setting
the field to the name of the property, for example <code>{{msg.topic}}</code>.</p>
<p>The node output contains an array of the chart state that can be persisted if needed. This can be passed
into the chart node to re-display the persisted data.
The node second output should no longer be used and will be removed in a future release. Use the
<code>ui_control</code> node to trigger a restore if needed.</p>
</script>