diff --git a/js/app/controllers/PlotModule.js b/js/app/controllers/PlotModule.js index f24055e..723fd6e 100644 --- a/js/app/controllers/PlotModule.js +++ b/js/app/controllers/PlotModule.js @@ -71,7 +71,8 @@ Ext.define('amdaDesktop.PlotModule', { var plotTabConfig = { folder : session.folder, plotFile : tabResult.plot, - context : tabResult.context + context : tabResult.context, + tabId : tabResult.id }; if (winResult == null) { @@ -123,7 +124,7 @@ Ext.define('amdaDesktop.PlotModule', { }); }, - updateInteractiveSession : function() { + updateInteractiveSession : function(interactiveResult) { }, diff --git a/js/app/views/InteractiveIntervalPlugin.js b/js/app/views/InteractiveIntervalPlugin.js deleted file mode 100644 index d5ae1bd..0000000 --- a/js/app/views/InteractiveIntervalPlugin.js +++ /dev/null @@ -1,370 +0,0 @@ -/** - * Project : AMDA-NG - * Name : InteractiveIntervalPlug.js - * @plugin amdaUI.InteractiveIntervalPlug - * @extends Ext.util.Observable - * @ptype interactiveIntervalPlugin - * @brief Plot interactive session UI (View) - * @author Myriam - * @version $Id: InteractiveIntervalPlugin.js 2617 2014-10-24 12:06:57Z elena $ - ******************************************************************************** - * FT Id : Date : Name - Description - ******************************************************************************* - * : - */ - - -Ext.define('amdaUI.InteractiveIntervalPlugin', { - extend: 'Ext.util.Observable',//'Ext.AbstractPlugin', - alias: 'plugin.interactiveIntervalPlugin', - - linkedNode : null, - - moduleId : 'timetab-win', - - rootNode : null, - win : null, - - addInterval : false, - - constructor: function(config) { - Ext.apply(this, config); - this.callParent(arguments); - }, - - - init: function(cmp) { - this.hostCmp = cmp; - this.hostCmp.on({ - open: this.onOpen, - startTime: this.setStart, - stopTime: this.setStop, - scope: this - }); - -//Global event - myDesktopApp.EventManager.on({ - refresh : this.insertInterval, - scope: this}); - }, - - onDestroy : function() { - this.win = null; - }, - - setStart: function(a){ - if (this.form) - this.form.getForm().findField('start').setValue(a); - }, - - setStop: function(b){ - var a = new Date(this.form.getForm().findField('start').getValue()); - if (a <= b) { - this.form.getForm().findField('stop').setValue(b); - } else { - this.form.getForm().findField('start').setValue(b); - this.form.getForm().findField('stop').setValue(a); - } - }, - -/** - * add Interval to Time table - **/ - insertInterval: function() { - - if (this.addInterval) { - var targetModule = myDesktopApp.getLoadedModule(this.moduleId); - if (targetModule) - { - var targetModuleUI = targetModule.getUiContent(); - if (targetModuleUI) - targetModuleUI.addInterval(this.start,this.stop); - } - } - this.addInterval = false; - }, - -/** - * creation of the window - */ - onOpen: function() { - if (!this.win) { - this.win = new Ext.Window({ - id: 'interactiveInter-win-' + this.hostCmp.ownerCt.ownerCt.getId(), // Plot window ID - width: 380, - height: 160, - x: 0, y: 0, - baseCls:'x-panel', - title: 'Interactive Interval', - layout: 'fit', - constrain: true, - collapsible: true, - ghost: false, - renderTo: this.hostCmp.ownerCt.getId(), - items: this.getFormConfig(), - listeners: { - scope: this, - beforeclose: function() { - this.hostCmp.ownerCt.destroyMire(); - Ext.PluginManager.unregister(this); - } - }, - getConstrainVector: function(constrainTo){ - var me = this; - if (me.constrain || me.constrainHeader) { - constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container || me.el.getScopeParent(); - return (me.constrainHeader ? me.header.el : me.el).getConstrainVector(constrainTo); - } - } - }); - - this.win.on('destroy', this.onDestroy, this); - - this.id = 'interactiveInter-' + this.hostCmp.ownerCt.ownerCt.getId(); - - Ext.PluginManager.register(this); - this.win.show(); - this.win.setPosition(0,0); - var tree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID); - this.rootNode = tree.getRootNode().findChild('id','timeTable-treeRootNode',true); - - amdaModel.InteractiveNode.preloadNodes(this.rootNode, - function() - { - }); - } - }, - -/** - * check if multi or individual operation - */ - isMultiZoom: function() { - - var win = myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.interactive_plot.id); - if (!win) return false; - - var multiPlotUI = win.items.getAt(0); - var checked = multiPlotUI.checkBoxGroup.getChecked(); - - if (checked.length == 0) return false; - // check if this Plot is not checked then this is individual zoom - var hostId = this.hostCmp.ownerCt.ownerCt.getId(); - - var isUnique = Ext.Array.every(checked, function(item){ - if (item.name === hostId) - return false; - }); - - return !isUnique; - }, - - resetStartStop: function() { - this.form.getForm().findField('start').setValue(''); - this.form.getForm().findField('stop').setValue(''); - this.hostCmp.ownerCt.resetMire(); - }, - - -/** - * Main form - */ - getFormConfig: function(){ - this.form = new Ext.form.FormPanel( { - frame: true, - width: 380, - height: 160, - layout: 'hbox', - fieldDefaults: { - labelWidth: 100 - }, - items: [ - { - xtype: 'container', - width : 250, - layout : 'vbox', - defaults: { height : 25, width: 250 }, - items: [ - { - xtype:'datefield', name:'start', fieldLabel: 'Start Time', - format : 'Y-m-d\\TH:i:s' - }, - { - xtype:'datefield', name:'stop', fieldLabel: 'Stop Time', - format : 'Y-m-d\\TH:i:s' - }, - { - xtype: 'textfield', - fieldLabel: 'Add in TimeTable', - name: 'timeTableName', - listeners : - { - render : function(o,op) - { - var me = this; - var el = me.el; - var dropTarget = Ext.create('Ext.dd.DropTarget', el, { - ddGroup: 'explorerTree', - notifyOver : function(ddSource, e, data) - { - if ((data.records[0].data.nodeType == 'timeTable') && (data.records[0].data.leaf)) - { - this.valid = true; - return this.dropAllowed; - } - this.valid = false; - return this.dropNotAllowed; - }, - notifyDrop : function(ddSource, e, data) - { - if (!this.valid) - return false; - me.setValue(data.records[0].get('text')); - return true; - } - }); - } - } - } - ] - }, - { - xtype: 'container', - width : 130, - margin: '0 0 0 15', - layout : 'vbox', - defaults: {height : 25, width: 100}, - items: [ - { - xtype: 'button', - text: 'Reset Start/Stop', - scope: this, - handler: function() { - this.resetStartStop(); - } - }, - { xtype: 'component', height: 34 }, - { - xtype: 'button', - text: 'Insert Interval', - scope: this, - handler: function(){ - // linkedNode.isValidName(value); - this.start = this.form.getForm().findField('start').getValue(); - this.stop = this.form.getForm().findField('stop').getValue(); - // new TimeTable or typed manually - var targetModule = myDesktopApp.getLoadedModule(this.moduleId); - var targetModuleUI = null; - if (targetModule) - targetModuleUI = targetModule.getUiContent(); - var TTname = this.form.getForm().findField('timeTableName').getValue(); -// TT window was closed or TTname was changed - if (!targetModuleUI || !this.linkedNode || TTname !== this.linkedNode.get('text')) { - var nodeWithSameName = this.rootNode.findChild('text', TTname, true); - if (nodeWithSameName !== null) { - this.linkedNode = nodeWithSameName; - this.linkedNode.editLeaf(); - this.addInterval = true; - } - else { - obj = Ext.create('amdaModel.TimeTable', {name : TTname, fromPlugin : true}); - this.linkedNode = Ext.create('amdaModel.TimeTableNode', { - leaf : true, - text : TTname, - nodeType : 'timeTable', - object : obj - }); - // this.linkedNode.set('id',''); - this.linkedNode.editLeaf(); - //TODO generic PRELOAD problem to fix - Ext.Function.defer(function(){ - var targetModule = myDesktopApp.getLoadedModule(this.moduleId); - if (targetModule) - { - targetModuleUI = targetModule.getUiContent(); - targetModuleUI.addInterval(this.start,this.stop); - } - this.resetStartStop(); - }, 1000, this); - } - } - else { - targetModuleUI.addInterval(this.start, this.stop); - this.resetStartStop(); - } - } - } - ] - } - ], - fbar : [ - { - text: 'Zoom In Start/Stop', - width: 100, - scope: this, - handler: function(){ - var startZoom = this.form.getForm().findField('start').getValue(); - var stopZoom = this.form.getForm().findField('stop').getValue(); - if(!startZoom || !stopZoom || !this.form.getForm().isValid()) { - myDesktopApp.warningMsg('StartTime or StopTime is incorrect'); - return; - } - - this.hostCmp.ownerCt.resetMire(); - var multiZoom = this.isMultiZoom(); - - if (multiZoom) { - var win = myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.interactive_plot.id); - var multiPlotUI = win.items.getAt(0); - var checked = multiPlotUI.checkBoxGroup.getChecked(); - - Ext.Array.each(checked,function(item, index, all){ - var id = item.name; - var winRes = myDesktopApp.getDesktop().getWindow(id); - - if (winRes) { - var panelResult = winRes.items.items[0]; - panelResult.setObjectIntoNode(); - panelResult.object.fireEvent('execute', true, 'zoom',startZoom,stopZoom); - } - }); - } - else { - this.hostCmp.ownerCt.setObjectIntoNode(); - this.hostCmp.ownerCt.object.fireEvent('execute', false, 'zoom',startZoom,stopZoom); - } - } - }, - { - text: 'Reset Zoom', - width: 100, - scope : this, - handler: function(){ - this.hostCmp.ownerCt.resetMire(); - var multiZoom = this.isMultiZoom(); - - if (multiZoom) { - var win = myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.interactive_plot.id); - var multiPlotUI = win.items.getAt(0); - var checked = multiPlotUI.checkBoxGroup.getChecked(); - - Ext.Array.each(checked,function(item, index, all){ - var id = item.name; - var winRes = myDesktopApp.getDesktop().getWindow(id); - if (winRes) { - var panelResult = winRes.items.items[0]; - panelResult.setObjectIntoNode(); - panelResult.object.fireEvent('execute', true, 'resetzoom'); - } - }); - } - else { - this.hostCmp.ownerCt.object.fireEvent('execute', false, 'resetzoom'); - } - } - } - ] - - }); - return this.form; - } -}); \ No newline at end of file diff --git a/js/app/views/PlotComponents/PlotContextManager.js b/js/app/views/PlotComponents/PlotContextManager.js index b854b6c..129d090 100644 --- a/js/app/views/PlotComponents/PlotContextManager.js +++ b/js/app/views/PlotComponents/PlotContextManager.js @@ -13,7 +13,6 @@ Ext.define('amdaPlotComp.PlotContextManager', { getPanel : function(context, xPos, yPos) { - if (!context.success) return null; @@ -35,6 +34,40 @@ Ext.define('amdaPlotComp.PlotContextManager', { return resPanel; }, + getPanelById : function(context, panelId) + { + if (!context.success) + return null; + + var resPanel = null; + Ext.each(context.page.panels, function(panel) { + if (panel.id == panelId) + { + resPanel = panel; + return; + } + }); + + return resPanel; + }, + + getPanelAxisById : function(panelContext, axisId) + { + if (!panelContext || !panelContext.plotArea) + return null; + + var resAxis = null; + Ext.each(panelContext.plotArea.axes, function(axis) { + if (axis.id == axisId) + { + resAxis = axis; + return; + } + }); + + return resAxis; + }, + isInPlotArea : function(panelContext, xPos, yPos) { if (!panelContext.plotArea) diff --git a/js/app/views/PlotComponents/PlotResultImage.js b/js/app/views/PlotComponents/PlotResultImage.js index 82eeb9e..c73f32a 100644 --- a/js/app/views/PlotComponents/PlotResultImage.js +++ b/js/app/views/PlotComponents/PlotResultImage.js @@ -18,8 +18,16 @@ Ext.define('amdaPlotComp.PlotResultImage', { onMouseMove : null, onClick : null, - verticalCursorDiv : null, - horizontalCursorDiv : null, + verticalCursor : null, + horizontalCursor : null, + + firstVerticalMarker : null, + secondVerticalMarker : null, + firstVerticalMarker : null, + secondVerticalMarker : null, + + showVerticalCursor : true, + showHorizontalCursor : true, constructor: function(config) { this.init(config); @@ -33,53 +41,137 @@ Ext.define('amdaPlotComp.PlotResultImage', { } }, - createCursor : function() { - if (this.verticalCursorDiv == null) + createNewVerticalDiv : function() { + var verticalDiv = new Ext.Element(document.createElement('div')); + verticalDiv.setStyle('position', 'absolute'); + verticalDiv.setStyle('top', '1px'); + verticalDiv.setStyle('height', '1px'); + verticalDiv.setStyle('borderLeft', '1px none rgb(0, 0, 0)'); + verticalDiv.setStyle('pointer-events', 'none'); + this.el.parent().appendChild(verticalDiv); + return verticalDiv; + }, + + createNewHorizontalDiv : function() { + var horizontalDiv = new Ext.Element(document.createElement('div')); + horizontalDiv.setStyle('position', 'absolute'); + horizontalDiv.setStyle('left', '1px'); + horizontalDiv.setStyle('width', '1px'); + horizontalDiv.setStyle('borderTop', "1px none rgb(0, 0, 0)"); + horizontalDiv.setStyle('pointer-events', 'none'); + this.el.parent().appendChild(horizontalDiv); + return horizontalDiv; + }, + + resetCursor : function() { + if (this.horizontalCursor) + this.horizontalCursor.setStyle('borderTopStyle', 'none'); + if (this.verticalCursor) + this.verticalCursor.setStyle('borderLeftStyle', 'none'); + }, + + updateCursor : function(containerX, containerY, containerWidth, containerHeight, xPos, yPos) { + if (this.horizontalCursor && this.showHorizontalCursor) { - this.verticalCursorDiv = new Ext.Element(document.createElement('div')); - this.verticalCursorDiv.setStyle('position', 'absolute'); - this.verticalCursorDiv.setStyle('top', '1px'); - this.verticalCursorDiv.setStyle('height', '1px'); - this.verticalCursorDiv.setStyle('borderLeft', '1px none rgb(0, 0, 0)'); - this.verticalCursorDiv.setStyle('pointer-events', 'none'); - this.el.parent().appendChild(this.verticalCursorDiv); + this.horizontalCursor.setStyle('left',containerX+'px'); + this.horizontalCursor.setStyle('top',yPos+'px'); + this.horizontalCursor.setStyle('width',containerWidth+'px'); + this.horizontalCursor.setStyle('borderTopStyle', 'solid'); } - - if (this.horizontalCursorDiv == null) + if (this.verticalCursor && this.showVerticalCursor) { - this.horizontalCursorDiv = new Ext.Element(document.createElement('div')); - this.horizontalCursorDiv.setStyle('position', 'absolute'); - this.horizontalCursorDiv.setStyle('left', '1px'); - this.horizontalCursorDiv.setStyle('width', '1px'); - this.horizontalCursorDiv.setStyle('borderTop', "1px none rgb(0, 0, 0)"); - this.horizontalCursorDiv.setStyle('pointer-events', 'none'); - this.el.parent().appendChild(this.horizontalCursorDiv); + this.verticalCursor.setStyle('left',xPos+'px'); + this.verticalCursor.setStyle('top',containerY+'px'); + this.verticalCursor.setStyle('height',containerHeight+'px'); + this.verticalCursor.setStyle('borderLeftStyle', 'solid'); } - this.resetCursor(); }, - resetCursor : function() { - if (this.horizontalCursorDiv) - this.horizontalCursorDiv.setStyle('borderTopStyle', 'none'); - if (this.verticalCursorDiv) - this.verticalCursorDiv.setStyle('borderLeftStyle', 'none'); + resetZoom : function() { + //This function is override during a startZoom call + }, + + stopZoom : function() { + this.showVerticalCursor = true; + this.showHorizontalCursor = true; + this.resetZoom(); + this.onClick = null; + this.resetZoom = function() {}; }, - updateCursor : function(panelX, panelY, panelWidth, panelHeight, xPos, yPos) { - if (this.horizontalCursorDiv) + startZoom : function(isHorizontal, containerPos, containerSize, onSelectFirst, onSelectSecond) { + this.resetZoom(); + + //this.showVerticalCursor = isHorizontal; + //this.showHorizontalCursor = !isHorizontal; + this.resetCursor(); + + var me = this; + var selectFirst = null; + var selectSecond = null; + + selectSecond = function(x, y) { - this.horizontalCursorDiv.setStyle('left',panelX+'px'); - this.horizontalCursorDiv.setStyle('top',yPos+'px'); - this.horizontalCursorDiv.setStyle('width',panelWidth+'px'); - this.horizontalCursorDiv.setStyle('borderTopStyle', 'solid'); - } - if (this.verticalCursorDiv) + if (isHorizontal) + { + me.secondVerticalMarker.setStyle('left',x+'px'); + me.secondVerticalMarker.setStyle('top',containerPos+'px'); + me.secondVerticalMarker.setStyle('height',containerSize+'px'); + me.secondVerticalMarker.setStyle('borderLeftStyle', 'dotted'); + if (onSelectSecond) + onSelectSecond(x); + } + else + { + me.secondHorizontalMarker.setStyle('left',containerPos+'px'); + me.secondHorizontalMarker.setStyle('top',y+'px'); + me.secondHorizontalMarker.setStyle('width',containerSize+'px'); + me.secondHorizontalMarker.setStyle('borderTopStyle', 'dotted'); + if (onSelectSecond) + onSelectSecond(y); + } + + me.onClick = selectFirst; + }; + + selectFirst = function(x, y) { - this.verticalCursorDiv.setStyle('left',xPos+'px'); - this.verticalCursorDiv.setStyle('top',panelY+'px'); - this.verticalCursorDiv.setStyle('height',panelHeight+'px'); - this.verticalCursorDiv.setStyle('borderLeftStyle', 'solid'); - } + if (isHorizontal) + { + me.secondVerticalMarker.setStyle('borderLeftStyle', 'none'); + me.firstVerticalMarker.setStyle('left',x+'px'); + me.firstVerticalMarker.setStyle('top',containerPos+'px'); + me.firstVerticalMarker.setStyle('height',containerSize+'px'); + me.firstVerticalMarker.setStyle('borderLeftStyle', 'dotted'); + if (onSelectFirst) + onSelectFirst(x); + } + else + { + me.secondHorizontalMarker.setStyle('borderLeftStyle', 'none'); + me.firstHorizontalMarker.setStyle('left',containerPos+'px'); + me.firstHorizontalMarker.setStyle('top',y+'px'); + me.firstHorizontalMarker.setStyle('width',containerSize+'px'); + me.firstHorizontalMarker.setStyle('borderTopStyle', 'dotted'); + if (onSelectFirst) + onSelectFirst(y); + } + + me.onClick = selectSecond; + }; + + this.resetZoom = function() + { + me.firstVerticalMarker.setStyle('borderLeftStyle', 'none'); + me.secondVerticalMarker.setStyle('borderLeftStyle', 'none'); + me.firstHorizontalMarker.setStyle('borderTopStyle', 'none'); + me.secondHorizontalMarker.setStyle('borderTopStyle', 'none'); + + me.resetCursor(); + me.onClick = selectFirst; + }; + + this.onClick = selectFirst; }, init : function(config) { @@ -90,11 +182,20 @@ Ext.define('amdaPlotComp.PlotResultImage', { width : config.width, height : config.height, onMouseMove : config.onMouseMove, - onClick : config.onClick, + onContextMenu : config.onContextMenu, listeners : { render : function(img, eOpts){ me.refreshMe(); - me.createCursor(); + //Create cursor + me.verticalCursor = me.createNewVerticalDiv(); + me.horizontalCursor = me.createNewHorizontalDiv(); + //Create markers (used for zoom) + me.firstVerticalMarker = me.createNewVerticalDiv(); + me.secondVerticalMarker = me.createNewVerticalDiv(); + me.firstHorizontalMarker = me.createNewHorizontalDiv(); + me.secondHorizontalMarker = me.createNewHorizontalDiv(); + + me.resetCursor(); }, el: { click: function(e, t, eOpts) { @@ -102,10 +203,19 @@ Ext.define('amdaPlotComp.PlotResultImage', { me.onClick(e.getX()-me.getPosition()[0], e.getY()-me.getPosition()[1]); }, mousemove: function(e, t, eOpts){ - me.verticalCursorDiv.setStyle('left', (e.getX()-me.getPosition()[0]-1)+"px"); - me.horizontalCursorDiv.setStyle('top', (e.getY()-me.getPosition()[1]-1)+"px"); + me.verticalCursor.setStyle('left', (e.getX()-me.getPosition()[0])+"px"); + me.horizontalCursor.setStyle('top', (e.getY()-me.getPosition()[1])+"px"); if (me.onMouseMove) me.onMouseMove(e.getX()-me.getPosition()[0], e.getY()-me.getPosition()[1]); + }, + contextmenu : function(event, t, eOpts ) { + event = event || window.event; + if (event.preventDefault) { + event.preventDefault(); + } + if (me.onContextMenu) + me.onContextMenu(event.getX(), event.getY(), event.getX()-me.getPosition()[0], event.getY()-me.getPosition()[1]); + return false; } } } diff --git a/js/app/views/PlotComponents/PlotZoomPlug.js b/js/app/views/PlotComponents/PlotZoomPlug.js new file mode 100644 index 0000000..d53d35c --- /dev/null +++ b/js/app/views/PlotComponents/PlotZoomPlug.js @@ -0,0 +1,363 @@ +/** + * Project : AMDA-NG + * Name : PlotZoomPlug.js + * @plugin amdaPlotComp.PlotZoomPlug + * @extends Ext.util.Observable + * @ptype plotZoomPlugin + * @brief Plot Zoom UI (View) + * @author Benjamin + * @version $Id: PlotZoomPlug.js + ******************************************************************************** + * FT Id : Date : Name - Description + ******************************************************************************* + * : + */ + + +Ext.define('amdaPlotComp.PlotZoomPlug', { + extend: 'Ext.util.Observable', + alias: 'plugin.plotZoomPlugin', + + ttModuleId : 'timetab-win', + + win : null, + form : null, + zoomType : '', + tabId : '', + panelId : -1, + + constructor: function(config) { + Ext.apply(this, config); + this.callParent(arguments); + }, + + onDestroy : function() { + this.win = null; + }, + + init: function(cmp) { + this.hostCmp = cmp; + }, + + setMinValue : function(min) { + if (!this.form) + return; + + if (this.zoomType == 'timeAxis') + this.form.getForm().findField('zoom-min-time').setValue(min); + else + this.form.getForm().findField('zoom-min-float').setValue(min); + }, + + setMaxValue : function(max) { + if (!this.form) + return; + + if (this.zoomType == 'timeAxis') + { + var minValue = this.form.getForm().findField('zoom-min-time').getValue(); + if (minValue <= max) + this.form.getForm().findField('zoom-max-time').setValue(max); + else + { + this.form.getForm().findField('zoom-min-time').setValue(max); + this.form.getForm().findField('zoom-max-time').setValue(minValue); + } + } + else + { + var minValue = this.form.getForm().findField('zoom-min-float').getValue(); + if (minValue <= max) + this.form.getForm().findField('zoom-max-float').setValue(max); + else + { + this.form.getForm().findField('zoom-min-float').setValue(max); + this.form.getForm().findField('zoom-max-float').setValue(minValue); + } + } + }, + +/** + * add Interval to Time table + **/ + insertInterval: function() { + if (this.zoomType != 'timeAxis') + return; + + myDesktopApp.getLoadedModule(this.ttModuleId, true, function(module){ + var targetModuleUI = targetModule.getUiContent(); + //if (targetModuleUI) + // targetModuleUI.addInterval(this.start,this.stop); + }); + }, + +/** + * creation of the window + */ + show : function(tabId, zoomType, panelId) { + if (!this.win) + { + this.win = new Ext.Window({ + id: 'plot-zoom-win-' + this.hostCmp.ownerCt.getId(), // Plot window ID + width: 250, + height: 250, + x: 0, y: 0, + baseCls:'x-panel', + title: 'Zoom', + layout: 'fit', + constrain: true, + collapsible: true, + resizable: false, + ghost: false, + renderTo: this.hostCmp.ownerCt.body, + items: this.getFormConfig(), + listeners: { + scope: this, + beforeclose: function() { + this.hostCmp.panelImage.stopZoom(); + Ext.PluginManager.unregister(this); + } + }, + getConstrainVector: function(constrainTo){ + var me = this; + if (me.constrain || me.constrainHeader) { + constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container || me.el.getScopeParent(); + return (me.constrainHeader ? me.header.el : me.el).getConstrainVector(constrainTo); + } + } + }); + + this.win.on('destroy', this.onDestroy, this); + + Ext.PluginManager.register(this); + } + + this.tabId = tabId; + this.updateWinByType(zoomType, panelId); + this.win.show(); + this.win.setPosition(0,0); + }, + + close : function() { + if (this.win == null) + return; + this.win.close(); + }, + + updateWinByType : function(zoomType, panelId) { + if (this.win == null) + return; + + this.zoomType = zoomType; + this.panelId = panelId; + + switch (zoomType) + { + case 'timeAxis': + this.win.setTitle('Zoom on time axis & Interval selection - Panel Id : '+panelId); + break; + case 'y-left' : + this.win.setTitle('Zoom on Y Left axis - Panel Id : '+panelId); + break; + case 'y-right' : + this.win.setTitle('Zoom on Y Right axis - Panel Id : '+panelId); + break; + case 'xaxis_id' : + this.win.setTitle('Zoom on X axis - Panel Id : '+panelId); + break; + } + + this.form.getForm().findField('zoom-min-time').setVisible(this.zoomType == 'timeAxis'); + this.form.getForm().findField('zoom-max-time').setVisible(this.zoomType == 'timeAxis'); + + this.form.getForm().findField('zoom-min-float').setVisible(this.zoomType != 'timeAxis'); + this.form.getForm().findField('zoom-max-float').setVisible(this.zoomType != 'timeAxis'); + + var ttNameField = this.form.getForm().findField('tt-name'); + if (ttNameField) + ttNameField.findParentByType('fieldset').setVisible(this.zoomType == 'timeAxis'); + + this.win.setHeight((this.zoomType == 'timeAxis') ? 250 : 160); + }, + + resetMinMaxValue: function() { + if (this.zoomType == 'timeAxis') + { + this.form.getForm().findField('zoom-min-time').setValue(''); + this.form.getForm().findField('zoom-max-time').setValue(''); + } + else + { + this.form.getForm().findField('zoom-min-float').setValue(null); + this.form.getForm().findField('zoom-max-float').setValue(null); + } + + this.hostCmp.panelImage.resetZoom(); + }, + +/** + * Main form + */ + getFormConfig: function(){ + + var intervalFieldSet = { + xtype: 'fieldset', + title: 'Interval Selection', + name: 'interval-selection-fieldset', + collapsible: false, + layout: { + type: 'vbox', + pack: 'start', + align: 'stretch' + }, + items : [ + { + xtype:'datefield', name:'zoom-min-time', fieldLabel: 'Start Time', + format : 'Y-m-d\\TH:i:s' + }, + { + xtype:'datefield', name:'zoom-max-time', fieldLabel: 'Stop Time', + format : 'Y-m-d\\TH:i:s' + }, + { + xtype:'numberfield', name:'zoom-min-float', fieldLabel: 'Min Value' + }, + { + xtype:'numberfield', name:'zoom-max-float', fieldLabel: 'Max Value' + }, + { + xtype: 'button', + width: 100, + text: 'Reset interval', + scope: this, + handler: function() { + this.resetMinMaxValue(); + } + } + ] + }; + + var insertTTFieldSet = { + xtype: 'fieldset', + title: 'TimeTable Insertion', + name: 'tt-insertion-fieldset', + collapsible: false, + layout: { + type: 'vbox', + pack: 'start', + align: 'stretch' + }, + items : [ + { + xtype: 'textfield', + fieldLabel: 'TimeTable Name', + name: 'tt-name', + listeners : + { + render : function(o,op) + { + var me = this; + var el = me.el; + var dropTarget = Ext.create('Ext.dd.DropTarget', el, { + ddGroup: 'explorerTree', + notifyOver : function(ddSource, e, data) + { + if ((data.records[0].data.nodeType == 'timeTable') && (data.records[0].data.leaf)) + { + this.valid = true; + return this.dropAllowed; + } + this.valid = false; + return this.dropNotAllowed; + }, + notifyDrop : function(ddSource, e, data) + { + if (!this.valid) + return false; + me.setValue(data.records[0].get('text')); + return true; + } + }); + } + } + }, + { + xtype: 'button', + width: 100, + text: 'Insert Interval', + scope: this, + handler: function(){ + if (this.zoomType != 'timeAxis') + return; + + this.start = this.form.getForm().findField('zoom-min-time').getValue(); + this.stop = this.form.getForm().findField('zoom-max-time').getValue(); + // new TimeTable or typed manually + var me = this; + var targetModule = myDesktopApp.getLoadedModule(this.ttModuleId, true, function(module) { + var targetModuleUI = module.getUiContent(); + var TTname = me.form.getForm().findField('tt-name').getValue(); + //ToDo + }); + + } + } + ] + }; + + this.form = new Ext.form.FormPanel( { + frame: true, + width: 250, + height: 250, + layout: { + type: 'vbox', + pack: 'start', + align: 'stretch' + }, + fieldDefaults: { + labelWidth: 60 + }, + items: [ + intervalFieldSet, + insertTTFieldSet + ], + fbar : [ + { + text: 'Apply Zoom', + width: 100, + scope: this, + handler: function(){ + if (this.zoomType == 'timeAxis') + { + var minZoom = this.form.getForm().findField('zoom-min-time').getValue(); + var maxZoom = this.form.getForm().findField('zoom-max-time').getValue(); + } + else + { + var minZoom = this.form.getForm().findField('zoom-min-float').getValue(); + var maxZoom = this.form.getForm().findField('zoom-max-float').getValue(); + } + + if(!maxZoom || !minZoom || !this.form.getForm().isValid()) { + myDesktopApp.warningMsg('Error in values definition'); + return; + } + + this.hostCmp.callInteractivePlot({'action' : 'zoom', 'tabId' : this.tabId, 'panelId' : this.panelId, 'axeId' : this.zoomType, 'min' : minZoom, 'max' : maxZoom}); + this.hostCmp.panelImage.resetZoom(); + } + }, + { + text: 'Undo Zoom', + width: 100, + scope : this, + handler: function(){ + this.hostCmp.callInteractivePlot({'action' : 'undozoom', 'tabId' : this.tabId, 'panelId' : this.panelId, 'axeId' : this.zoomType}); + this.hostCmp.panelImage.resetZoom(); + } + } + ] + }); + return this.form; + } +}); \ No newline at end of file diff --git a/js/app/views/PlotTabResultUI.js b/js/app/views/PlotTabResultUI.js index ab8ca77..bcf3c18 100644 --- a/js/app/views/PlotTabResultUI.js +++ b/js/app/views/PlotTabResultUI.js @@ -18,12 +18,13 @@ Ext.define('amdaUI.PlotTabResultUI', { alias: 'widget.plotTabResult', requires: [ - 'amdaUI.InteractiveIntervalPlugin', + 'amdaPlotComp.PlotZoomPlug', 'amdaPlotComp.PlotContextManager' ], panelImage : null, crtContext : null, + tabId : '', constructor: function(config) { this.addEvents({'pagesize':true}); @@ -57,6 +58,127 @@ Ext.define('amdaUI.PlotTabResultUI', { 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 me = this; + 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.tabId, axis.id, panelContext.id); + zoomPlugin.resetMinMaxValue(); + me.panelImage.startZoom(true, me.toPixelOnResultImage(panelContext.y), 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.tabId, 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.tabId, 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.tabId, 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; + } + + }); + }, + createPlotImage: function(resultFolder, plotFile) { var me = this; var size = this.getImageSize(); @@ -139,9 +261,31 @@ Ext.define('amdaUI.PlotTabResultUI', { } me.coordinatesField.setText(text); }, - onClick : function(x, y) { - //console.log('position : '+me.toPixelOnSourceImage(x)+', '+me.toPixelOnSourceImage(y)); - }, + onContextMenu : function(absoluteX, absoluteY, imageX, imageY) { + if (!me.crtContext) + return; + + me.contextualMenu.removeAll(); + + var sourceXPos = me.toPixelOnSourceImage(imageX); + var sourceYPos = me.toPixelOnSourceImage(imageY); + var panel = amdaPlotComp.PlotContextManager.getPanel(me.crtContext, sourceXPos, sourceYPos); + + if (panel != null) + { + 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 request' + }); + + me.contextualMenu.showAt(absoluteX, absoluteY); + } }); return this.panelImage; @@ -158,8 +302,38 @@ Ext.define('amdaUI.PlotTabResultUI', { this.panelImage.refreshMe(); }, + callInteractivePlot : function(obj) { + loadMask.show(true); + AmdaAction.interactivePlot(obj, function (result, e) { + loadMask.hide(); + var t = e.getTransaction(); + if (e.status) + { + if (result) + { + if (result.success) + { + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) { + module.startInteractiveSession(result); + }); + } + else + myDesktopApp.errorMsg('Interactive action error - '+result.message); + } + else + myDesktopApp.errorMsg('Cannot execute interactive action'); + } + else + { + // FAILURE + myDesktopApp.errorMsg('Error System - '+e.message); + } + },this); + }, + init: function(configResult){ this.crtContext = configResult.context; + this.tabId = configResult.tabId; this.coordinatesField = new Ext.toolbar.TextItem({ width: 300, @@ -178,7 +352,8 @@ Ext.define('amdaUI.PlotTabResultUI', { scope : this, changecomplete: function(s, v) { - //ToDo - this.resetMire(); + var zoomPlugin = this.getPlugin('plot-zoom-plugin-id'); + zoomPlugin.close(); var size = this.getImageSize(); this.panelImage.width = size.width; this.panelImage.height = size.height; @@ -188,16 +363,24 @@ Ext.define('amdaUI.PlotTabResultUI', { } }); + + 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: [] + }); var plotResultTabPanelConfig = { preventHeader : true, @@ -205,7 +388,11 @@ Ext.define('amdaUI.PlotTabResultUI', { items: [ this.createPlotImage(configResult.folder, configResult.plotFile) ], - dockedItems: [mouseToolbar] + dockedItems: [mouseToolbar], + plugins: [ { + ptype: 'plotZoomPlugin', + pluginId : 'plot-zoom-plugin-id' + }] }; Ext.apply(this , plotResultTabPanelConfig); diff --git a/php/classes/AmdaAction.php b/php/classes/AmdaAction.php index 2403fa5..2e9efab 100644 --- a/php/classes/AmdaAction.php +++ b/php/classes/AmdaAction.php @@ -1240,6 +1240,12 @@ class AmdaAction { unlink(USERDIR.$name); return array('success' => true); } + + public function interactivePlot($obj) + { + require_once(INTEGRATION_SRC_DIR."RequestManager.php"); + return $this->executeRequest($obj, FunctionTypeEnumClass::ACTION); + } } ?> diff --git a/php/config.php b/php/config.php index 5518f78..a7be0b0 100644 --- a/php/config.php +++ b/php/config.php @@ -371,6 +371,9 @@ $API = array( ), 'deleteSpecialInfo'=>array( 'len'=>1 + ), + 'interactivePlot'=>array( + 'len'=>1 ) ) ) -- libgit2 0.21.2