diff --git a/www/frontend/controls_frontend.txt b/www/frontend/controls_frontend.txt index b8ed91528..2d9ad41db 100644 --- a/www/frontend/controls_frontend.txt +++ b/www/frontend/controls_frontend.txt @@ -273,16 +273,17 @@ 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 389 www/frontend/app/resources/icons/resultset_previous.png UPD 2013-06-30_11:47:12 101 www/frontend/app/resources/application.css -UPD 2014-11-08_12:33:44 2976 www/frontend/app/app.js +UPD 2014-11-09_03:04:11 5622 www/frontend/app/app.js UPD 2013-04-28_02:00:20 1205 www/frontend/app/view/ChartGridPanel.js UPD 2014-11-08_12:44:55 14475 www/frontend/app/view/DevicePanel.js +UPD 2014-11-09_03:10:38 747 www/frontend/app/view/ChartViewport.js UPD 2014-11-08_12:52:12 9085 www/frontend/app/view/TableDataGridPanel.js -UPD 2014-04-23_05:47:51 65039 www/frontend/app/view/LineChartPanel.js +UPD 2014-11-09_03:08:20 65133 www/frontend/app/view/LineChartPanel.js UPD 2014-01-12_12:09:17 5144 www/frontend/app/view/StatusPanel.js -UPD 2014-11-08_12:54:06 8578 www/frontend/app/view/Viewport.js -UPD 2014-11-08_01:05:40 20348 www/frontend/app/controller/MainController.js +UPD 2014-11-09_03:08:41 8866 www/frontend/app/view/Viewport.js +UPD 2014-11-09_03:07:33 20348 www/frontend/app/controller/MainController.js UPD 2014-01-12_02:49:58 16562 www/frontend/app/controller/StatusController.js -UPD 2014-11-08_12:36:47 111652 www/frontend/app/controller/ChartController.js +UPD 2014-11-09_03:07:05 116072 www/frontend/app/controller/ChartController.js UPD 2014-11-08_12:53:12 5408 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:36 338 www/frontend/app/model/SavedChartsModel.js diff --git a/www/frontend/www/frontend/app/app.js b/www/frontend/www/frontend/app/app.js index a8121a46b..337e98530 100644 --- a/www/frontend/www/frontend/app/app.js +++ b/www/frontend/www/frontend/app/app.js @@ -10,35 +10,36 @@ Ext.Loader.setConfig({ } }); -Ext.application({ - name: 'FHEM Frontend', - requires: [ - 'FHEM.view.Viewport' - ], +//get url params in order to detect which app to start (fullfeatured or just simpleviewer) +var paramArr = document.URL.split("?"); +if (paramArr && paramArr.length > 1 && paramArr[1].indexOf("showchart") > -1) { + var params = Ext.Object.fromQueryString(paramArr[1]), + chartid = params.showchart; + + Ext.application({ + name: 'FHEM Chartviewer', + requires: [ + 'FHEM.view.ChartViewport' + ], + controllers: [ + 'FHEM.controller.ChartController' + ], - controllers: [ - 'FHEM.controller.StatusController', - 'FHEM.controller.MainController', - 'FHEM.controller.ChartController', - 'FHEM.controller.TableDataController' - ], - - launch: function() { - - // Gather information from FHEM to display status, devices, etc. - var me = this, - url = '../../../fhem?cmd=jsonlist2&XHR=1'; - - Ext.Ajax.request({ - method: 'GET', - async: false, - disableCaching: false, - url: url, - success: function(response){ - Ext.getBody().unmask(); - try { + launch: function() { + + // Gather information from FHEM + var me = this, + url = '../../../fhem?cmd=jsonlist2&XHR=1'; + + Ext.Ajax.request({ + method: 'GET', + async: false, + disableCaching: false, + url: url, + success: function(response){ + Ext.getBody().unmask(); + FHEM.info = Ext.decode(response.responseText); - if (window.location.href.indexOf("frontenddev") > 0) { FHEM.appPath = 'www/frontenddev/app/'; } else { @@ -56,9 +57,7 @@ Ext.application({ if ((!FHEM.dblogname || Ext.isEmpty(FHEM.dblogname)) && Ext.isEmpty(FHEM.filelogs)) { Ext.Msg.alert("Error", "Could not find a DbLog or FileLog Configuration. Do you have them already defined?"); } else { - Ext.create("FHEM.view.Viewport", { - hidden: true - }); + Ext.create("FHEM.view.ChartViewport", {chartid:chartid}); //removing the loadingimage var p = Ext.DomQuery.select('p[class=loader]')[0], @@ -66,14 +65,78 @@ Ext.application({ p.removeChild(img); // further configuration of viewport starts in maincontroller } - } catch (e) { - Ext.Msg.alert("Oh no!", "JsonList did not respond correctly. This is a bug in FHEM. This Frontend cannot work without a valid JsonList response. See this link for details and complain there: http://forum.fhem.de/index.php/topic,17292.msg113132.html#msg113132"); - } - }, - failure: function() { - Ext.Msg.alert("Error", "The connection to FHEM could not be established"); - } - }); - - } -}); \ No newline at end of file + }, + failure: function() { + Ext.Msg.alert("Error", "The connection to FHEM could not be established"); + } + }); + } + }); +} else { + Ext.application({ + name: 'FHEM Frontend', + requires: [ + 'FHEM.view.Viewport' + ], + + controllers: [ + 'FHEM.controller.StatusController', + 'FHEM.controller.MainController', + 'FHEM.controller.ChartController', + 'FHEM.controller.TableDataController' + ], + + launch: function() { + + // Gather information from FHEM to display status, devices, etc. + var me = this, + url = '../../../fhem?cmd=jsonlist2&XHR=1'; + + Ext.Ajax.request({ + method: 'GET', + async: false, + disableCaching: false, + url: url, + success: function(response){ + Ext.getBody().unmask(); + try { + FHEM.info = Ext.decode(response.responseText); + + if (window.location.href.indexOf("frontenddev") > 0) { + FHEM.appPath = 'www/frontenddev/app/'; + } else { + FHEM.appPath = 'www/frontend/app/'; + } + FHEM.filelogs = []; + Ext.each(FHEM.info.Results, function(result) { + if (result.Internals.TYPE === "DbLog" && result.Internals.NAME) { + FHEM.dblogname = result.Internals.NAME; + } + if (result.Internals.TYPE === "FileLog") { + FHEM.filelogs.push(result); + } + }); + if ((!FHEM.dblogname || Ext.isEmpty(FHEM.dblogname)) && Ext.isEmpty(FHEM.filelogs)) { + Ext.Msg.alert("Error", "Could not find a DbLog or FileLog Configuration. Do you have them already defined?"); + } else { + Ext.create("FHEM.view.Viewport", { + hidden: true + }); + + //removing the loadingimage + var p = Ext.DomQuery.select('p[class=loader]')[0], + img = Ext.DomQuery.select('#loading-overlay')[0]; + p.removeChild(img); + // further configuration of viewport starts in maincontroller + } + } catch (e) { + Ext.Msg.alert("Oh no!", "JsonList did not respond correctly. This is a bug in FHEM. This Frontend cannot work without a valid JsonList response. See this link for details and complain there: http://forum.fhem.de/index.php/topic,17292.msg113132.html#msg113132"); + } + }, + failure: function() { + Ext.Msg.alert("Error", "The connection to FHEM could not be established"); + } + }); + } + }); +} \ No newline at end of file diff --git a/www/frontend/www/frontend/app/controller/ChartController.js b/www/frontend/www/frontend/app/controller/ChartController.js index 1041fc131..842cda78f 100644 --- a/www/frontend/www/frontend/app/controller/ChartController.js +++ b/www/frontend/www/frontend/app/controller/ChartController.js @@ -22,12 +22,21 @@ Ext.define('FHEM.controller.ChartController', { * minValue of Y2 Axis gets saved here as reference */ minY2Value: 9999999, + + /** + * are we showing just a simple chart? + */ + simplechartview: false, refs: [ { selector: 'panel[name=chartformpanel]', ref: 'chartformpanel' //this.getChartformpanel() }, + { + selector: 'panel[name=chartpanel]', + ref: 'chartpanel' //this.getChartpanel() + }, { selector: 'datefield[name=starttimepicker]', ref: 'starttimepicker' //this.getStarttimepicker() @@ -71,6 +80,10 @@ Ext.define('FHEM.controller.ChartController', { { selector: 'radiogroup[name=datasourceradio]', ref: 'datasourceradio' //this.getDatasourceradio() + }, + { + selector: 'viewport[name=chartviewport]', + ref: 'simplechartviewport' } ], @@ -100,6 +113,9 @@ Ext.define('FHEM.controller.ChartController', { 'menuitem[name=renamechartfromcontext]': { click: this.renamechart }, + 'menuitem[name=integratechartfromcontext]': { + click: this.integrateChart + }, 'treepanel[name=maintreepanel]': { itemclick: this.loadsavedchart }, @@ -129,6 +145,9 @@ Ext.define('FHEM.controller.ChartController', { }, 'button[name=loadfullchart]': { loadchart: this.loadsavedchart + }, + 'viewport[name=chartviewport]': { + afterrender: this.loadAndShowSimpleChart } }); @@ -321,37 +340,38 @@ Ext.define('FHEM.controller.ChartController', { yaxes = Ext.ComponentQuery.query('combobox[name=yaxiscombo]'), rowFieldSets = Ext.ComponentQuery.query('fieldset[commonName=singlerowfieldset]'), yaxesstatistics = Ext.ComponentQuery.query('combobox[name=yaxisstatisticscombo]'), - axissideradio = Ext.ComponentQuery.query('radiogroup[name=axisside]'); - - var starttime = me.getStarttimepicker().getValue(), + axissideradio = Ext.ComponentQuery.query('radiogroup[name=axisside]'), + starttime = me.getStarttimepicker().getValue(), dbstarttime = Ext.Date.format(starttime, 'Y-m-d_H:i:s'), endtime = me.getEndtimepicker().getValue(), dbendtime = Ext.Date.format(endtime, 'Y-m-d_H:i:s'), dynamicradio = Ext.ComponentQuery.query('radiogroup[name=dynamictime]')[0], chartpanel = me.getLinechartpanel(), - hiddenchartdiv = Ext.get("hiddenchart"); - - //cleanup chartpanel - var existingchartgrid = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0]; - if (!existingchartgrid) { - var chartdatagrid = Ext.create('FHEM.view.ChartGridPanel', { - name: 'chartgridpanel', - minHeight: 200, - maxHeight: 200, - collapsed: true - }); - chartpanel.add(chartdatagrid); - } else { - existingchartgrid.down('grid').getStore().removeAll(); - } - var existingchart = Ext.ComponentQuery.query('panel[name=chartpanel]')[0]; - if (existingchart) { - existingchart.destroy(); - } - var store = Ext.create('FHEM.store.ChartStore'), + hiddenchartdiv = Ext.get("hiddenchart"), + existingchart = Ext.ComponentQuery.query('panel[name=chartpanel]')[0], + store = Ext.create('FHEM.store.ChartStore'), proxy = store.getProxy(), chart; + //cleanup chartpanel + if (!me.simplechartview) { + var existingchartgrid = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0]; + if (!existingchartgrid) { + var chartdatagrid = Ext.create('FHEM.view.ChartGridPanel', { + name: 'chartgridpanel', + minHeight: 200, + maxHeight: 200, + collapsed: true + }); + chartpanel.add(chartdatagrid); + } else { + existingchartgrid.down('grid').getStore().removeAll(); + } + } + + if (existingchart) { + existingchart.destroy(); + } if (hidden === true) { chart = me.createChart(store, hiddenchartdiv); @@ -470,41 +490,48 @@ Ext.define('FHEM.controller.ChartController', { i++; }); - }, 300); + }, 100); }, /** * resize the chart to fit the centerpanel */ resizeChart: function() { - var lcp = Ext.ComponentQuery.query('linechartpanel')[0]; - var lcv = Ext.ComponentQuery.query('chart')[0]; - var cfp = Ext.ComponentQuery.query('form[name=chartformpanel]')[0]; - var cdg = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0]; - + var me = this, + lcp = Ext.ComponentQuery.query('linechartpanel')[0], + lcv = Ext.ComponentQuery.query('chart')[0], + cfp = Ext.ComponentQuery.query('form[name=chartformpanel]')[0], + cdg = Ext.ComponentQuery.query('panel[name=chartgridpanel]')[0] || true; + if (lcv) { if (lcp && lcv && cfp && cdg) { var lcph = lcp.getHeight(), lcpw = lcp.getWidth(), cfph = cfp.getHeight(), - cdgh = cdg.getHeight(); + cdgh = Ext.isObject(cdg) ? cdg.getHeight() : 0; - if (lcph && lcpw && cfph && cdgh) { - var chartheight = lcph - cfph - cdgh - 80; - var chartwidth = lcpw - 5; - lcv.height = chartheight; - lcv.width = chartwidth; - //render after 50ms to get component right - window.setTimeout(function() { - if (lcv.series.get(0).hideAll) { - lcv.series.get(0).hideAll(); - } - lcv.doComponentLayout(); - if (lcv.series.get(0).showAll) { - lcv.series.get(0).showAll(); - } - lcv.redraw(); - }, 50); + if (Ext.isNumeric(lcph) && + Ext.isNumeric(lcpw) && + Ext.isNumeric(cfph) && + Ext.isNumeric(cdgh)) { + + var chartheight = lcph - cfph - cdgh - 80; + var chartwidth = lcpw - 5; + lcv.height = chartheight; + lcv.width = chartwidth; + //render after 50ms to get component right + window.setTimeout(function() { + if (lcv.series.get(0).hideAll) { + lcv.series.get(0).hideAll(); + } + lcv.doComponentLayout(); + if (lcv.series.get(0).showAll) { + lcv.series.get(0).showAll(); + } + lcv.redraw(); + + me.fireEvent("chartready"); + }, 50); } } } @@ -519,7 +546,7 @@ Ext.define('FHEM.controller.ChartController', { var chart = Ext.create('Ext.panel.Panel', { title: 'Chart', name: 'chartpanel', - collapsible: true, + collapsible: !me.simplechartview, titleCollapse: true, animCollapse: false, width: hidden ? 1 : false, @@ -944,7 +971,6 @@ Ext.define('FHEM.controller.ChartController', { } //as we have the valuetext, we can fill the grid - //fill the grid with the data me.fillChartGrid(json.data, valuetext); var timestamptext; @@ -1170,6 +1196,7 @@ Ext.define('FHEM.controller.ChartController', { } me.getLinechartpanel().setLoading(false); + }, /** @@ -1181,6 +1208,11 @@ Ext.define('FHEM.controller.ChartController', { var chart = Ext.ComponentQuery.query('chart')[0], axis; + // make chart visible before manipulating axes + if (!chart.isVisible()) { + chart.up().up().show(); + } + if (axisside === "left") { axis = chart.axes.get(0); axistitle = this.getChartformpanel().down('textfield[name=leftaxistitle]').getValue(); @@ -2015,7 +2047,10 @@ Ext.define('FHEM.controller.ChartController', { } this.requestChartData(false, hidden); - this.getLinechartpanel().setTitle(name); + // set title only in standard mode to master panel (not simple chart view) + if (!me.simplechartview) { + this.getLinechartpanel().setTitle(name); + } } else { Ext.Msg.alert("Error", "The Chart could not be loaded! RawChartdata was:
" + chartdata); } @@ -2176,9 +2211,10 @@ Ext.define('FHEM.controller.ChartController', { * fill the charts grid with data */ fillChartGrid: function(jsondata, valuetext) { - if (jsondata && jsondata[0]) { - //this.getChartformpanel().collapse(); - + + var grid = this.getChartdatagrid(); + if (grid && jsondata && jsondata[0]) { + var store = this.getChartdatagrid().getStore(), columnwidth = 0, storefields = [], @@ -2365,5 +2401,101 @@ Ext.define('FHEM.controller.ChartController', { }); } Ext.ComponentQuery.query('treepanel')[0].setLoading(false); + }, + + /** + * method used to retrieve config of a saved chart and create the desired chart for + * simpler fhem integration (simple chart view) + */ + loadAndShowSimpleChart: function() { + // get the chartconfig for the given id + var me = this, + chartid = me.getSimplechartviewport().chartid, + config = {}; + + me.simplechartview = true; + + // first, check the filelogs + Ext.each(FHEM.filelogcharts, function(log) { + if (log.ID === parseInt(chartid,10)) { + config.raw = {}; + config.raw.data = log; + me.on("chartready", function() { + var c = Ext.ComponentQuery.query('chart')[0]; + c.setHeight(c.getHeight() + 30); + c.up().setTitle(log.NAME); + }); + me.loadsavedchart(false, config, false); + return false; + } + }); + + // if no filelog found, search the db + if (Ext.isEmpty(config.raw)) { + //load the saved charts store with configured dblog name + var me = this, + store = Ext.create('FHEM.store.SavedChartsStore', {}); + + store.getProxy().url = '../../../fhem?cmd=get+' + FHEM.dblogname + '+-+webchart+""+""+""+getcharts&XHR=1'; + store.load(); + store.on("load", function() { + store.each(function(rec) { + if (rec.raw.NAME && rec.raw.NAME === chartid) { + config = rec; + me.on("chartready", function() { + var c = Ext.ComponentQuery.query('chart')[0]; + c.setHeight(c.getHeight() + 30); + c.up().setTitle(rec.raw.NAME); + }); + me.loadsavedchart(false, config, false); + return false; + } + }); + + // if no match found, throw error + if (Ext.isEmpty(config.raw)) { + Ext.Msg.alert("Error", "The chart could not be found!"); + return; + } + }); + } + }, + + /** + * method shows an fhem definition for this chart + * to integrate it as an iframe in the fhem view + */ + integrateChart: function(menu) { + /** + * define charttest weblink iframe http://192.168.0.111:8085/fhem/frontenddev/index.html?a=b&c=d&showchart=sdfsd + attr charttest htmlattr width="500" height="300" + attr charttest room Keller + */ + var me = this, + rec = menu.record, + url = window.location.href, + id; + + if (!rec || !rec.raw || !rec.raw.data) { + Ext.Msg.alert("Error", "Invalid configuration, please report!"); + return false; + } + + url += '?showchart='; + + if (rec.raw.data.TYPE === "savedfilelogchart") { + url += rec.raw.data.ID; + } else { + url += rec.raw.data.NAME; + } + + Ext.create('Ext.window.Window', { + width: 600, + height: 150, + html: 'Copy the following code to your fhem.cfg and modify it to integrate this chart in your FHEM views:

' + + 'define ' + rec.raw.data.NAME + ' weblink iframe ' + url + '
' + + 'attr ' + rec.raw.data.NAME + ' htmlattr width="500" height="300"
' + + 'attr ' + rec.raw.data.NAME + ' room Keller
' + }).show(); } }); diff --git a/www/frontend/www/frontend/app/controller/MainController.js b/www/frontend/www/frontend/app/controller/MainController.js index 6b2497c08..da62ef0d1 100644 --- a/www/frontend/www/frontend/app/controller/MainController.js +++ b/www/frontend/www/frontend/app/controller/MainController.js @@ -93,7 +93,7 @@ Ext.define('FHEM.controller.MainController', { }); var sp = this.getStatustextfield(); - sp.setText("Frontend Version: 1.1.0 - 2014-11-08"); + sp.setText("Frontend Version: 1.1.1 - 2014-11-09"); this.setupTree(); }, diff --git a/www/frontend/www/frontend/app/view/ChartViewport.js b/www/frontend/www/frontend/app/view/ChartViewport.js new file mode 100644 index 000000000..7892eafd8 --- /dev/null +++ b/www/frontend/www/frontend/app/view/ChartViewport.js @@ -0,0 +1,33 @@ +/** + * The main application viewport, which displays the charts + * @extends Ext.Viewport + */ +Ext.define('FHEM.view.ChartViewport', { + extend: 'Ext.Viewport', + name: 'chartviewport', + layout: 'fit', + requires: [ + 'FHEM.view.LineChartPanel', + 'Ext.panel.Panel' + ], + /** + * the given chart reference + */ + chartid: null, + + initComponent: function() { + var me = this; + + Ext.apply(me, { + items: [ + { + xtype: 'linechartpanel', + name: 'linechartpanel', + hideSettingsPanel: true, + preventHeader: true + } + ] + }); + me.callParent(arguments); + } +}); diff --git a/www/frontend/www/frontend/app/view/LineChartPanel.js b/www/frontend/www/frontend/app/view/LineChartPanel.js index 6e52ea078..dbb3d5417 100644 --- a/www/frontend/www/frontend/app/view/LineChartPanel.js +++ b/www/frontend/www/frontend/app/view/LineChartPanel.js @@ -69,7 +69,12 @@ Ext.define('FHEM.view.LineChartPanel', { /** * the title */ - title: 'Line Chart', + title: false, + + /** + * + */ + hideSettingsPanel: false, /** * init function @@ -101,6 +106,7 @@ Ext.define('FHEM.view.LineChartPanel', { collapsible: true, titleCollapse: true, animCollapse: false, + hidden: me.hideSettingsPanel, items: [ { xtype: 'fieldset', diff --git a/www/frontend/www/frontend/app/view/Viewport.js b/www/frontend/www/frontend/app/view/Viewport.js index 8da5e5c99..144e17a89 100644 --- a/www/frontend/www/frontend/app/view/Viewport.js +++ b/www/frontend/www/frontend/app/view/Viewport.js @@ -159,6 +159,10 @@ Ext.define('FHEM.view.Viewport', { text: 'Rename Chart', name: 'renamechartfromcontext', record: rec + }, '-', { + text: 'Integrate in FHEM', + name: 'integratechartfromcontext', + record: rec } ] }).showAt(e.xy);