adapted to flot
This commit is contained in:
parent
58df4816b6
commit
2350f62992
5 changed files with 114 additions and 188 deletions
|
@ -8,14 +8,12 @@
|
|||
<script type="text/javascript" src="javascripts/jquery-treeTable.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jquery-extensions.js"></script>
|
||||
|
||||
<script type="text/javascript" src="javascripts/jqplot/jquery.jqplot.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.canvasTextRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.dateAxisRenderer.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.cursor.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.highlighter.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jqplot/plugins/jqplot.trendline.min.js"></script>
|
||||
<!--[if IE]><script language="javascript" type="text/javascript" src="javascripts/excanvas.min.js"></script><![endif]-->
|
||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.js"></script>
|
||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.selection.js"></script>
|
||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.navigate.js"></script>
|
||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.crosshair.js"></script>
|
||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.symbol.js"></script>
|
||||
|
||||
<script type="text/javascript" src="javascripts/json.js"></script>
|
||||
<script type="text/javascript" src="javascripts/uuid.js"></script>
|
||||
|
|
|
@ -45,10 +45,7 @@ function showEntities() {
|
|||
var i = 0;
|
||||
eachRecursive(vz.entities, function(entity, parent) {
|
||||
entity.active = true; // TODO active by default or via backend property?
|
||||
entity.color = vz.options.plot.seriesColors[i++ % vz.options.plot.seriesColors.length];
|
||||
|
||||
vz.plot.series[vz.plot.series.length] = vz.plot.seriesDefault;
|
||||
|
||||
entity.color = vz.options.plot.colors[i++ % vz.options.plot.colors.length];
|
||||
|
||||
$('#entities tbody').append(
|
||||
$('<tr>')
|
||||
|
@ -137,7 +134,7 @@ function showEntityDetails(entity) {
|
|||
});
|
||||
}
|
||||
|
||||
function validateChannel(form) {
|
||||
function validateEntity(form) {
|
||||
var entity = getDefinition(entities, form.type.value);
|
||||
|
||||
$.each(entity.required, function(index, property) {
|
||||
|
@ -184,57 +181,13 @@ function validateProperty(property, value) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entities from backend
|
||||
*/
|
||||
function fetchEntities() {
|
||||
$.getJSON(backend + '/capabilities/definition/entity.json', function(data) {
|
||||
entities = data.definition.entity;
|
||||
|
||||
// Add channel types to dropdown
|
||||
$('#new select').empty();
|
||||
$.each(entities, function(index, entity) {
|
||||
if (entity.model == 'Volkszaehler\\Model\\Channel') {
|
||||
$('#new select').append('<option value="' + entity.name + '">' + entity.translation.de + '</option>');
|
||||
}
|
||||
});
|
||||
|
||||
// show related properties
|
||||
$('#new select').trigger('change');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties from backend
|
||||
*/
|
||||
function fetchProperties() {
|
||||
$.getJSON(backend + '/capabilities/definition/property.json', function(data) {
|
||||
properties = data.definition.property;
|
||||
|
||||
// show related properties
|
||||
$('#new select').trigger('change');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get channels from controller
|
||||
*/
|
||||
function fetchChannels() {
|
||||
$.getJSON(controller, function(data) {
|
||||
channels = data;
|
||||
|
||||
// add fetched channels to table
|
||||
showChannels();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show from for new Channel
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
function showEntityForm(type) {
|
||||
function getEntityDOM(type) {
|
||||
$('#properties').empty();
|
||||
var entity = getDefinition(entities, type);
|
||||
|
||||
|
@ -255,66 +208,7 @@ function showEntityForm(type) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid
|
||||
* @return
|
||||
*/
|
||||
function deleteChannel(uuid) {
|
||||
$.getJSON(controller, { operation: 'delete', uuid: uuid }, function(data) {
|
||||
channels = data;
|
||||
showChannels();
|
||||
});
|
||||
}
|
||||
|
||||
function addChannel(form) {
|
||||
var uuid = false;
|
||||
|
||||
if (validateChannel(form)) {
|
||||
//if (uuid = addChannelBackend(form)) {
|
||||
if (addChannelController(form, randomUUID)) { //uuid)) {
|
||||
fetchChannels();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
//removeChannelBackend(uuid);
|
||||
alert('Error: adding channel to controller');
|
||||
}
|
||||
/*}
|
||||
else {
|
||||
alert('Error: adding channel to backend');
|
||||
}*/
|
||||
}
|
||||
else {
|
||||
alert('Please correct your input');
|
||||
}
|
||||
}
|
||||
|
||||
function addChannelController(form, uuid) {
|
||||
$.getJSON(controller, { operation: 'add', uuid: uuid, port: form.port.value, type: form.type.value }, function(data) {
|
||||
channels = data;
|
||||
showChannels();
|
||||
});
|
||||
|
||||
return true; // TODO
|
||||
}
|
||||
|
||||
function addChannelBackend(form) {
|
||||
$.getJSON(backend + '/channel.json', { operation: 'add' }, function(data) {
|
||||
|
||||
});
|
||||
|
||||
return true; // TODO
|
||||
}
|
||||
|
||||
function getDefinition(definition, type) {
|
||||
for (var i in definition) {
|
||||
if (definition[i].name == type) {
|
||||
return definition[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertyForm(property) {
|
||||
function getPropertyDOM(property) {
|
||||
switch (property.type) {
|
||||
case 'string':
|
||||
case 'float':
|
||||
|
|
|
@ -32,6 +32,13 @@
|
|||
* Initialize the WUI (Web User Interface)
|
||||
*/
|
||||
function initInterface() {
|
||||
/*$('#content').resizable({
|
||||
alsoResize: $('#plot'),
|
||||
//ghost: true,
|
||||
//animate: true,
|
||||
autoHide: true
|
||||
});*/
|
||||
|
||||
$('#accordion h3').click(function() {
|
||||
$(this).next().toggle('fast');
|
||||
return false;
|
||||
|
@ -54,13 +61,13 @@ function initInterface() {
|
|||
});
|
||||
|
||||
// bind controls
|
||||
$('#move input').click(panPlot);
|
||||
$('#move input').click(handleControl);
|
||||
|
||||
// options
|
||||
$('input[name=trendline]').attr('checked', vz.options.plot.seriesDefaults.trendline.show).change(function() {
|
||||
/*$('input[name=trendline]').attr('checked', vz.options.plot.seriesDefaults.trendline.show).change(function() {
|
||||
vz.options.plot.seriesDefaults.trendline.show = $(this).attr('checked');
|
||||
drawPlot();
|
||||
});
|
||||
});*/
|
||||
|
||||
$('input[name=backendUrl]').val(vz.options.backendUrl).change(function() {
|
||||
vz.options.backendUrl = $(this).val();
|
||||
|
@ -88,6 +95,9 @@ function initInterface() {
|
|||
*/
|
||||
function refreshWindow() {
|
||||
if ($('input[name=refresh]').attr('checked')) {
|
||||
var delta = vz.to - vz.from;
|
||||
vz.to = new Date().getTime(); // move plot
|
||||
vz.from = vz.to - delta; // move plot
|
||||
loadData();
|
||||
}
|
||||
}
|
||||
|
@ -95,12 +105,13 @@ function refreshWindow() {
|
|||
/**
|
||||
* Move & zoom in the plotting area
|
||||
*/
|
||||
function panPlot() {
|
||||
delta = vz.to - vz.from;
|
||||
function handleControl() {
|
||||
var delta = vz.to - vz.from;
|
||||
var middle = Math.round(vz.from + delta/2);
|
||||
|
||||
switch(this.value) {
|
||||
case 'move_last':
|
||||
vz.to = (new Date()).getTime();
|
||||
vz.to = new Date().getTime();
|
||||
vz.from = vz.to - delta;
|
||||
break;
|
||||
|
||||
|
@ -114,15 +125,18 @@ function panPlot() {
|
|||
break;
|
||||
|
||||
case 'zoom_reset':
|
||||
// TODO
|
||||
vz.from = middle - Math.floor(defaultInterval/2);
|
||||
vz.to = middle + Math.ceil(defaultInterval/2);
|
||||
break;
|
||||
|
||||
case 'zoom_in':
|
||||
// TODO
|
||||
vz.from += Math.floor(delta/4);
|
||||
vz.to -= Math.ceil(delta/4);
|
||||
break;
|
||||
|
||||
case 'zoom_out':
|
||||
// TODO
|
||||
vz.from -= delta;
|
||||
vz.to += delta;
|
||||
break;
|
||||
|
||||
case 'refresh':
|
||||
|
@ -146,12 +160,19 @@ function loadData() {
|
|||
}
|
||||
|
||||
function drawPlot() {
|
||||
vz.plot.axes.xaxis.min = vz.from;
|
||||
vz.plot.axes.xaxis.max = vz.to;
|
||||
|
||||
vz.plot.replot({
|
||||
resetAxes: 'yaxis',
|
||||
clear: true
|
||||
var data = new Array;
|
||||
eachRecursive(vz.entities, function(entity, parent) {
|
||||
if (entity.active && entity.type != 'group') {
|
||||
data.push({
|
||||
data: entity.data.tuples,
|
||||
color: entity.color
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
vz.options.plot.xaxis.min = vz.from;
|
||||
vz.options.plot.xaxis.max = vz.to;
|
||||
|
||||
vz.plot = $.plot($('#plot'), data, vz.options.plot);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// default time interval to show
|
||||
const defaultInterval = 7*24*60*60*1000; // 1 week
|
||||
|
||||
// volkszaehler.org object
|
||||
// holds all data and options for the frontend
|
||||
var vz = {
|
||||
|
@ -35,57 +38,45 @@ var vz = {
|
|||
// parameter for json server
|
||||
to: new Date().getTime(),
|
||||
|
||||
//parameter for json server (last 24 hours)
|
||||
from: new Date().getTime() - 24*60*60*1000,
|
||||
//parameter for json server (last week)
|
||||
from: new Date().getTime() - defaultInterval,
|
||||
|
||||
options: {
|
||||
backendUrl: '../backend/index.php',
|
||||
tuples: 300,
|
||||
plot: {
|
||||
series: [],
|
||||
seriesColors: ['#83CAFF', '#7E0021', '#579D1C', '#FFD320', '#FF420E', '#004586', '#0084D1', '#C5000B', '#FF950E', '#4B1F6F', '#AECF00', '#314004'],
|
||||
cursor: {
|
||||
zoom: true,
|
||||
showTooltip: true,
|
||||
constrainZoomTo: 'x',
|
||||
showVerticalLine: true
|
||||
},
|
||||
seriesDefaults: {
|
||||
lineWidth: 1,
|
||||
showMarker: true,
|
||||
showLine: false,
|
||||
markerOptions: {
|
||||
style: 'dash',
|
||||
shadow: false,
|
||||
size: 2
|
||||
},
|
||||
trendline: {
|
||||
colors: ['#83CAFF', '#7E0021', '#579D1C', '#FFD320', '#FF420E', '#004586', '#0084D1', '#C5000B', '#FF950E', '#4B1F6F', '#AECF00', '#314004'],
|
||||
series: {
|
||||
lines: { show: false },
|
||||
points: {
|
||||
show: true,
|
||||
shadow: false,
|
||||
color: 'red'
|
||||
}
|
||||
},
|
||||
axes: {
|
||||
yaxis: {
|
||||
autoscale: true,
|
||||
label: 'Leistung (Watt)',
|
||||
tickOptions: {
|
||||
formatString: '%.3f'
|
||||
},
|
||||
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
|
||||
},
|
||||
xaxis: {
|
||||
autoscale: true,
|
||||
tickOptions: {
|
||||
formatString: '%d.%m.%y %H:%M',
|
||||
angle: -35
|
||||
},
|
||||
pad: 1,
|
||||
renderer: $.jqplot.DateAxisRenderer,
|
||||
rendererOptions: {
|
||||
tickRenderer: $.jqplot.CanvasAxisTickRenderer
|
||||
radius: 1,
|
||||
//symbol: 'square'
|
||||
symbol: function(ctx, x, y, radius, shadow) {
|
||||
ctx.rect(x, y, radius, radius);
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: { show: false },
|
||||
xaxis: {
|
||||
mode: 'time',
|
||||
timeformat: '%d.%b %h:%M',
|
||||
monthNames: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
|
||||
},
|
||||
yaxis: {
|
||||
min: 0,
|
||||
zoomRange: [1, null] // dont scale yaxis when zooming
|
||||
},
|
||||
selection: { mode: "x" },
|
||||
//crosshair: { mode: "x" },
|
||||
grid: { hoverable: true, autoHighlight: false },
|
||||
zoom: {
|
||||
interactive: true,
|
||||
frameRate: null
|
||||
},
|
||||
pan: {
|
||||
interactive: false,
|
||||
frameRate: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,17 +99,34 @@ $(document).ready(function() {
|
|||
// start auto refresh timer
|
||||
window.setInterval(refreshWindow, 5000);
|
||||
|
||||
// initialize plot
|
||||
vz.plot = $.jqplot('plot', vz.options.plot);
|
||||
// handle zooming & panning
|
||||
var plot = $('#plot');
|
||||
plot
|
||||
.bind("plotselected", function (event, ranges) {
|
||||
vz.from = Math.floor(ranges.xaxis.from);
|
||||
vz.to = Math.ceil(ranges.xaxis.to);
|
||||
loadData();
|
||||
})
|
||||
/*.bind('plotpan', function (event, plot) {
|
||||
var axes = plot.getAxes();
|
||||
vz.from = Math.floor(axes.xaxis.min);
|
||||
vz.to = Math.ceil(axes.xaxis.max);
|
||||
vz.options.plot.yaxis.min = axes.yaxis.min;
|
||||
vz.options.plot.yaxis.max = axes.yaxis.max;
|
||||
})*/
|
||||
.bind('plotzoom', function (event, plot) {
|
||||
var axes = plot.getAxes();
|
||||
vz.from = Math.floor(axes.xaxis.min);
|
||||
vz.to = Math.ceil(axes.xaxis.max);
|
||||
//vz.options.plot.yaxis.min = axes.yaxis.min;
|
||||
//vz.options.plot.yaxis.max = axes.yaxis.max;
|
||||
vz.options.plot.yaxis.min = 0;
|
||||
vz.options.plot.yaxis.max = null; // autoscaling
|
||||
loadData();
|
||||
})
|
||||
.bind('mouseup', function(event) {
|
||||
loadData();
|
||||
});
|
||||
|
||||
// zoom events
|
||||
vz.plot.target.bind('jqplotZoom', function(event, gridpos, datapos, plot, cursor) {
|
||||
//alert('zoomed'); // TODO refresh of data
|
||||
});
|
||||
|
||||
vz.plot.target.bind('jqplotResetZoom', function(event, plot, cursor) {
|
||||
alert('zoom reset'); // TODO refresh of data
|
||||
});
|
||||
|
||||
loadEntities();
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ tbody tr td {
|
|||
}
|
||||
|
||||
#content {
|
||||
margin: 100px auto 20px;
|
||||
margin: 50px auto 20px;
|
||||
width: 800px;
|
||||
padding: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
|
@ -31,6 +31,11 @@ tbody tr td {
|
|||
border: 1px solid black;
|
||||
}
|
||||
|
||||
#plot {
|
||||
width: 800px;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
text-align: center;
|
||||
font-size: 0.7em;
|
||||
|
|
Loading…
Add table
Reference in a new issue