/** * Project  : AMDA-NG * Name : PlotTabResultUI.js * @class amdaUI.PlotTabResultUI * @extends Ext. panel.Panel * @brief Plot Tab Result UI definition (View) * @author * @version $Id: PlotTabResultUI.js benjamin */ Ext.define('amdaUI.PlotTabResultUI', { extend: 'Ext.panel.Panel', alias: 'widget.plotTabResult', requires: [ 'amdaPlotComp.PlotZoomPlug', 'amdaPlotComp.PlotExtendShiftPlug', 'amdaPlotComp.PlotContextManager', 'amdaPlotComp.PlotResultImage' ], panelImage : null, crtContext : null, interactiveId : '', navToolBar : null, isTTNavBar : false, crtTTFileIndex : 0, disableSynchronize: false, multiplot: false, hiddenForm: null, constructor: function(config) { this.addEvents({'pagesize':true}); this.init(config); this.callParent(arguments); }, updateMultiplot : function(multiplot) { this.multiplot = multiplot; this.findParentByType('window').updateTitle(this.multiplot); }, getImageSize : function() { if (!this.crtContext) return { width : 0, height : 0 }; return { width : this.crtContext.page.width * this.sliderPage.getValue()/100., height : this.crtContext.page.height * this.sliderPage.getValue()/100. } }, getImageUrl: function(resultFolder, plotFile) { return 'data/'+sessionID +'/RES/'+resultFolder+ '/' + plotFile; }, toPixelOnSourceImage : function(value) { return value*100/this.sliderPage.getValue(); }, toPixelOnResultImage : function(value) { return value*this.sliderPage.getValue()/100; }, createZoomItemsForPanel: function(panelId) { var zoomPlugin = this.getPlugin('plot-zoom-plugin-id'); if (zoomPlugin == null) return; var panelContext = amdaPlotComp.PlotContextManager.getPanelById(this.crtContext, panelId); var size = this.getImageSize(); var me = this; var insertIntervalItem = null; Ext.each(panelContext.plotArea.axes, function (axis) { //Events for zoom on a time axis var onMinTimeSelection = function (posX) { //Panel and axis context must be retrieved by using the crtContext var panelContext = amdaPlotComp.PlotContextManager.getPanelById(me.crtContext, panelId); var axisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panelContext, axis.id); var sourceXPos = me.toPixelOnSourceImage(posX); var crtTimestamp = amdaPlotComp.PlotContextManager.toAxisValue(axisContext, panelContext.plotArea.x, panelContext.plotArea.x+panelContext.plotArea.width, sourceXPos); var crtTime = new Date(crtTimestamp*1000); crtTime = Ext.Date.add(crtTime, Ext.Date.MINUTE, crtTime.getTimezoneOffset()); zoomPlugin.setMinValue(crtTime); }; var onMaxTimeSelection = function (posX) { //Panel and axis context must be retrieved by using the crtContext var panelContext = amdaPlotComp.PlotContextManager.getPanelById(me.crtContext, panelId); var axisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panelContext, axis.id); var sourceXPos = me.toPixelOnSourceImage(posX); var crtTimestamp = amdaPlotComp.PlotContextManager.toAxisValue(axisContext, panelContext.plotArea.x, panelContext.plotArea.x+panelContext.plotArea.width, sourceXPos); var crtTime = new Date(crtTimestamp*1000); crtTime = Ext.Date.add(crtTime, Ext.Date.MINUTE, crtTime.getTimezoneOffset()); zoomPlugin.setMaxValue(crtTime); }; //Events for zoom on a Y axis var onMinYValueSelection = function(posY) { //Panel and axis context must be retrieved by using the crtContext var panelContext = amdaPlotComp.PlotContextManager.getPanelById(me.crtContext, panelId); var axisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panelContext, axis.id); var sourceYPos = me.toPixelOnSourceImage(posY); var crtValue = amdaPlotComp.PlotContextManager.toAxisValue(axisContext, panelContext.plotArea.y+panelContext.plotArea.height, panelContext.plotArea.y, sourceYPos); zoomPlugin.setMinValue(crtValue); }; var onMaxYValueSelection = function(posY) { //Panel and axis context must be retrieved by using the crtContext var panelContext = amdaPlotComp.PlotContextManager.getPanelById(me.crtContext, panelId); var axisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panelContext, axis.id); var sourceYPos = me.toPixelOnSourceImage(posY); var crtValue = amdaPlotComp.PlotContextManager.toAxisValue(axisContext, panelContext.plotArea.y+panelContext.plotArea.height, panelContext.plotArea.y, sourceYPos); zoomPlugin.setMaxValue(crtValue); }; //Events for zoom on X axis var onMinXValueSelection = function(posX) { //Panel and axis context must be retrieved by using the crtContext var panelContext = amdaPlotComp.PlotContextManager.getPanelById(me.crtContext, panelId); var axisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panelContext, axis.id); var sourceXPos = me.toPixelOnSourceImage(posX); var crtValue = amdaPlotComp.PlotContextManager.toAxisValue(axisContext, panelContext.plotArea.x, panelContext.plotArea.x + panelContext.plotArea.width, sourceXPos); zoomPlugin.setMinValue(crtValue); }; var onMaxXValueSelection = function(posX) { //Panel and axis context must be retrieved by using the crtContext var panelContext = amdaPlotComp.PlotContextManager.getPanelById(me.crtContext, panelId); var axisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panelContext, axis.id); var sourceXPos = me.toPixelOnSourceImage(posX); var crtValue = amdaPlotComp.PlotContextManager.toAxisValue(axisContext, panelContext.plotArea.x, panelContext.plotArea.x + panelContext.plotArea.width, sourceXPos); zoomPlugin.setMaxValue(crtValue); }; switch (axis.id) { case 'timeAxis': me.contextualMenu.add({ text:'Zoom on Time Axis', handler : function(item, e) { zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); zoomPlugin.resetMinMaxValue(); me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection); }, scope: this }); insertIntervalItem = { text:'Insert Interval in TimeTable or Catalog', handler : function(item, e) { zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); zoomPlugin.resetMinMaxValue(); me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection); }, scope: this }; break; case 'y-left' : me.contextualMenu.add({ text:'Zoom on Y Left Axis', handler : function(item, e) { zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); zoomPlugin.resetMinMaxValue(); me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection); } }); break; case 'y-right' : me.contextualMenu.add({ text:'Zoom on Y Right Axis', handler : function(item, e) { zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); zoomPlugin.resetMinMaxValue(); me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection); } }); break; case 'xaxis_id' : me.contextualMenu.add({ text:'Zoom on X Axis', handler : function(item, e) { zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); zoomPlugin.resetMinMaxValue(); me.panelImage.startZoom(true, me.toPixelOnResultImage(panelContext.y), me.toPixelOnResultImage(panelContext.height), onMinXValueSelection, onMaxXValueSelection); } }); break; case 'epochAxis' : //Nothing to add break; } }); if (insertIntervalItem != null) { me.contextualMenu.add('-'); me.contextualMenu.add(insertIntervalItem); } }, getAxisValue: function(axis, pixelMin, pixelMax, pixelVal) { var val = amdaPlotComp.PlotContextManager.toAxisValue(axis, pixelMin, pixelMax, pixelVal); return parseFloat(val).toPrecision(5); }, createPlotImage: function(resultFolder, plotFile) { var me = this; var size = this.getImageSize(); this.panelImage = Ext.create('amdaPlotComp.PlotResultImage', { src : this.getImageUrl(resultFolder, plotFile), width : size.width, height : size.height, onMouseMove : function(x, y) { if (!me.crtContext) return; var sourceXPos = me.toPixelOnSourceImage(x); var sourceYPos = me.toPixelOnSourceImage(y); var panel = amdaPlotComp.PlotContextManager.getPanel(me.crtContext, sourceXPos, sourceYPos); var text = ''; if (me.panelImage) { if (!panel) { me.panelImage.resetCursor(); text += 'No panel'; } else { text += 'Panel Id : '; text += panel.id; if (amdaPlotComp.PlotContextManager.isInPlotArea(panel, sourceXPos, sourceYPos)) { /*me.panelImage.updateCursor( me.toPixelOnResultImage(panel.plotArea.x), me.toPixelOnResultImage(panel.plotArea.y), me.toPixelOnResultImage(panel.plotArea.width), me.toPixelOnResultImage(panel.plotArea.height), x, y);*/ me.panelImage.updateCursor( me.toPixelOnResultImage(0), me.toPixelOnResultImage(0), me.toPixelOnResultImage(me.crtContext.page.width), me.toPixelOnResultImage(me.crtContext.page.height), x, y); var xText = ''; var yLeftText = ''; var yRightText = ''; Ext.each(panel.plotArea.axes, function (axis) { switch (axis.id) { case 'timeAxis': var crtTimestamp = amdaPlotComp.PlotContextManager.toAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); var crtTime = new Date(crtTimestamp*1000); xText = crtTime.toJSON(); break; case 'y-left' : yLeftText = me.getAxisValue(axis, panel.plotArea.y+panel.plotArea.height, panel.plotArea.y, sourceYPos); break; case 'y-right' : yRightText = me.getAxisValue(axis, panel.plotArea.y+panel.plotArea.height, panel.plotArea.y, sourceYPos); break; case 'xaxis_id' : xText = me.getAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); break; case 'epochAxis' : xText = me.getAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); break; } }); if (xText != '') text += (', X : '+xText); if (yLeftText != '') text += (', Y Left : '+yLeftText); if (yRightText != '') text += (', Y Right : '+yRightText); } else me.panelImage.resetCursor(); } } me.coordinatesField.setText(text); }, onContextMenu : function(absoluteX, absoluteY, imageX, imageY) { if (!me.crtContext) return; me.contextualMenu.removeAll(true); var sourceXPos = me.toPixelOnSourceImage(imageX); var sourceYPos = me.toPixelOnSourceImage(imageY); var panel = amdaPlotComp.PlotContextManager.getPanel(me.crtContext, sourceXPos, sourceYPos); if (panel != null) { if (panel.plotArea.hasSpectro) { me.contextualMenu.add([ { text:'Instant cut at this position', handler : function () { var timeAxisContext = amdaPlotComp.PlotContextManager.getPanelAxisById(panel, 'timeAxis'); if (timeAxisContext == null) return; var crtTimestamp = amdaPlotComp.PlotContextManager.toAxisValue(timeAxisContext, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); var crtTime = new Date(crtTimestamp*1000); crtTime = Ext.Date.add(crtTime, Ext.Date.MINUTE, crtTime.getTimezoneOffset()); me.callInteractivePlot({'action' : 'instant', 'interactiveId' : this.interactiveId, 'panelId' : panel.id, 'time' : crtTime}); }, scope: me }, '-' ]); } if (amdaPlotComp.PlotContextManager.isInPlotArea(panel, sourceXPos, sourceYPos)) me.createZoomItemsForPanel(panel.id); } if (me.contextualMenu.items.getCount() > 0) me.contextualMenu.add('-'); me.contextualMenu.add([ { text:'Extend/Shift Time interval', disabled : me.isTTNavBar, handler : function () { var extendShiftPlugin = this.getPlugin('plot-extendshift-plugin-id'); extendShiftPlugin.show(me.interactiveId); }, scope: me }, '-', { text: 'Save Plot', handler : function () { if (me.hiddenForm == null) me.hiddenForm = Ext.create('Ext.form.Panel', { title:'hiddenForm', renderTo: Ext.getBody(), standardSubmit: true, url: 'php/downloadPlot.php', timeout: 120000, height:100, width: 100, hidden:true, items:[] }); me.hiddenForm.getForm().submit({ params: { sessionId: sessionID, interactiveId : me.interactiveId }, success: function(form, action) {}, failure: function(form, action) {} }); } } ]); me.contextualMenu.showAt(absoluteX, absoluteY); } }); return this.panelImage; }, updatePlotImage: function(configResult, newPlot) { this.crtContext = configResult.context; this.crtTTFileIndex = configResult.ttFileIndex; if (this.isTTNavBar != (!configResult.isInterval) || (this.isSuperposeMode != this.crtContext.page.superposeMode)) { //Update navigation bar this.updateNavToolBar(!configResult.isInterval, this.crtContext.page.superposeMode); } this.updateTimeTableInfo(); this.panelImage.setSrc(this.getImageUrl(configResult.folder, configResult.plotFile)); var size = this.getImageSize(); this.panelImage.setSize(size.width, size.height); this.panelImage.refreshMe(); }, updateTimeTableInfo: function() { if (!this.navToolBar) return; var ttNameField = this.navToolBar.items.get('tt-table-'+this.interactiveId); if (ttNameField) ttNameField.setValue(this.crtContext.page.ttName); var ttNumberField = this.navToolBar.items.get('tt-number-'+this.interactiveId); if (ttNumberField) ttNumberField.setValue(this.crtContext.page.ttIndex + 1); var ttTotalField = this.navToolBar.items.get('tt-total-'+this.interactiveId); if (ttTotalField) ttTotalField.setValue(this.crtContext.page.ttNbIntervals); }, callInteractivePlot : function(obj) { loadMask.show(true); var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); obj['multiplot'] = this.multiplot; AmdaAction.interactivePlot(obj, function (result, e) { loadMask.hide(); var t = e.getTransaction(); if (e.status) { if (result) { if (result.success) { plotModule.updateInteractiveSession(result, false); } else myDesktopApp.errorMsg('Interactive action error - '+result.message); } else myDesktopApp.errorMsg('Cannot execute interactive action'); } else { // FAILURE myDesktopApp.errorMsg('Error System - '+e.message); } },this); }, updateNavToolBar : function(isTimeTable, isSuperposeMode) { if (this.navToolBar) this.navToolBar.removeAll(true); var commonItemsCfg = [ '-', { xtype: 'tbspacer', width: 20 }, '->', { text: 'Get HST Data', scope: this, menu: [ { text: 'Giant Planet Auroral Emissions', scope: this, handler: function() { var me = this; myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.astro.id, true, function (module) { var startTime = new Date(me.crtContext.page.startTime*1000); startTime = Ext.Date.add(startTime, Ext.Date.MINUTE, startTime.getTimezoneOffset()); var stopTime = new Date(me.crtContext.page.stopTime*1000); stopTime = Ext.Date.add(stopTime, Ext.Date.MINUTE, stopTime.getTimezoneOffset()); module.createWindow(startTime,stopTime); }); } }] }]; if (isTimeTable){ var navigationItemsCfg = [{ text: 'Previous', scope: this, handler: function(){ var ttFileIndex = this.crtTTFileIndex; var ttintervalIndex = this.crtContext.page.ttIndex; if (ttintervalIndex <= 0 && ttFileIndex>0){ --ttFileIndex; } else --ttintervalIndex; this.callInteractivePlot({'action' : 'goto', 'interactiveId' : this.interactiveId, 'ttFileIndex' : ttFileIndex, 'intIndex' : ttintervalIndex}); } }, '-', { text: 'Next', scope: this, handler: function(){ var ttFileIndex = this.crtTTFileIndex; var ttintervalIndex = this.crtContext.page.ttIndex; if (ttintervalIndex >= this.crtContext.page.ttNbIntervals-1){ ++ttFileIndex; ttintervalIndex = 0; } else ++ttintervalIndex; this.callInteractivePlot({'action' : 'goto', 'interactiveId' : this.interactiveId, 'ttFileIndex' : ttFileIndex, 'intIndex' : ttintervalIndex}); } }, '-', { text: 'Go to Interval #', scope: this, handler: function(bt){ var ttGotoNumberField = this.navToolBar.items.get('tt-goto-number-'+this.interactiveId); var goToIndex = ttGotoNumberField.getValue() - 1; if ((goToIndex < 0) || (goToIndex >= this.crtContext.page.ttNbIntervals)) myDesktopApp.errorMsg('This interval number is outside of the current timeTable'); else this.callInteractivePlot({'action' : 'goto', 'interactiveId' : this.interactiveId, 'ttFileIndex' : this.crtTTFileIndex, 'intIndex' : goToIndex}); } }, { xtype: 'numberfield', id : 'tt-goto-number-'+this.interactiveId, hideTrigger: true, width: 50, minValue: 1 }, ' ', ' ', ' ', { xtype: 'textfield', id: 'tt-table-'+this.interactiveId, labelAlign: 'right', labelWidth: 30, fieldLabel: 'Table', width: 130, disabled : true }, { xtype: 'textfield', id: 'tt-number-'+this.interactiveId, labelAlign: 'right', labelWidth: 30, fieldLabel: 'Int #', width: 90, disabled : true }, { xtype: 'textfield', id: 'tt-total-'+this.interactiveId, labelAlign: 'right', labelWidth: 30, fieldLabel: 'Total', width: 90, disabled : true }]; } else { var navigationItemsCfg = [ { text: 'Backward', scope: this, handler: function(){ this.callInteractivePlot({'action' : 'backward', 'interactiveId' : this.interactiveId}); } }, '-', { text: '1/2 Backward', scope: this, handler: function(){ this.callInteractivePlot({'action' : 'halfbackward', 'interactiveId' : this.interactiveId}); } }, '-', { text: '1/2 Forward', scope: this, handler: function(){ this.callInteractivePlot({'action' : 'halfforward', 'interactiveId' : this.interactiveId}); } }, '-', { text: 'Forward', scope: this, handler: function(){ this.callInteractivePlot({'action' : 'forward', 'interactiveId' : this.interactiveId}); } }]; } var toolItemsCfg = navigationItemsCfg; Ext.each(commonItemsCfg, function(item){ toolItemsCfg.push(item); }); if (!this.navToolBar) { var toolConfig = { dock: 'top', items: toolItemsCfg }; this.navToolBar = Ext.create('Ext.toolbar.Toolbar', toolConfig); } else this.navToolBar.add(toolItemsCfg); this.navToolBar.setDisabled(isSuperposeMode); this.isTTNavBar = isTimeTable; this.isSuperposeMode = isSuperposeMode; }, init: function(configResult){ this.crtContext = configResult.context; this.interactiveId = configResult.interactiveId; this.multiplot = (configResult.multiplot == true); this.coordinatesField = new Ext.toolbar.TextItem({ width: 300, text : '' }); this.sliderPage = new Ext.slider.Single({ width: 130, value: 75, increment: 5, minValue: 50, maxValue: 100, fieldLabel : 'Resize', labelWidth : 40, listeners: { scope : this, changecomplete: function(s, v) { var zoomPlugin = this.getPlugin('plot-zoom-plugin-id'); zoomPlugin.close(); var size = this.getImageSize(); this.panelImage.width = size.width; this.panelImage.height = size.height; this.panelImage.doComponentLayout(); this.fireEvent('pagesize',this,v); } } }); var mouseToolbar = { xtype: 'toolbar', height: 25, dock: 'bottom', items:[ this.coordinatesField, '->', this.sliderPage ] }; this.contextualMenu = Ext.create('Ext.menu.Menu', { width: 200, plain: true, items: [] }); this.updateNavToolBar(!configResult.isInterval, this.crtContext.page.superposeMode); this.updateTimeTableInfo(); var plotResultTabPanelConfig = { preventHeader : true, autoScroll: true, items: [ this.createPlotImage(configResult.folder, configResult.plotFile)], dockedItems: [this.navToolBar, mouseToolbar], plugins: [ { ptype: 'plotZoomPlugin', pluginId : 'plot-zoom-plugin-id' }, { ptype: 'plotExtendShiftPlugin', pluginId : 'plot-extendshift-plugin-id' }], listeners: { scope : this, destroy : function () { var zoomPlugin = this.getPlugin('plot-zoom-plugin-id'); if (zoomPlugin) zoomPlugin.close(); var exttendShiftPlugin = this.getPlugin('plot-extendshift-plugin-id'); if (exttendShiftPlugin) exttendShiftPlugin.close(); } } }; Ext.apply(this , plotResultTabPanelConfig); } });