diff --git a/frontend/index.html b/frontend/index.html
index 009f70e..9c03afc 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -8,14 +8,12 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/frontend/javascripts/backend.js b/frontend/javascripts/backend.js
index f946e41..c618cb9 100644
--- a/frontend/javascripts/backend.js
+++ b/frontend/javascripts/backend.js
@@ -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(
$('
')
@@ -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('');
- }
- });
-
- // 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':
diff --git a/frontend/javascripts/frontend.js b/frontend/javascripts/frontend.js
index 06f06d2..3c57e66 100644
--- a/frontend/javascripts/frontend.js
+++ b/frontend/javascripts/frontend.js
@@ -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);
}
diff --git a/frontend/javascripts/init.js b/frontend/javascripts/init.js
index c40eb46..40913fd 100644
--- a/frontend/javascripts/init.js
+++ b/frontend/javascripts/init.js
@@ -25,6 +25,9 @@
* along with volkszaehler.org. If not, see .
*/
+// 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();
});
diff --git a/frontend/stylesheets/style.css b/frontend/stylesheets/style.css
index 16e5d38..defdb27 100644
--- a/frontend/stylesheets/style.css
+++ b/frontend/stylesheets/style.css
@@ -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;