chartingfrontend: some bugfixes, introducing multicharts / statusview
git-svn-id: https://svn.fhem.de/fhem/trunk@4630 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -3,6 +3,7 @@ DIR www/frontend/app/model
|
|||||||
DIR www/frontend/app/store
|
DIR www/frontend/app/store
|
||||||
DIR www/frontend/app/view
|
DIR www/frontend/app/view
|
||||||
DIR www/frontend/app/controller
|
DIR www/frontend/app/controller
|
||||||
|
DIR www/frontend/app/imagecache
|
||||||
DIR www/frontend/app/resources
|
DIR www/frontend/app/resources
|
||||||
DIR www/frontend/app/resources/icons
|
DIR www/frontend/app/resources/icons
|
||||||
DIR www/frontend/lib
|
DIR www/frontend/lib
|
||||||
@@ -28,7 +29,7 @@ DIR www/frontend/lib/ext-4.2.0.663/images/window
|
|||||||
DIR www/frontend/lib/ext-4.2.0.663/images/grid
|
DIR www/frontend/lib/ext-4.2.0.663/images/grid
|
||||||
DIR www/frontend/lib/ext-4.2.0.663/images/util
|
DIR www/frontend/lib/ext-4.2.0.663/images/util
|
||||||
DIR www/frontend/lib/ext-4.2.0.663/images/util/splitter
|
DIR www/frontend/lib/ext-4.2.0.663/images/util/splitter
|
||||||
UPD 2013-12-26_09:59:17 1054 www/frontend/index.html
|
UPD 2014-01-11_09:31:08 1170 www/frontend/index.html
|
||||||
UPD 2013-04-01_07:03:30 260475 www/frontend/lib/ext-4.2.0.663/ext-theme-gray-all.css
|
UPD 2013-04-01_07:03:30 260475 www/frontend/lib/ext-4.2.0.663/ext-theme-gray-all.css
|
||||||
UPD 2013-12-07_02:00:26 1497654 www/frontend/lib/ext-4.2.0.663/ext-all.js
|
UPD 2013-12-07_02:00:26 1497654 www/frontend/lib/ext-4.2.0.663/ext-all.js
|
||||||
UPD 2013-04-01_07:03:33 1981 www/frontend/lib/ext-4.2.0.663/images/tools/tools-sprites-trans.gif
|
UPD 2013-04-01_07:03:33 1981 www/frontend/lib/ext-4.2.0.663/images/tools/tools-sprites-trans.gif
|
||||||
@@ -272,14 +273,16 @@ UPD 2013-03-02_01:53:05 524 www/frontend/app/resources/icons/resultset_last.png
|
|||||||
UPD 2013-04-03_07:27:17 733 www/frontend/app/resources/icons/add.png
|
UPD 2013-04-03_07:27:17 733 www/frontend/app/resources/icons/add.png
|
||||||
UPD 2013-04-03_07:27:17 389 www/frontend/app/resources/icons/resultset_previous.png
|
UPD 2013-04-03_07:27:17 389 www/frontend/app/resources/icons/resultset_previous.png
|
||||||
UPD 2013-06-30_11:47:12 101 www/frontend/app/resources/application.css
|
UPD 2013-06-30_11:47:12 101 www/frontend/app/resources/application.css
|
||||||
UPD 2014-01-03_12:47:07 2714 www/frontend/app/app.js
|
UPD 2014-01-12_11:31:30 3028 www/frontend/app/app.js
|
||||||
UPD 2013-04-28_02:00:20 1205 www/frontend/app/view/ChartGridPanel.js
|
UPD 2013-04-28_02:00:20 1205 www/frontend/app/view/ChartGridPanel.js
|
||||||
UPD 2013-07-07_12:12:08 16201 www/frontend/app/view/DevicePanel.js
|
UPD 2013-07-07_12:12:08 16201 www/frontend/app/view/DevicePanel.js
|
||||||
UPD 2013-12-26_08:39:37 10257 www/frontend/app/view/TableDataGridPanel.js
|
UPD 2013-12-26_08:39:37 10257 www/frontend/app/view/TableDataGridPanel.js
|
||||||
UPD 2014-01-03_01:24:06 65039 www/frontend/app/view/LineChartPanel.js
|
UPD 2014-01-03_01:24:06 65039 www/frontend/app/view/LineChartPanel.js
|
||||||
UPD 2013-12-27_01:39:11 9980 www/frontend/app/view/Viewport.js
|
UPD 2014-01-12_12:09:17 5144 www/frontend/app/view/StatusPanel.js
|
||||||
UPD 2014-01-03_01:38:11 19171 www/frontend/app/controller/MainController.js
|
UPD 2014-01-12_12:55:22 10486 www/frontend/app/view/Viewport.js
|
||||||
UPD 2014-01-03_01:30:11 107834 www/frontend/app/controller/ChartController.js
|
UPD 2014-01-12_02:42:27 21844 www/frontend/app/controller/MainController.js
|
||||||
|
UPD 2014-01-12_02:49:58 16562 www/frontend/app/controller/StatusController.js
|
||||||
|
UPD 2014-01-12_02:51:54 109250 www/frontend/app/controller/ChartController.js
|
||||||
UPD 2013-06-30_11:46:54 5415 www/frontend/app/controller/TableDataController.js
|
UPD 2013-06-30_11:46:54 5415 www/frontend/app/controller/TableDataController.js
|
||||||
UPD 2013-04-01_07:04:35 202 www/frontend/app/model/ReadingsModel.js
|
UPD 2013-04-01_07:04:35 202 www/frontend/app/model/ReadingsModel.js
|
||||||
UPD 2013-04-01_07:04:36 338 www/frontend/app/model/SavedChartsModel.js
|
UPD 2013-04-01_07:04:36 338 www/frontend/app/model/SavedChartsModel.js
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Ext.application({
|
|||||||
],
|
],
|
||||||
|
|
||||||
controllers: [
|
controllers: [
|
||||||
|
'FHEM.controller.StatusController',
|
||||||
'FHEM.controller.MainController',
|
'FHEM.controller.MainController',
|
||||||
'FHEM.controller.ChartController',
|
'FHEM.controller.ChartController',
|
||||||
'FHEM.controller.TableDataController'
|
'FHEM.controller.TableDataController'
|
||||||
@@ -38,6 +39,12 @@ Ext.application({
|
|||||||
try {
|
try {
|
||||||
FHEM.info = Ext.decode(response.responseText);
|
FHEM.info = Ext.decode(response.responseText);
|
||||||
FHEM.version = FHEM.info.Results[0].devices[0].ATTR.version;
|
FHEM.version = FHEM.info.Results[0].devices[0].ATTR.version;
|
||||||
|
|
||||||
|
if (window.location.href.indexOf("frontenddev") > 0) {
|
||||||
|
FHEM.appPath = 'www/frontenddev/app/';
|
||||||
|
} else {
|
||||||
|
FHEM.appPath = 'www/frontend/app/';
|
||||||
|
}
|
||||||
Ext.each(FHEM.info.Results, function(result) {
|
Ext.each(FHEM.info.Results, function(result) {
|
||||||
if (result.list === "DbLog" && result.devices[0].NAME) {
|
if (result.list === "DbLog" && result.devices[0].NAME) {
|
||||||
FHEM.dblogname = result.devices[0].NAME;
|
FHEM.dblogname = result.devices[0].NAME;
|
||||||
|
|||||||
@@ -123,6 +123,12 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
},
|
},
|
||||||
'radiogroup[name=datasourceradio]': {
|
'radiogroup[name=datasourceradio]': {
|
||||||
change: this.dataSourceChanged
|
change: this.dataSourceChanged
|
||||||
|
},
|
||||||
|
'button[name=updatepreviewchart]': {
|
||||||
|
loadhiddenchart: this.loadsavedchart
|
||||||
|
},
|
||||||
|
'button[name=loadfullchart]': {
|
||||||
|
loadchart: this.loadsavedchart
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -291,7 +297,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
/**
|
/**
|
||||||
* Triggers a request to FHEM Module to get the data from Database
|
* Triggers a request to FHEM Module to get the data from Database
|
||||||
*/
|
*/
|
||||||
requestChartData: function(stepchangecalled) {
|
requestChartData: function(stepchangecalled, hidden) {
|
||||||
|
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
@@ -314,7 +320,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
dbendtime = Ext.Date.format(endtime, 'Y-m-d_H:i:s'),
|
dbendtime = Ext.Date.format(endtime, 'Y-m-d_H:i:s'),
|
||||||
dynamicradio = Ext.ComponentQuery.query('radiogroup[name=dynamictime]')[0],
|
dynamicradio = Ext.ComponentQuery.query('radiogroup[name=dynamictime]')[0],
|
||||||
chartpanel = me.getLinechartpanel(),
|
chartpanel = me.getLinechartpanel(),
|
||||||
chart = me.getChart();
|
hiddenchartdiv = Ext.get("hiddenchart");
|
||||||
|
|
||||||
//cleanup chartpanel
|
//cleanup chartpanel
|
||||||
var existingchartgrid = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0];
|
var existingchartgrid = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0];
|
||||||
@@ -334,9 +340,16 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
existingchart.destroy();
|
existingchart.destroy();
|
||||||
}
|
}
|
||||||
var store = Ext.create('FHEM.store.ChartStore'),
|
var store = Ext.create('FHEM.store.ChartStore'),
|
||||||
proxy = store.getProxy();
|
proxy = store.getProxy(),
|
||||||
|
chart;
|
||||||
|
|
||||||
|
|
||||||
|
if (hidden === true) {
|
||||||
|
chart = me.createChart(store, hiddenchartdiv);
|
||||||
|
} else {
|
||||||
chart = me.createChart(store);
|
chart = me.createChart(store);
|
||||||
chartpanel.add(chart);
|
chartpanel.add(chart);
|
||||||
|
}
|
||||||
|
|
||||||
//reset zoomValues
|
//reset zoomValues
|
||||||
chartpanel.setLastYmax(null);
|
chartpanel.setLastYmax(null);
|
||||||
@@ -455,14 +468,12 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
* resize the chart to fit the centerpanel
|
* resize the chart to fit the centerpanel
|
||||||
*/
|
*/
|
||||||
resizeChart: function() {
|
resizeChart: function() {
|
||||||
|
|
||||||
var lcp = Ext.ComponentQuery.query('linechartpanel')[0];
|
var lcp = Ext.ComponentQuery.query('linechartpanel')[0];
|
||||||
var lcv = Ext.ComponentQuery.query('chart')[0];
|
var lcv = Ext.ComponentQuery.query('chart')[0];
|
||||||
var cfp = Ext.ComponentQuery.query('form[name=chartformpanel]')[0];
|
var cfp = Ext.ComponentQuery.query('form[name=chartformpanel]')[0];
|
||||||
var cdg = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0];
|
var cdg = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0];
|
||||||
|
|
||||||
if (lcv) {
|
if (lcv) {
|
||||||
|
|
||||||
if (lcp && lcv && cfp && cdg) {
|
if (lcp && lcv && cfp && cdg) {
|
||||||
var lcph = lcp.getHeight(),
|
var lcph = lcp.getHeight(),
|
||||||
lcpw = lcp.getWidth(),
|
lcpw = lcp.getWidth(),
|
||||||
@@ -493,7 +504,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
/**
|
/**
|
||||||
* create the base chart
|
* create the base chart
|
||||||
*/
|
*/
|
||||||
createChart: function(store) {
|
createChart: function(store, hidden) {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
var chart = Ext.create('Ext.panel.Panel', {
|
var chart = Ext.create('Ext.panel.Panel', {
|
||||||
@@ -502,6 +513,9 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
collapsible: true,
|
collapsible: true,
|
||||||
titleCollapse: true,
|
titleCollapse: true,
|
||||||
animCollapse: false,
|
animCollapse: false,
|
||||||
|
width: hidden ? 1 : false,
|
||||||
|
height: hidden ? 1 : false,
|
||||||
|
renderTo: hidden ? hidden : false,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
xtype: 'toolbar',
|
xtype: 'toolbar',
|
||||||
@@ -531,6 +545,9 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
var chart = btn.up().up().down('chart'),
|
var chart = btn.up().up().down('chart'),
|
||||||
cp = chart.up().up();
|
cp = chart.up().up();
|
||||||
|
|
||||||
|
//only reset zoom when chart was really zoomed, else will break layout
|
||||||
|
if (cp.timesZoomed !== 0) {
|
||||||
|
|
||||||
chart.restoreZoom();
|
chart.restoreZoom();
|
||||||
|
|
||||||
chart.axes.get(0).minimum = cp.getLastYmin();
|
chart.axes.get(0).minimum = cp.getLastYmin();
|
||||||
@@ -559,18 +576,20 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
});
|
});
|
||||||
cp.artifactSeries = [];
|
cp.artifactSeries = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
chart.redraw();
|
chart.redraw();
|
||||||
// restore the counter as we have zoomed out
|
// restore the counter as we have zoomed out
|
||||||
cp.timesZoomed = 0;
|
cp.timesZoomed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
xtype: 'chart',
|
xtype: 'chart',
|
||||||
|
isPreviewChart: hidden ? true : false,
|
||||||
legend: {
|
legend: {
|
||||||
position: 'right',
|
position: 'right',
|
||||||
|
visible: hidden ? false : true,
|
||||||
labelFont: '10px Helvetica, sans-serif',
|
labelFont: '10px Helvetica, sans-serif',
|
||||||
padding: 4
|
padding: 4
|
||||||
},
|
},
|
||||||
@@ -605,35 +624,6 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
store: store,
|
store: store,
|
||||||
enableMask: true,
|
enableMask: true,
|
||||||
mask: true,//'vertical',//true, //'horizontal',
|
mask: true,//'vertical',//true, //'horizontal',
|
||||||
gradients: [{
|
|
||||||
id: 'gradientId',
|
|
||||||
angle: 90,
|
|
||||||
stops: {
|
|
||||||
0: {
|
|
||||||
color: '#FF0000'
|
|
||||||
},
|
|
||||||
50: {
|
|
||||||
color: '#FFFF00'
|
|
||||||
},
|
|
||||||
100: {
|
|
||||||
color: '#079400'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
id: 'gradientId2',
|
|
||||||
angle: 0,
|
|
||||||
stops: {
|
|
||||||
0: {
|
|
||||||
color: '#590'
|
|
||||||
},
|
|
||||||
20: {
|
|
||||||
color: '#599'
|
|
||||||
},
|
|
||||||
100: {
|
|
||||||
color: '#ddd'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
listeners: {
|
listeners: {
|
||||||
mousedown: function(evt) {
|
mousedown: function(evt) {
|
||||||
// fix for firefox, not dragging images
|
// fix for firefox, not dragging images
|
||||||
@@ -687,7 +677,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
*/
|
*/
|
||||||
createBaseLine: function(index, basestart, baseend, basefill, basecolor) {
|
createBaseLine: function(index, basestart, baseend, basefill, basecolor) {
|
||||||
var me = this,
|
var me = this,
|
||||||
chart = me.getChart(),
|
chart = Ext.ComponentQuery.query('chart')[0],
|
||||||
store = chart.getStore(),
|
store = chart.getStore(),
|
||||||
yfield = "VALUEBASE" + index;
|
yfield = "VALUEBASE" + index;
|
||||||
|
|
||||||
@@ -743,7 +733,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
populateAxis: function(i, axeslength, device, yaxis, yaxisindex, styleConfig, axisside, yaxisstatistics, dbstarttime, dbendtime, logtype) {
|
populateAxis: function(i, axeslength, device, yaxis, yaxisindex, styleConfig, axisside, yaxisstatistics, dbstarttime, dbendtime, logtype) {
|
||||||
|
|
||||||
var me = this,
|
var me = this,
|
||||||
chart = me.getChart(),
|
chart = Ext.ComponentQuery.query('chart')[0],
|
||||||
store = chart.getStore(),
|
store = chart.getStore(),
|
||||||
proxy = store.getProxy(),
|
proxy = store.getProxy(),
|
||||||
yseries,
|
yseries,
|
||||||
@@ -773,14 +763,42 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
// as the get command wont support absolute pathes by default...
|
// as the get command wont support absolute pathes by default...
|
||||||
currentlogfile = "../../../../../../../../" + currentlogfile;
|
currentlogfile = "../../../../../../../../" + currentlogfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the conversions keys and values from userconfig
|
||||||
|
var queryString;
|
||||||
|
if (Ext.isDefined(FHEM) && Ext.isDefined(FHEM.userconfig)) {
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
Ext.iterate(FHEM.userconfig.chartkeys, function(k, v) {
|
||||||
|
|
||||||
|
if (count === 0) {
|
||||||
|
queryString = '$fld[' + (yaxisindex - 1) + ']=~"' + k + '"?' + v + ':';
|
||||||
|
} else {
|
||||||
|
queryString += '($fld[' + (yaxisindex - 1) + ']=~"' + k + '"?' + v + ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
|
||||||
|
// last fallback, similar to parseint
|
||||||
|
queryString += '$fld[3]*1';
|
||||||
|
|
||||||
|
// add closing brackets
|
||||||
|
for (bracket = 1; bracket < count; bracket++) {
|
||||||
|
queryString += ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd = 'get Logfile ' +
|
cmd = 'get Logfile ' +
|
||||||
currentlogfile + ' - ' + dbstarttime +
|
currentlogfile + ' - ' + dbstarttime +
|
||||||
' ' + dbendtime + ' ' + yaxisindex + ':' + yaxis +
|
' ' + dbendtime + ' ' + yaxisindex + ':' + yaxis +
|
||||||
'\\x3a::$fld[' + (yaxisindex - 1) +
|
'\\x3a::' + queryString;
|
||||||
']=~"ok|on|open|active|true"?1:($fld[' +
|
|
||||||
(yaxisindex - 1) +
|
// '\\x3a::$fld[' + (yaxisindex - 1) +
|
||||||
']=~"low|off|closed|inactive|false"?0:$fld[' +
|
// ']=~"ok|on|open|active|true"?1:($fld[' +
|
||||||
(yaxisindex - 1) + ']*1)';
|
// (yaxisindex - 1) +
|
||||||
|
// ']=~"low|off|closed|inactive|false"?0:$fld[' +
|
||||||
|
// (yaxisindex - 1) + ']*1)';
|
||||||
} else if (!Ext.isDefined(yaxisstatistics) || yaxisstatistics === "none" || Ext.isEmpty(yaxisstatistics)) {
|
} else if (!Ext.isDefined(yaxisstatistics) || yaxisstatistics === "none" || Ext.isEmpty(yaxisstatistics)) {
|
||||||
cmd = 'get ' + FHEM.dblogname + ' - webchart ' + dbstarttime + ' ' + dbendtime + ' ';
|
cmd = 'get ' + FHEM.dblogname + ' - webchart ' + dbstarttime + ' ' + dbendtime + ' ';
|
||||||
cmd +=device + ' timerange ' + "TIMESTAMP" + ' ' + yaxis;
|
cmd +=device + ' timerange ' + "TIMESTAMP" + ' ' + yaxis;
|
||||||
@@ -993,7 +1011,6 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chart.series.add(yseries);
|
chart.series.add(yseries);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
failure: function() {
|
failure: function() {
|
||||||
@@ -1138,9 +1155,10 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
|
|
||||||
chart.axes.get(2).processView();
|
chart.axes.get(2).processView();
|
||||||
|
|
||||||
|
// only call resize function when not a hidden chart
|
||||||
|
if (chart.isPreviewChart === false) {
|
||||||
me.resizeChart();
|
me.resizeChart();
|
||||||
|
}
|
||||||
chart.show();
|
|
||||||
|
|
||||||
me.getLinechartpanel().setLoading(false);
|
me.getLinechartpanel().setLoading(false);
|
||||||
},
|
},
|
||||||
@@ -1151,7 +1169,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
createSeries: function(yfield, title, styleConfig, axisside) {
|
createSeries: function(yfield, title, styleConfig, axisside) {
|
||||||
|
|
||||||
//setting axistitle and fontsize
|
//setting axistitle and fontsize
|
||||||
var chart = this.getChart(),
|
var chart = Ext.ComponentQuery.query('chart')[0],
|
||||||
axis;
|
axis;
|
||||||
|
|
||||||
if (axisside === "left") {
|
if (axisside === "left") {
|
||||||
@@ -1188,6 +1206,19 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
//adding linked yfield to axis fields
|
//adding linked yfield to axis fields
|
||||||
axis.fields.push(yfield);
|
axis.fields.push(yfield);
|
||||||
|
|
||||||
|
chart.surface.addGradient({
|
||||||
|
id: 'gradientId',
|
||||||
|
angle: 90,
|
||||||
|
stops: {
|
||||||
|
10: {
|
||||||
|
color: '#FFFFFF'
|
||||||
|
},
|
||||||
|
100: {
|
||||||
|
color: '#' + styleConfig.fillcolorhexcode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var series = {
|
var series = {
|
||||||
type : 'line',
|
type : 'line',
|
||||||
axis : axisside,
|
axis : axisside,
|
||||||
@@ -1202,8 +1233,8 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
},
|
},
|
||||||
fill: (styleConfig.yaxisfillcheck === "false" || styleConfig.yaxisfillcheck === false) ? false : true,
|
fill: (styleConfig.yaxisfillcheck === "false" || styleConfig.yaxisfillcheck === false) ? false : true,
|
||||||
style: {
|
style: {
|
||||||
fill: '#' + styleConfig.fillcolorhexcode,
|
// fill: '#' + styleConfig.fillcolorhexcode,
|
||||||
// fill: 'url(#gradientId)',
|
fill: 'url(#gradientId)',
|
||||||
opacity: styleConfig.fillopacity,
|
opacity: styleConfig.fillopacity,
|
||||||
stroke: '#' + styleConfig.linecolorhexcode,
|
stroke: '#' + styleConfig.linecolorhexcode,
|
||||||
'stroke-width': styleConfig.linestrokewidth
|
'stroke-width': styleConfig.linestrokewidth
|
||||||
@@ -1249,7 +1280,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
*/
|
*/
|
||||||
generalizeChartData: function(generalizationfactor, index) {
|
generalizeChartData: function(generalizationfactor, index) {
|
||||||
|
|
||||||
var store = this.getChart().getStore();
|
var store = Ext.ComponentQuery.query('chart')[0].getStore();
|
||||||
|
|
||||||
this.factorpositive = 1 + (generalizationfactor / 100),
|
this.factorpositive = 1 + (generalizationfactor / 100),
|
||||||
this.factornegative = 1 - (generalizationfactor / 100),
|
this.factornegative = 1 - (generalizationfactor / 100),
|
||||||
@@ -1625,8 +1656,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
// preapre the string for the file
|
// preapre the string for the file
|
||||||
var finalstring = "FHEM.filelogcharts = " + Ext.encode(FHEM.filelogcharts) + ";;";
|
var finalstring = "FHEM.filelogcharts = " + Ext.encode(FHEM.filelogcharts) + ";;";
|
||||||
|
|
||||||
var cmd = "{ `echo '" + finalstring + "' > www/frontend/app/filelogcharts.js`}";
|
var cmd = "{ `echo '" + finalstring + "' > " + FHEM.appPath + "filelogcharts.js`}";
|
||||||
// var cmd = "{ `echo '" + finalstring + "' > www/frontenddev/app/filelogcharts.js`}";
|
|
||||||
|
|
||||||
Ext.Ajax.request({
|
Ext.Ajax.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -1669,7 +1699,8 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
/**
|
/**
|
||||||
* loading saved chart data and trigger the load of the chart
|
* loading saved chart data and trigger the load of the chart
|
||||||
*/
|
*/
|
||||||
loadsavedchart: function(treeview, record) {
|
loadsavedchart: function(treeview, record, hidden) {
|
||||||
|
|
||||||
if (!record.raw.data) {
|
if (!record.raw.data) {
|
||||||
record.raw.data = record.raw;
|
record.raw.data = record.raw;
|
||||||
}
|
}
|
||||||
@@ -1691,7 +1722,10 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
//cleanup the form before loading
|
//cleanup the form before loading
|
||||||
this.resetFormFields();
|
this.resetFormFields();
|
||||||
|
|
||||||
|
// no collapsing when hidden chart, will break the panel if done hidden
|
||||||
|
if (hidden !== true) {
|
||||||
this.getChartformpanel().collapse();
|
this.getChartformpanel().collapse();
|
||||||
|
}
|
||||||
|
|
||||||
if (chartdata && !Ext.isEmpty(chartdata)) {
|
if (chartdata && !Ext.isEmpty(chartdata)) {
|
||||||
|
|
||||||
@@ -1912,7 +1946,7 @@ Ext.define('FHEM.controller.ChartController', {
|
|||||||
me.getChartformpanel().down('textfield[name=leftaxistitle]').setValue(leftaxistitle);
|
me.getChartformpanel().down('textfield[name=leftaxistitle]').setValue(leftaxistitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.requestChartData();
|
this.requestChartData(false, hidden);
|
||||||
this.getLinechartpanel().setTitle(name);
|
this.getLinechartpanel().setTitle(name);
|
||||||
} else {
|
} else {
|
||||||
Ext.Msg.alert("Error", "The Chart could not be loaded! RawChartdata was: <br>" + chartdata);
|
Ext.Msg.alert("Error", "The Chart could not be loaded! RawChartdata was: <br>" + chartdata);
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
'panel[name=fhemaccordion]': {
|
'panel[name=fhemaccordion]': {
|
||||||
expand: this.showFHEMPanel
|
expand: this.showFHEMPanel
|
||||||
},
|
},
|
||||||
|
'panel[name=fhemstatusaccordion]': {
|
||||||
|
expand: this.showFHEMStatusPanel
|
||||||
|
},
|
||||||
'panel[name=tabledataaccordionpanel]': {
|
'panel[name=tabledataaccordionpanel]': {
|
||||||
expand: this.showDatabaseTablePanel
|
expand: this.showDatabaseTablePanel
|
||||||
},
|
},
|
||||||
@@ -68,6 +71,9 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
},
|
},
|
||||||
'button[name=sortedtree]': {
|
'button[name=sortedtree]': {
|
||||||
click: this.setupTree
|
click: this.setupTree
|
||||||
|
},
|
||||||
|
'panel[name=statuspanel]': {
|
||||||
|
saveconfig: this.saveObjectToUserConfig
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -84,6 +90,8 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
me.createLineChartPanel();
|
me.createLineChartPanel();
|
||||||
me.createDatabaseTablePanel();
|
me.createDatabaseTablePanel();
|
||||||
|
|
||||||
|
me.showFHEMStatusPanel();
|
||||||
|
|
||||||
me.getMainviewport().show();
|
me.getMainviewport().show();
|
||||||
me.getMainviewport().getEl().setOpacity(0);
|
me.getMainviewport().getEl().setOpacity(0);
|
||||||
me.getMainviewport().getEl().animate({
|
me.getMainviewport().getEl().animate({
|
||||||
@@ -95,7 +103,7 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
|
|
||||||
if (Ext.isDefined(FHEM.version)) {
|
if (Ext.isDefined(FHEM.version)) {
|
||||||
var sp = this.getStatustextfield();
|
var sp = this.getStatustextfield();
|
||||||
sp.setText(FHEM.version + "; Frontend Version: 1.0.7 - 2014-01-03");
|
sp.setText(FHEM.version + "; Frontend Version: 1.0.8 - 2014-01-12");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setupTree(false);
|
this.setupTree(false);
|
||||||
@@ -192,8 +200,10 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
//add the charts to the tree
|
//add the charts to the tree
|
||||||
store.on("load", function() {
|
store.on("load", function() {
|
||||||
var rootNode = me.getMaintreepanel().getRootNode(),
|
var rootNode = me.getMaintreepanel().getRootNode(),
|
||||||
chartfolder = {text: "Charts", expanded: true, children: []};
|
chartfolder = {text: "Charts", expanded: true, children: []},
|
||||||
|
statusfolder = {text: "StatusRoom", expanded: true, children: []};
|
||||||
rootNode.appendChild(chartfolder);
|
rootNode.appendChild(chartfolder);
|
||||||
|
rootNode.appendChild(statusfolder);
|
||||||
var chartfoldernode = rootNode.findChild("text", "Charts", true);
|
var chartfoldernode = rootNode.findChild("text", "Charts", true);
|
||||||
|
|
||||||
//add the filelogcharts to the store
|
//add the filelogcharts to the store
|
||||||
@@ -226,6 +236,7 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
chartchild = {text: 'Create new Chart', leaf: true, data: {template: true}, iconCls:'x-tree-icon-leaf-chart'};
|
chartchild = {text: 'Create new Chart', leaf: true, data: {template: true}, iconCls:'x-tree-icon-leaf-chart'};
|
||||||
chartfoldernode.appendChild(chartchild);
|
chartfoldernode.appendChild(chartchild);
|
||||||
|
|
||||||
|
me.getMaintreepanel().fireEvent('treeloaded');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -455,6 +466,15 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
showFHEMStatusPanel: function() {
|
||||||
|
var panel = Ext.ComponentQuery.query('statuspanel')[0];
|
||||||
|
this.hideCenterPanels();
|
||||||
|
panel.show();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -572,6 +592,54 @@ Ext.define('FHEM.controller.MainController', {
|
|||||||
var panel = Ext.ComponentQuery.query('tabledatagridpanel')[0];
|
var panel = Ext.ComponentQuery.query('tabledatagridpanel')[0];
|
||||||
this.hideCenterPanels();
|
this.hideCenterPanels();
|
||||||
panel.show();
|
panel.show();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method appending and saving a given object to the file userconfig.js, which is loaded on page load
|
||||||
|
* The location names the accesible part where the object should be saved in
|
||||||
|
*/
|
||||||
|
saveObjectToUserConfig: function(objectToSave, location) {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (FHEM.userconfig && objectToSave && !Ext.isEmpty(location)) {
|
||||||
|
|
||||||
|
FHEM.userconfig[location] = objectToSave;
|
||||||
|
|
||||||
|
// preapre the string for the file
|
||||||
|
var finalstring = "FHEM = {};;FHEM.userconfig = " + Ext.encode(FHEM.userconfig) + ";;";
|
||||||
|
|
||||||
|
var cmd = "{ `echo '" + finalstring + "' > " + FHEM.appPath + "userconfig.js`}";
|
||||||
|
|
||||||
|
Ext.Ajax.request({
|
||||||
|
method: 'POST',
|
||||||
|
disableCaching: false,
|
||||||
|
url: '../../../fhem?',
|
||||||
|
params: {
|
||||||
|
cmd: cmd,
|
||||||
|
XHR: 1
|
||||||
|
},
|
||||||
|
success: function(response){
|
||||||
|
if (response.status === 200) {
|
||||||
|
Ext.Msg.alert("Success", "Changes successfully saved!");
|
||||||
|
} else if (response.statusText) {
|
||||||
|
Ext.Msg.alert("Error", "The Changes could not be saved, error Message is:<br><br>" + response.statusText);
|
||||||
|
} else {
|
||||||
|
Ext.Msg.alert("Error", "The Changes could not be saved!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
failure: function(response) {
|
||||||
|
if (response.statusText) {
|
||||||
|
Ext.Msg.alert("Error", "The Changes could not be saved, error Message is:<br><br>" + response.statusText);
|
||||||
|
} else {
|
||||||
|
Ext.Msg.alert("Error", "The Changes could not be saved!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Ext.Msg.alert("Error", "A save attempt was made without enough parameters!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
});
|
});
|
||||||
@@ -0,0 +1,454 @@
|
|||||||
|
/**
|
||||||
|
* The Controller handling Status Panel
|
||||||
|
*/
|
||||||
|
Ext.define('FHEM.controller.StatusController', {
|
||||||
|
extend: 'Ext.app.Controller',
|
||||||
|
requires: [
|
||||||
|
'FHEM.view.StatusPanel'
|
||||||
|
],
|
||||||
|
|
||||||
|
refs: [
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean indicating when the charts tree is loaded
|
||||||
|
*/
|
||||||
|
treeloaded: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean indicating when the statuspanel is rendered
|
||||||
|
*/
|
||||||
|
statuspanelrendered: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean indicating that we are currently updating a preview chart
|
||||||
|
*/
|
||||||
|
updateRunning: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean indicating that we are currently updating via global autoupdater
|
||||||
|
*/
|
||||||
|
autoUpdateRunning: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init function to register listeners
|
||||||
|
*/
|
||||||
|
init: function() {
|
||||||
|
this.control({
|
||||||
|
'button[name=updatepreviewchart]': {
|
||||||
|
click: this.updatePreviewChart
|
||||||
|
},
|
||||||
|
'button[name=loadfullchart]': {
|
||||||
|
click: this.loadFullChart
|
||||||
|
},
|
||||||
|
'panel[name=statuspanel]': {
|
||||||
|
afterrender: function() {
|
||||||
|
this.statuspanelrendered = true;
|
||||||
|
this.setupPanelsFromTreeContent();
|
||||||
|
},
|
||||||
|
show: this.setupGlobalUpdateTask,
|
||||||
|
hide: function() {
|
||||||
|
Ext.each(Ext.TaskManager.tasks, function(task) {
|
||||||
|
if (task.name === 'countdowntask') {
|
||||||
|
Ext.TaskManager.stop(task);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'panel[name=maintreepanel]': {
|
||||||
|
treeloaded: function() {
|
||||||
|
this.treeloaded = true;
|
||||||
|
this.setupPanelsFromTreeContent();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'button[name=applypreviewchartsize]': {
|
||||||
|
click: function() {
|
||||||
|
this.destroyAllPreviewPanels();
|
||||||
|
this.setupPanelsFromTreeContent();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'button[name=reloadallpreviews]': {
|
||||||
|
click: this.triggerUpdateForAllPreviews
|
||||||
|
},
|
||||||
|
'treeview': {
|
||||||
|
drop: function() {
|
||||||
|
this.destroyAllPreviewPanels();
|
||||||
|
this.setupPanelsFromTreeContent();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'button[name=savepreviewchartsconfig]': {
|
||||||
|
click: function() {
|
||||||
|
|
||||||
|
var panel = Ext.ComponentQuery.query('panel[name=statuspanel]')[0],
|
||||||
|
location = 'previewchartsconfig',
|
||||||
|
objectToSave = {};
|
||||||
|
|
||||||
|
objectToSave.width = Ext.ComponentQuery.query('numberfield[name=previewchartwidth]')[0].getValue();
|
||||||
|
objectToSave.height = Ext.ComponentQuery.query('numberfield[name=previewchartheight]')[0].getValue();
|
||||||
|
objectToSave.autoUpdate = Ext.ComponentQuery.query('checkbox[name=autoupdatecheckbox]')[0].getValue();
|
||||||
|
objectToSave.updateInterval = Ext.ComponentQuery.query('numberfield[name=updateinterval]')[0].getValue();
|
||||||
|
|
||||||
|
// delegate to maincontroller
|
||||||
|
panel.fireEvent("saveconfig", objectToSave, location);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'checkbox[name=autoupdatecheckbox]': {
|
||||||
|
change: this.setupGlobalUpdateTask
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setupGlobalUpdateTask: function() {
|
||||||
|
|
||||||
|
var me = this,
|
||||||
|
autoUpdate = Ext.ComponentQuery.query('checkbox[name=autoupdatecheckbox]')[0].getValue(),
|
||||||
|
updateInterval = Ext.ComponentQuery.query('numberfield[name=updateinterval]')[0].getValue(),
|
||||||
|
txt = Ext.ComponentQuery.query('text[name=countdowntext]')[0];
|
||||||
|
|
||||||
|
if (autoUpdate === true && !Ext.isEmpty(updateInterval)) {
|
||||||
|
|
||||||
|
txt.setDisabled(false);
|
||||||
|
|
||||||
|
// stop all old tasks
|
||||||
|
Ext.each(Ext.TaskManager.tasks, function(task) {
|
||||||
|
if (task.name === 'countdowntask') {
|
||||||
|
Ext.TaskManager.stop(task);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// start the countdown
|
||||||
|
Ext.ComponentQuery.query('text[name=countdowntext]')[0].counter = updateInterval;
|
||||||
|
var countdownTask = Ext.TaskManager.start({
|
||||||
|
run: function() {
|
||||||
|
var txt = Ext.ComponentQuery.query('text[name=countdowntext]')[0];
|
||||||
|
if (txt.counter > 0) {
|
||||||
|
txt.setText('Next Update in ' + (txt.counter - 1) + 's');
|
||||||
|
txt.counter--;
|
||||||
|
} else if (txt.counter === 0 && !me.autoUpdateRunning){
|
||||||
|
me.autoUpdateRunning = true;
|
||||||
|
me.triggerUpdateForAllPreviews();
|
||||||
|
txt.setText('Updating...');
|
||||||
|
txt.counter--;
|
||||||
|
} else if (!me.autoUpdateRunning){
|
||||||
|
var currentInterval = Ext.ComponentQuery.query('numberfield[name=updateinterval]')[0].getValue();
|
||||||
|
txt.setText('Next Update in ' + currentInterval + 's');
|
||||||
|
txt.counter = currentInterval;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'countdowntask',
|
||||||
|
interval: 900
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Ext.each(Ext.TaskManager.tasks, function(task) {
|
||||||
|
if (task.name === 'countdowntask') {
|
||||||
|
Ext.TaskManager.stop(task);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
txt.setText('Update disabled');
|
||||||
|
txt.setDisabled(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
createPreviewChartPanel: function(record) {
|
||||||
|
var me = this,
|
||||||
|
desiredWidth = Ext.ComponentQuery.query('numberfield[name=previewchartwidth]')[0].getValue(),
|
||||||
|
desiredHeight = Ext.ComponentQuery.query('numberfield[name=previewchartheight]')[0].getValue(),
|
||||||
|
savename;
|
||||||
|
|
||||||
|
if (record.raw.ID) {
|
||||||
|
savename = record.raw.ID + '.svg';
|
||||||
|
} else {
|
||||||
|
savename = record.raw.data.ID + '.svg';
|
||||||
|
}
|
||||||
|
var previewchartcontainer = Ext.ComponentQuery.query('panel[name=previewchartcontainer]')[0],
|
||||||
|
previewpanel = Ext.create('Ext.panel.Panel', {
|
||||||
|
width: desiredWidth,
|
||||||
|
height: desiredHeight,
|
||||||
|
title: record.raw.text ? record.raw.text : 'No title found...',
|
||||||
|
record: record,
|
||||||
|
name: 'chartpreviewpanel',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'toolbar',
|
||||||
|
ui: 'footer',
|
||||||
|
enableOverflow: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'text',
|
||||||
|
name: 'lastupdatedtext',
|
||||||
|
text: "Last Updated: not yet"
|
||||||
|
},
|
||||||
|
'->',
|
||||||
|
{
|
||||||
|
text: 'Open Full Chart',
|
||||||
|
name: 'loadfullchart'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Reload',
|
||||||
|
name: 'updatepreviewchart'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'image',
|
||||||
|
layout: 'fit',
|
||||||
|
// add date to path to avoid cached images from browser
|
||||||
|
src: 'app/imagecache/' + savename + '?_' + new Date(),
|
||||||
|
width: desiredWidth,
|
||||||
|
height: desiredHeight - 53
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
previewchartcontainer.add(previewpanel);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
loadFullChart: function(btn) {
|
||||||
|
var rec = btn.up('panel[name=chartpreviewpanel]').record;
|
||||||
|
|
||||||
|
var centerpanels = Ext.ComponentQuery.query('panel[region=center]');
|
||||||
|
Ext.each(centerpanels, function(panel) {
|
||||||
|
panel.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
Ext.ComponentQuery.query('linechartpanel')[0].show();
|
||||||
|
Ext.ComponentQuery.query('treepanel')[0].expand();
|
||||||
|
|
||||||
|
btn.fireEvent('loadchart', null, rec, false);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
destroyAllPreviewPanels: function() {
|
||||||
|
Ext.ComponentQuery.query('panel[name=previewchartcontainer]')[0].removeAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setupPanelsFromTreeContent: function() {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
if (me.statuspanelrendered && me.treeloaded) {
|
||||||
|
var root = Ext.ComponentQuery.query('treepanel')[0].getRootNode(),
|
||||||
|
statusfoldernode = root.findChild("text", "StatusRoom", true);
|
||||||
|
|
||||||
|
if (statusfoldernode.childNodes.length > 0) {
|
||||||
|
Ext.ComponentQuery.query('panel[name=previewchartcontainer]')[0].update('');
|
||||||
|
} else {
|
||||||
|
Ext.ComponentQuery.query('panel[name=previewchartcontainer]')[0].update(
|
||||||
|
'This panel gives you an overview of your Charts by displaying them as small windows here.<br>' +
|
||||||
|
'To add Charts to this Overview, simply drop some into the folder "StatusRoom" which you<br>' +
|
||||||
|
'can find in the tree on the left side.<br>' +
|
||||||
|
'Add as much charts as you want, configure their size and update options and save your<br>' +
|
||||||
|
'settings by clicking on "Save configuration".<br>' +
|
||||||
|
'The first time you add a new chart you need to reload it, before you can see it!');
|
||||||
|
}
|
||||||
|
|
||||||
|
Ext.each(statusfoldernode.childNodes, function(node) {
|
||||||
|
me.createPreviewChartPanel(node);
|
||||||
|
});
|
||||||
|
|
||||||
|
//initialize auto update
|
||||||
|
me.setupGlobalUpdateTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
updatePreviewChart: function(btn, panel) {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
if (panel && panel.down) {
|
||||||
|
btn = panel.down('button[name=updatepreviewchart]');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me.updateRunning === true) {
|
||||||
|
window.setTimeout(function() {
|
||||||
|
me.updatePreviewChart(btn);
|
||||||
|
}, 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
me.updateRunning = true;
|
||||||
|
|
||||||
|
// destroy all old charts
|
||||||
|
me.destroyAllCharts();
|
||||||
|
|
||||||
|
var imgcontainer = btn.up('panel').down('image');
|
||||||
|
imgcontainer.setLoading(true);
|
||||||
|
|
||||||
|
// get record from panel
|
||||||
|
var record = btn.up('panel').record;
|
||||||
|
// event will get caught in chartcontroller
|
||||||
|
btn.fireEvent('loadhiddenchart', null, record, true);
|
||||||
|
|
||||||
|
// now we wait till the chart is rendered
|
||||||
|
var task = Ext.TaskManager.start({
|
||||||
|
run: function() {
|
||||||
|
me.checkForRenderedChart(imgcontainer, task);
|
||||||
|
},
|
||||||
|
name: 'hiddenchart',
|
||||||
|
interval: 500
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
triggerUpdateForAllPreviews: function() {
|
||||||
|
var me = this,
|
||||||
|
allPanels = Ext.ComponentQuery.query('panel[name=chartpreviewpanel]');
|
||||||
|
|
||||||
|
Ext.each(allPanels, function(panel) {
|
||||||
|
me.updatePreviewChart(false, panel);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method destroys all rendered charts
|
||||||
|
*/
|
||||||
|
destroyAllCharts: function() {
|
||||||
|
var charts = Ext.ComponentQuery.query('chart');
|
||||||
|
Ext.each(charts, function(chart) {
|
||||||
|
chart.destroy();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
checkForRenderedChart: function(imgcontainer, task){
|
||||||
|
var me = this,
|
||||||
|
desiredWidth = Ext.ComponentQuery.query('numberfield[name=previewchartwidth]')[0].getValue(),
|
||||||
|
desiredHeight = Ext.ComponentQuery.query('numberfield[name=previewchartheight]')[0].getValue();
|
||||||
|
|
||||||
|
var chart = Ext.ComponentQuery.query('chart')[0];
|
||||||
|
if (chart && chart.surface && chart.surface.el && chart.surface.el.dom) {
|
||||||
|
chart.setHeight(desiredHeight - 53); // removing the panels title and toolbar from height
|
||||||
|
chart.setWidth(desiredWidth);
|
||||||
|
data = chart.surface.el.dom;
|
||||||
|
// we need to cleanup the "ext"-invisible items because they will get rendered
|
||||||
|
textArray = data.getElementsByTagName("text");
|
||||||
|
Ext.each(textArray, function(text) {
|
||||||
|
if (text.getAttribute("class") && text.getAttribute("class").indexOf("x-hide-visibility") >= 0 ) {
|
||||||
|
text.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var serializer = new XMLSerializer(),
|
||||||
|
svgstring = serializer.serializeToString(data),
|
||||||
|
canvas = document.getElementById("canvas"),
|
||||||
|
ctx = canvas.getContext("2d"),
|
||||||
|
DOMURL = self.URL || self.webkitURL || self,
|
||||||
|
img = new Image(),
|
||||||
|
svg = new Blob([svgstring], {type: "image/svg+xml;charset=utf-8"}),
|
||||||
|
url = DOMURL.createObjectURL(svg);
|
||||||
|
|
||||||
|
img.onload = function() {
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
DOMURL.revokeObjectURL(url);
|
||||||
|
};
|
||||||
|
img.src = url;
|
||||||
|
imgcontainer.setSrc(img.src);
|
||||||
|
imgcontainer.setLoading(false);
|
||||||
|
|
||||||
|
Ext.TaskManager.stop(task);
|
||||||
|
me.destroyAllCharts();
|
||||||
|
|
||||||
|
var rec = imgcontainer.up('panel').record;
|
||||||
|
imgcontainer.up('panel').down('text[name=lastupdatedtext]').setText(Ext.Date.format(new Date(), 'Y-m-d H:i:s'));
|
||||||
|
|
||||||
|
me.saveImageToDisk(svgstring, rec);
|
||||||
|
me.updateRunning = false;
|
||||||
|
|
||||||
|
// check if an autoupdate has completed
|
||||||
|
var sp = imgcontainer.up('panel[name=previewchartcontainer]');
|
||||||
|
if (me.autoUpdateRunning && imgcontainer.up('panel').title === sp.items.items[sp.items.items.length - 1].title) {
|
||||||
|
me.autoUpdateRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
saveImageToDisk: function(svgstring, rec) {
|
||||||
|
|
||||||
|
var savename;
|
||||||
|
|
||||||
|
if (rec.raw.ID) {
|
||||||
|
savename = rec.raw.ID + '.svg';
|
||||||
|
} else {
|
||||||
|
savename = rec.raw.data.ID + '.svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
//fhem specific fixes ...
|
||||||
|
svgstring = svgstring.replace(/;/g, ";;");
|
||||||
|
svgstring = svgstring.replace(/\#/g, "\\x23");
|
||||||
|
|
||||||
|
var svgArr = [],
|
||||||
|
lastMax = 0;
|
||||||
|
|
||||||
|
// we split up the string in onehundredthousands-packages, so fhem will accept those posts...
|
||||||
|
while (svgstring.length > lastMax) {
|
||||||
|
svgArr.push(svgstring.slice(lastMax, lastMax + 100000));
|
||||||
|
lastMax = lastMax + 100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0,
|
||||||
|
cmd;
|
||||||
|
Ext.each(svgArr, function(part) {
|
||||||
|
if (i === 0) {
|
||||||
|
cmd = "{ `echo '" + part + "' > " + FHEM.appPath + "imagecache/" + savename + "`}";
|
||||||
|
} else {
|
||||||
|
cmd = "{ `echo -n '" + part + "' >> " + FHEM.appPath + "imagecache/" + savename + "`}";
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
Ext.Ajax.request({
|
||||||
|
method: 'POST',
|
||||||
|
disableCaching: false,
|
||||||
|
async: false,
|
||||||
|
url: '../../../fhem?',
|
||||||
|
params: {
|
||||||
|
cmd: cmd,
|
||||||
|
XHR: 1
|
||||||
|
},
|
||||||
|
success: function(response){
|
||||||
|
if (response.status === 200) {
|
||||||
|
// no feedback
|
||||||
|
} else if (response.statusText) {
|
||||||
|
Ext.Msg.alert("Error", "The Chart-Image could not be saved, error Message is:<br><br>" + response.statusText);
|
||||||
|
} else {
|
||||||
|
Ext.Msg.alert("Error", "The Chart-Image could not be saved!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
failure: function(response) {
|
||||||
|
if (response.statusText) {
|
||||||
|
Ext.Msg.alert("Error", "The Chart-Image could not be saved, error Message is:<br><br>" + response.statusText);
|
||||||
|
} else {
|
||||||
|
Ext.Msg.alert("Error", "The Chart-Image could not be saved!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
123
fhem/www/frontend/www/frontend/app/view/StatusPanel.js
Normal file
123
fhem/www/frontend/www/frontend/app/view/StatusPanel.js
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* A Panel containing FHEM status information
|
||||||
|
*/
|
||||||
|
Ext.define('FHEM.view.StatusPanel', {
|
||||||
|
extend: 'Ext.panel.Panel',
|
||||||
|
alias : 'widget.statuspanel',
|
||||||
|
name: 'statuspanel',
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
title: 'FHEM Status',
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
region: 'center',
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
autoScroll: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init function
|
||||||
|
*/
|
||||||
|
initComponent: function() {
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
|
||||||
|
me.items = [
|
||||||
|
{
|
||||||
|
xtype: 'toolbar',
|
||||||
|
ui: 'footer',
|
||||||
|
enableOverflow: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
xtype: 'numberfield',
|
||||||
|
fieldLabel: "Width",
|
||||||
|
labelWidth: 30,
|
||||||
|
width: 120,
|
||||||
|
padding: '0 20px 0 5px',
|
||||||
|
name: 'previewchartwidth',
|
||||||
|
value: (FHEM.userconfig.previewchartsconfig &&
|
||||||
|
FHEM.userconfig.previewchartsconfig.width) ?
|
||||||
|
FHEM.userconfig.previewchartsconfig.width : 459
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'numberfield',
|
||||||
|
fieldLabel: "Height",
|
||||||
|
labelWidth: 30,
|
||||||
|
width: 120,
|
||||||
|
padding: '0 20px 0 5px',
|
||||||
|
name: 'previewchartheight',
|
||||||
|
value: (FHEM.userconfig.previewchartsconfig &&
|
||||||
|
FHEM.userconfig.previewchartsconfig.height) ?
|
||||||
|
FHEM.userconfig.previewchartsconfig.height : 280
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Apply Size',
|
||||||
|
name: 'applypreviewchartsize'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'tbseparator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'checkbox',
|
||||||
|
fieldLabel: "Auto Update?",
|
||||||
|
labelWidth: 70,
|
||||||
|
name: 'autoupdatecheckbox',
|
||||||
|
checked: (FHEM.userconfig.previewchartsconfig &&
|
||||||
|
FHEM.userconfig.previewchartsconfig.autoUpdate === false) ?
|
||||||
|
false : true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'numberfield',
|
||||||
|
fieldLabel: "Update Interval",
|
||||||
|
labelWidth: 80,
|
||||||
|
name: 'updateinterval',
|
||||||
|
width: 150,
|
||||||
|
minValue: 60,
|
||||||
|
editable: false,
|
||||||
|
value: (FHEM.userconfig.previewchartsconfig &&
|
||||||
|
FHEM.userconfig.previewchartsconfig.updateInterval) ?
|
||||||
|
FHEM.userconfig.previewchartsconfig.updateInterval : 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'text',
|
||||||
|
name: 'countdowntext',
|
||||||
|
width: 100,
|
||||||
|
counter: (FHEM.userconfig.previewchartsconfig &&
|
||||||
|
FHEM.userconfig.previewchartsconfig.updateInterval) ?
|
||||||
|
FHEM.userconfig.previewchartsconfig.updateInterval - 2 : 118,
|
||||||
|
text: 'Updates disabled',
|
||||||
|
disabled: (FHEM.userconfig.previewchartsconfig &&
|
||||||
|
FHEM.userconfig.previewchartsconfig.autoUpdate === false) ?
|
||||||
|
true : false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Reload all now!',
|
||||||
|
name: 'reloadallpreviews',
|
||||||
|
cls:'x-btn-default-small'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Save configuration',
|
||||||
|
name: 'savepreviewchartsconfig'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xtype: 'panel',
|
||||||
|
name: 'previewchartcontainer',
|
||||||
|
layout: 'column',
|
||||||
|
html: 'This panel gives you an overview of your Charts by displaying them as small windows here.<br>' +
|
||||||
|
'To add Charts to this Overview, simply drop some into the folder "StatusRoom" which you<br>' +
|
||||||
|
'can find in the tree on the left side.<br>' +
|
||||||
|
'Add as much charts as you want, configure their size and update options and save your<br>' +
|
||||||
|
'settings by clicking on "Save configuration".<br>' +
|
||||||
|
'The first time you add a new chart you need to reload it, before you can see it!'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
me.callParent(arguments);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -9,6 +9,7 @@ Ext.define('FHEM.view.Viewport', {
|
|||||||
requires: [
|
requires: [
|
||||||
'FHEM.view.LineChartPanel',
|
'FHEM.view.LineChartPanel',
|
||||||
'FHEM.view.TableDataGridPanel',
|
'FHEM.view.TableDataGridPanel',
|
||||||
|
'FHEM.view.StatusPanel',
|
||||||
'FHEM.controller.ChartController',
|
'FHEM.controller.ChartController',
|
||||||
'FHEM.store.SavedChartsStore',
|
'FHEM.store.SavedChartsStore',
|
||||||
'Ext.layout.container.Border',
|
'Ext.layout.container.Border',
|
||||||
@@ -107,6 +108,13 @@ Ext.define('FHEM.view.Viewport', {
|
|||||||
type: 'accordion'
|
type: 'accordion'
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
|
{
|
||||||
|
title: 'FHEM Status',
|
||||||
|
name: 'fhemstatusaccordion',
|
||||||
|
expanded: true,
|
||||||
|
bodyPadding: '5 5 5 5',
|
||||||
|
html: 'See your current FHEM Status / Overview Information here.'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'FHEM',
|
title: 'FHEM',
|
||||||
name: 'fhemaccordion',
|
name: 'fhemaccordion',
|
||||||
@@ -198,28 +206,31 @@ Ext.define('FHEM.view.Viewport', {
|
|||||||
minHeight: 30
|
minHeight: 30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
region: 'center',
|
xtype: 'statuspanel'
|
||||||
title: 'Welcome',
|
|
||||||
layout: 'hbox',
|
|
||||||
bodyStyle: 'padding:5px 5px 0',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
xtype: 'image',
|
|
||||||
src: '../../fhem/images/default/fhemicon.png',
|
|
||||||
height: 132,
|
|
||||||
width: 120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
xtype: 'text',
|
|
||||||
name: 'statustextfield',
|
|
||||||
padding: '50 0 0 20',
|
|
||||||
width: 400,
|
|
||||||
height: 130,
|
|
||||||
html: '<br>Welcome to the new FHEM Frontend.<br>For Informations, Problems and discussion, visit the <a href="http://forum.fhem.de/index.php?t=msg&th=10439&start=0&rid=0">FHEM Forums</a>'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
height: '100%'
|
|
||||||
}
|
}
|
||||||
|
// {
|
||||||
|
// region: 'center',
|
||||||
|
// title: 'Welcome',
|
||||||
|
// layout: 'hbox',
|
||||||
|
// bodyStyle: 'padding:5px 5px 0',
|
||||||
|
// items: [
|
||||||
|
// {
|
||||||
|
// xtype: 'image',
|
||||||
|
// src: '../../fhem/images/default/fhemicon.png',
|
||||||
|
// height: 132,
|
||||||
|
// width: 120
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// xtype: 'text',
|
||||||
|
// name: 'statustextfield',
|
||||||
|
// padding: '50 0 0 20',
|
||||||
|
// width: 400,
|
||||||
|
// height: 130,
|
||||||
|
// html: '<br>Welcome to the new FHEM Frontend.<br>For Informations, Problems and discussion, visit the <a href="http://forum.fhem.de/index.php?t=msg&th=10439&start=0&rid=0">FHEM Forums</a>'
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// height: '100%'
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,5 +28,7 @@
|
|||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div id=hiddenchart width=1 height=1"></div>
|
||||||
|
<canvas id=canvas width=200 height=200></canvas>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user