Commit 96e34ad166ed6909cbbb9553bd7b83f2b5ffd5fd

Authored by Benjamin Renard
2 parents 3c82b05e 641a1a72
Exists in FER_TFCat

Merge branch 'DAS2' into FER_TFCat

Showing 55 changed files with 1572 additions and 1073 deletions   Show diff stats
catalogTTList.html
... ... @@ -6,7 +6,7 @@
6 6 <link rel="stylesheet" type="text/css" href="js/lib/ext/resources/css/ext-all.css"/>
7 7 <link rel="stylesheet" type="text/css" href="js/resources/css/amda.css"/>
8 8 <script type="text/javascript" src="js/lib/ext/ext-all.js"></script>
9   - <script type="text/javascript" src="js/app/catalogTTList.js"></script>
  9 + <script type="text/javascript" src="js/app/catalogTTList.js?t=1"></script>
10 10 </head>
11 11  
12 12 <body background="js/resources/images/desktop/wallpapers/Cdpp2.jpg"/>
... ...
desktop.php
... ... @@ -41,7 +41,7 @@ if ($sessionID === FALSE) {
41 41 <!-- Important ! the order of css loading : ext-all.css - should be the first -->
42 42 <link rel="stylesheet" type="text/css" href="js/lib/ext/resources/css/ext-all.css" />
43 43 <link rel="stylesheet" type="text/css" href="js/resources/css/desktop.css" />
44   - <link rel="stylesheet" type="text/css" href="js/resources/css/amda.css" />
  44 + <link rel="stylesheet" type="text/css" href="js/resources/css/amda.css?v=2" />
45 45  
46 46 <link rel="stylesheet" href="js/lib/codemirror/codemirror-5.65.12/lib/codemirror.css">
47 47 <link rel="stylesheet" href="js/lib/codemirror/codemirror-5.65.12/addon/lint/lint.css">
... ... @@ -239,4 +239,4 @@ if ($sessionID === FALSE) {
239 239  
240 240 <body />
241 241  
242   -</html>
243 242 \ No newline at end of file
  243 +</html>
... ...
generic_data/defaultValues.json
... ... @@ -129,10 +129,18 @@
129 129 },
130 130 "histogram2D":{
131 131 "histo2DFunction":"density",
  132 + "histo2DyAxis":"y-left",
132 133 "xbinnumber":100,
133 134 "ybinnumber":100,
134 135 "smoothfactor":1
135 136 },
  137 + "histogram1D":{
  138 + "histo1DFunction":"density",
  139 + "histo1DyAxis":"y-left",
  140 + "xbinnumber":100,
  141 + "histo1DStyle":"bar",
  142 + "color":"#FF0000"
  143 + },
136 144 "sauvaud":{
137 145 "yAxis":"y-right",
138 146 "resolution":3000
... ...
generic_data/defaultValuesConfig.json
... ... @@ -38,7 +38,8 @@
38 38 { "key": "epochPlot", "value": "Epoch Plot" },
39 39 { "key": "instantPlot", "value": "Instant Plot" },
40 40 { "key": "statusPlot", "value": "Status Plot" },
41   - { "key": "tickPlot", "value": "Tick Plot" }
  41 + { "key": "tickPlot", "value": "Tick Plot" },
  42 + { "key": "histoPlot", "value": "Histogram Plot" }
42 43 ],
43 44  
44 45 "availableFontNames": [
... ... @@ -254,11 +255,28 @@
254 255 "availableHistogram2DFunctions": [
255 256 { "key": "density", "value": "Density" },
256 257 { "key": "normdensity", "value": "Normalised Density" },
257   - { "key": "mean", "value": "Mean" },
258   - { "key": "min", "value": "Minimum" },
259   - { "key": "max", "value": "Maximum" },
260   - { "key": "median", "value": "Median" },
261   - { "key": "stadev", "value": "Standard Deviation" }
  258 + { "key": "mean", "value": "Mean (of a 3rd parameter)" },
  259 + { "key": "min", "value": "Minimum (of a 3rd parameter)" },
  260 + { "key": "max", "value": "Maximum (of a 3rd parameter)" },
  261 + { "key": "median", "value": "Median (of a 3rd parameter)" },
  262 + { "key": "stadev", "value": "Std. Dev. (of a 3rd parameter) " }
  263 + ],
  264 +
  265 + "availableHistogram1DFunctions": [
  266 + { "key": "density", "value": "Density" },
  267 + { "key": "normdensity", "value": "Normalised Density" },
  268 + { "key": "mean", "value": "Mean (of a 2nd parameter)" },
  269 + { "key": "min", "value": "Minimum (of a 2nd parameter)" },
  270 + { "key": "max", "value": "Maximum (of a 2nd parameter)" },
  271 + { "key": "median", "value": "Median (of a 2nd parameter)" },
  272 + { "key": "stadev", "value": "Sta. Dev. (of a 2nd parameter)" },
  273 + { "key": "skewness", "value": "Skewness (of a 2nd parameter)" },
  274 + { "key": "kurtosis", "value": "Kurtosis (of a 2nd parameter)" }
  275 + ],
  276 +
  277 + "availableHistogram1DStyles": [
  278 + { "key": "bar", "value": "Bar-like" },
  279 + { "key": "stairs", "value": "Stair-like" }
262 280 ],
263 281  
264 282 "availableDimsOnXAxis": [
... ...
generic_data/defaultValuesLinks.json
... ... @@ -231,6 +231,26 @@
231 231 "type":"combobox",
232 232 "store":"availableHistogram2DFunctions"
233 233 },
  234 + "plot.histogram2D.histo2DyAxis":
  235 + {
  236 + "type":"combobox",
  237 + "store":"availableYAxes"
  238 + },
  239 + "plot.histogram1D.histo1DFunction":
  240 + {
  241 + "type":"combobox",
  242 + "store":"availableHistogram1DFunctions"
  243 + },
  244 + "plot.histogram1D.histo1DStyle":
  245 + {
  246 + "type":"combobox",
  247 + "store":"availableHistogram1DStyles"
  248 + },
  249 + "plot.histogram1D.histo1DyAxis":
  250 + {
  251 + "type":"combobox",
  252 + "store":"availableYAxes"
  253 + },
234 254 "plot.sauvaud.yAxis":
235 255 {
236 256 "type":"combobox",
... ...
help/catalogTTFilterHelp 0 โ†’ 100644
... ... @@ -0,0 +1,29 @@
  1 +<p>
  2 +The filter function is an only on-screen function, nothing will be saved untill you decide to save the catalog or time table. There is also a "<b><i>Clear Filters</i></b>" button at top right of the grid which will erase all filters applied on screen.<br/>
  3 +</p>
  4 +<p>
  5 +The mechanism is the same for integer and double type columns.<br/>
  6 +Once in the filter menu you will see three boxes you are able to fill:
  7 +<ul>
  8 + <li><b><i> '>'</i></b> box: returns on screen intervals where the values of the filtered column are higher than the number filled in the box.</li>
  9 + <li><b><i> '<'</i></b> box: returns on screen intervals where the values of the filtered column are lower than the number filled in the box.</li>
  10 + <li><b><i> '='</i></b> box: returns on screen intervals where the values of the filtered column are the same than the number filled in the box.</li>
  11 +</ul>
  12 +</p>
  13 +
  14 +<p>
  15 +For the filter on a string column, there is only one box. The filter will return on screen the intervals where the value of the filtered column contains the filled string of characters
  16 +</p>
  17 +
  18 +<p>
  19 +For the date filter, the boxes are self-explanatory:
  20 +<ul>
  21 + <li><b><i> 'before'</i></b> box: returns on screen intervals where the values of the filtered column are before than the date filled in the box.</li>
  22 + <li><b><i> 'after'</i></b> box: returns on screen intervals where the values of the filtered column are after than the date filled in the box.</li>
  23 + <li><b><i> 'on'</i></b> box: returns on screen intervals where the values of the filtered column are the same than the date filled in the box.</li>
  24 +</ul>
  25 +</p>
  26 +
  27 +
  28 +
  29 +
... ...
index.html
... ... @@ -106,11 +106,12 @@
106 106 <div id="PaveAnnoucements">
107 107 <div id="TitrePaveAnnoucement">Announcements</div>
108 108  
  109 +<div id="DateAnnoucement">12/03/2024</div>
  110 +<div id="TexteAnnoucement">New function histogram<br/>Juno, JUICE, Galileo M-shell from JRM33+CON2020</div>
  111 +<div id="DateAnnoucement">17/07/2023</div>
  112 +<div id="TexteAnnoucement">Juno FGM, JEDI, WAVES &amp; JADE L3: New perijoves 45-47<br/>Add Juno JADE L5 datasets: Differential Energy Flux &amp; moments<br/>Add Juno JEDI Pitch Angle Distribution</div>
  113 +
109 114 <div id="DateAnnoucement">03/08/2022</div>
110 115 <div id="TexteAnnoucement">AMDA DOI: https://doi.org/10.6096/2011</div>
111 116 <div id="DateAnnoucement">20/01/2022</div>
112 117 <div id="TexteAnnoucement">Solar Orbiter RPW, <br/>Solar Orbiter PAS: Version 2.0,<br/> Fix Cassini LEMMS data,<br/> Fix VEX orbits shared catalog,<br/>New frames available in framesTransformation function</div>
113   -<div id="DateAnnoucement">28/07/2021</div>
114   -<div id="TexteAnnoucement">New data:</br>MMS (including burst mode), <br/>VEX IMA: Version 2.0,<br/> BepiColombo Venus flybys ephemeris,<br/> PSP Venus flybys: ephemeris & data,<br/>JASON3: AMBRE</div>
115   -<div id="DateAnnoucement">28/07/2021</div>
116   -<div id="TexteAnnoucement">Fix remote access to CDAWeb</div>
... ...
js/app/AmdaApp.js
... ... @@ -478,7 +478,7 @@ Ext.define(&#39;amdaApp.AmdaApp&#39;, {
478 478 {
479 479 text : 'Workspaces',
480 480 iconCls : 'icon-ws',
481   - disabled: false,
  481 + disabled: true,
482 482 scope : this,
483 483 handler:function(obj, e){
484 484 e.stopEvent();
... ...
js/app/catalogTTList.js
... ... @@ -28,7 +28,8 @@ Ext.onReady(function () {
28 28 }
29 29 });
30 30 var presentationPanel = Ext.create('Ext.panel.Panel', {
31   - height: 80,
  31 + height: 80,
  32 + region: 'north',
32 33 layout:'hbox',
33 34 bodyStyle: { background : '#dfe8f6'},
34 35 items:[
... ... @@ -63,16 +64,16 @@ Ext.onReady(function () {
63 64 });
64 65 var grid = Ext.create('Ext.grid.Panel', {
65 66 xtype:'grouped-grid',
  67 + region: 'center',
66 68 requires: [
67 69 'Ext.grid.feature.Grouping'
68 70 ],
69   - minHeight: 200,
70 71 store: store,
71 72 features: [{
72 73 ftype: 'grouping',
73 74 groupHeaderTpl: '{columnName}: {name} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})',
74 75 hideGroupedHeader: true,
75   - startCollapsed: false,
  76 + startCollapsed: true,
76 77 id: 'typeGrouping'
77 78 }],
78 79 columns: [
... ... @@ -122,7 +123,7 @@ Ext.onReady(function () {
122 123 closable:false,
123 124 autoScroll : true,
124 125 maximizable: true,
125   - layout:'anchor',
  126 + layout: 'border',
126 127 items: [
127 128 presentationPanel,
128 129 grid
... ...
js/app/controllers/DownloadModule.js
... ... @@ -39,6 +39,10 @@ Ext.define(&#39;amdaDesktop.DownloadModule&#39;, {
39 39 var form = uiContent.down('form').getForm();
40 40 var values = form.getValues();
41 41 // Ext.state.Manager.set(this.id + '_form', values);
  42 + if (Number.isNaN(Date.parse(values.startDate)) || Number.isNaN(Date.parse(values.stopDate))) {
  43 + return;
  44 + }
  45 +
42 46 Ext.state.Manager.set('timeinterval', {'startDate' : values.startDate,'stopDate' : values.stopDate });
43 47 },
44 48  
... ...
js/app/controllers/ExplorerModule.js
... ... @@ -206,11 +206,9 @@ Ext.define(&#39;amdaDesktop.ExplorerModule&#39;,
206 206  
207 207 addLogMessage: function (message) {
208 208 var height, msg, panel, win
209   - height = 40
210 209 msg = Ext.create('Ext.Component', {
211   - height: height,
212   - html: message,
213   - style: {color: '#555555'}
  210 + html: '<div class="logMessage">'+message+'</div>',
  211 + style: {color: '#555555', marginLeft:'5px', marginBottom:'2px'}
214 212 })
215 213 win = myDesktopApp.getDesktop().getWindow(this.id)
216 214 panel = win.items.get('LogPanel')
... ...
js/app/controllers/JobsMgr.js
... ... @@ -78,7 +78,6 @@ Ext.define(&#39;amdaDesktop.JobsMgr&#39;, {
78 78 // Update from Server Jobs Running and Finished
79 79 if (res.nFinished > 0 || res.nError) {
80 80 Ext.Array.each(res.jobsFinished, function (job) {
81   - console.log(job.status)
82 81 /**
83 82 * Called asynchronously on each finished job
84 83 * @param {Job} job The finished job.
... ...
js/app/controllers/SampModule.js
... ... @@ -170,8 +170,8 @@ Ext.define(&#39;amdaDesktop.SampModule&#39;, {
170 170 showStartHubMsg : function()
171 171 {
172 172 var msg = "Cannot connect to a SAMP hub.<br/>";
173   - msg += 'You can use Java WebStart to start a JSAMP hub by just clicking here: <a href="http://astrojs.github.io/sampjs/hub/webhub.jnlp">start hub</a><br/>';
174   - msg += 'Or use internal hub included in tools like <a href="http://www.star.bris.ac.uk/~mbt/topcat/topcat-full.jnlp">TOPCAT</a> or <a href="http://aladin.u-strasbg.fr/java/nph-aladin.pl?frame=get&id=aladin.jnlp">Aladin</a>';
  173 + msg += 'You can use Java WebStart to start a JSAMP hub by just clicking here: <a href="https://astrojs.github.io/sampjs/hub/webhub.jnlp">start hub</a><br/>';
  174 + msg += 'Or use internal hub included in tools like <a href="https://www.star.bris.ac.uk/~mbt/topcat/topcat-full.jnlp">TOPCAT</a> or <a href="https://aladin.u-strasbg.fr/java/nph-aladin.pl?frame=get&id=aladin.jnlp">Aladin</a>';
175 175 myDesktopApp.errorMsg(msg);
176 176 },
177 177  
... ...
js/app/models/BkgJobNode.js
... ... @@ -174,19 +174,6 @@ Ext.define(&#39;amdaModel.BkgJobNode&#39;, {
174 174  
175 175 amdaDesktop.JobsMgr.updateStatus = null;
176 176  
177   - switch (this.get('jobType'))
178   - {
179   - case 'condition' : var type = 'Data Mining '; break;
180   - case 'request' : var type = 'Plot '; break;
181   - case 'download' : var type = 'Download '; break;
182   - case 'statistic' : var type = 'Statistics '; break;
183   - default: var type = 'unknown';
184   - }
185   -
186   - var message = Ext.Date.format(new Date(), 'd-m-Y H:i:s: ') + ': '+ type + ' '+this.get('text') + ' killed';
187   - myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id, true, function (module) {
188   - module.addLogMessage(message);
189   - });
190 177 }
191 178 //delete fieldset from Result Module if it is open
192 179 else {
... ...
js/app/models/InteractiveNode.js
... ... @@ -483,7 +483,7 @@ Ext.define(&#39;amdaModel.InteractiveNode&#39;, {
483 483 var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s.u'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s.u')};
484 484 }
485 485 else {
486   - var timeObj = {start: Ext.Date.format(startTime, 'Y/m/d H:i:s.u'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s.u')};
  486 + var timeObj = {start: Ext.Date.format(startDate, 'Y/m/d H:i:s.u'), stop: Ext.Date.format(stopDate, 'Y/m/d H:i:s.u')};
487 487 }
488 488 return timeObj;
489 489 },
... ... @@ -616,6 +616,24 @@ Ext.define(&#39;amdaModel.InteractiveNode&#39;, {
616 616 });
617 617 }
618 618 }
  619 + else {
  620 + if((this.get('nodeType') == "bkgWorks") &&
  621 + (this.get('status') == amdaModel.BkgJobNode.STATUS_LIST.IN_PROGRESS)){
  622 + switch (this.get('jobType'))
  623 + {
  624 + case 'condition' : var type = 'Data Mining '; break;
  625 + case 'request' : var type = 'Plot '; break;
  626 + case 'download' : var type = 'Download '; break;
  627 + case 'statistic' : var type = 'Statistics '; break;
  628 + default: var type = 'unknown';
  629 + }
  630 +
  631 + var message = Ext.Date.format(new Date(res.time*1000), 'Y-m-d H:i:s: ') + type + ' '+this.get('text') + ' killed';
  632 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.explorer.id, true, function (module) {
  633 + module.addLogMessage(message);
  634 + });
  635 + }
  636 + }
619 637 }
620 638 //update mask info in myData
621 639 if (res.maskDesc && !res.maskDeleted) {
... ...
js/app/models/PlotObjects/PlotHistogram1DSerieObject.js 0 โ†’ 100644
... ... @@ -0,0 +1,75 @@
  1 +/**
  2 + * Project  : TMA-AMDA
  3 + * Name : PlotHistogram1DSerieObject.js
  4 + * @class amdaPlotObj.PlotHistogram1DSerieObject
  5 + * @extends amdaPlotObj.PlotBaseSerieObject
  6 + * @brief Plot Histogram1D Business Object Definition
  7 + * @author Furkan Erdogan
  8 + * @version $Id: PlotHistogram1DSerieObject.js furkan $
  9 + ******************************************************************************
  10 + * FT Id : Date : Name - Description
  11 + ******************************************************************************
  12 + * : :08/02/2023: FER - file creation
  13 + */
  14 +
  15 +
  16 +Ext.define('amdaPlotObj.PlotHistogram1DSerieObject', {
  17 + extend: 'amdaPlotObj.PlotBaseSerieObject',
  18 + requires: ['amdaPlotObj.PlotAxisObject'],
  19 + fields : [
  20 + // {name: 'serie-xaxis-param', type: 'string'},
  21 + // {name: 'serie-resampling-mode', type: 'string'},
  22 + {name: 'histo1d-yaxis', type: 'string'},
  23 + {name: 'histo1d-function', type: 'string'},
  24 + {name: 'histotype-param', type: 'string' },
  25 + {name: 'histo1d-xbinnumber', type: 'int'},
  26 + {name: 'histo1d-style', type: 'string'},
  27 + {name: 'histo1d-color', type: 'string', defaultValue: "none"}
  28 + ],
  29 +
  30 + constructor: function(){
  31 + var me = this;
  32 + if ((arguments.length > 0) && arguments[0]) {
  33 + if (!arguments[0]['histo1d-yaxis']) {
  34 + // Compatibility mode to support old saved requests
  35 + arguments[0]['histo1d-yaxis'] = amdaDefaultValues.plot.histogram1D.histo1DyAxis;
  36 + }
  37 + if (!arguments['histo1d-style']) {
  38 + // Compatibility mode to support old saved requests
  39 + arguments[0]['histo1d-style'] = amdaDefaultValues.plot.histogram1D.histo1DStyle;
  40 + }
  41 + }
  42 + me.callParent(arguments);
  43 + },
  44 +
  45 + setDefaultValues: function()
  46 + {
  47 + // this.set('serie-xaxis-param', '');
  48 + // this.set('serie-resampling-mode', amdaDefaultValues.plot.serie.resamplingMode);
  49 + this.set('histo1d-yaxis', amdaDefaultValues.plot.histogram1D.histo1DyAxis);
  50 + this.set('histo1d-function', amdaDefaultValues.plot.histogram1D.histo1DFunction);
  51 + this.set('histotype-param', '');
  52 + this.set('histo1d-xbinnumber', amdaDefaultValues.plot.histogram1D.xbinnumber);
  53 + this.set('histo1d-style', amdaDefaultValues.plot.histogram1D.histo1DStyle);
  54 + this.set('histo1d-color', amdaDefaultValues.plot.histogram1D.color);
  55 +
  56 + this.callParent(arguments);
  57 + },
  58 +
  59 + getJsonValues : function()
  60 + {
  61 + var serieValues = this.callParent(arguments);
  62 + // serieValues['serie-xaxis-param'] = this.get('serie-xaxis-param');
  63 + // serieValues['serie-resampling-mode'] = this.get('serie-resampling-mode');
  64 + serieValues['histo1d-yaxis'] = this.get('histo1d-yaxis');
  65 + serieValues['histo1d-function'] = this.get('histo1d-function');
  66 + serieValues['histotype-param'] = this.get('histotype-param');
  67 + serieValues['histo1d-xbinnumber'] = this.get('histo1d-xbinnumber');
  68 + serieValues['histo1d-style'] = this.get('histo1d-style');
  69 + serieValues['histo1d-color'] = this.get('histo1d-color');
  70 + // serieValues['histo1D-ybinnumber'] = this.get('histo1D-ybinnumber');
  71 + // serieValues['histo1D-smoothfactor'] = this.get('histo1D-smoothfactor');
  72 +
  73 + return serieValues;
  74 + }
  75 +});
... ...
js/app/models/PlotObjects/PlotHistogram2DSerieObject.js
... ... @@ -19,6 +19,7 @@ Ext.define(&#39;amdaPlotObj.PlotHistogram2DSerieObject&#39;, {
19 19 fields : [
20 20 {name: 'serie-xaxis-param', type: 'string'},
21 21 {name: 'serie-resampling-mode', type: 'string'},
  22 + {name: 'histo2d-yaxis', type: 'string'},
22 23 {name: 'histo2d-function', type: 'string'},
23 24 {name: 'histotype-param', type: 'string' },
24 25 {name: 'histo2d-xbinnumber', type: 'int'},
... ... @@ -29,13 +30,20 @@ Ext.define(&#39;amdaPlotObj.PlotHistogram2DSerieObject&#39;, {
29 30  
30 31 constructor: function(){
31 32 var me = this;
32   - me.callParent(arguments);
  33 + if ((arguments.length > 0) && arguments[0]) {
  34 + if (!arguments[0]['histo2d-yaxis']) {
  35 + // Compatibility mode to support old saved requests
  36 + arguments[0]['histo2d-yaxis'] = amdaDefaultValues.plot.histogram2D.histo2DyAxis;
  37 + }
  38 + }
  39 + me.callParent(arguments);
33 40 },
34 41  
35 42 setDefaultValues: function()
36 43 {
37 44 this.set('serie-xaxis-param', '');
38 45 this.set('serie-resampling-mode', amdaDefaultValues.plot.serie.resamplingMode);
  46 + this.set('histo2d-yaxis', amdaDefaultValues.plot.histogram2D.histo2DyAxis);
39 47 this.set('histo2d-function', amdaDefaultValues.plot.histogram2D.histo2DFunction);
40 48 this.set('histotype-param', '');
41 49 this.set('histo2d-xbinnumber', amdaDefaultValues.plot.histogram2D.xbinnumber);
... ... @@ -50,6 +58,7 @@ Ext.define(&#39;amdaPlotObj.PlotHistogram2DSerieObject&#39;, {
50 58 var serieValues = this.callParent(arguments);
51 59 serieValues['serie-xaxis-param'] = this.get('serie-xaxis-param');
52 60 serieValues['serie-resampling-mode'] = this.get('serie-resampling-mode');
  61 + serieValues['histo2d-yaxis'] = this.get('histo2d-yaxis');
53 62 serieValues['histo2d-function'] = this.get('histo2d-function');
54 63 serieValues['histotype-param'] = this.get('histotype-param');
55 64 serieValues['histo2d-xbinnumber'] = this.get('histo2d-xbinnumber');
... ...
js/app/models/PlotObjects/PlotPanelObject.js
... ... @@ -248,6 +248,7 @@ Ext.define(&#39;amdaPlotObj.PlotPanelObject&#39;, {
248 248 recs = this.axes().add({id : 'color'});
249 249 recs[0].setDefaultValues('color');
250 250 break;
  251 + case 'histoPlot':
251 252 case 'xyPlot' :
252 253 //X Axis
253 254 var recs = this.axes().add({id : 'xaxis_id'});
... ...
js/app/models/PlotObjects/PlotParamObject.js
... ... @@ -21,6 +21,7 @@ Ext.define(&#39;amdaPlotObj.PlotParamObject&#39;, {
21 21 'amdaPlotObj.PlotSerieObject',
22 22 'amdaPlotObj.PlotOrbitSerieObject',
23 23 'amdaPlotObj.PlotHistogram2DSerieObject',
  24 + 'amdaPlotObj.PlotHistogram1DSerieObject',
24 25 'amdaPlotObj.PlotSpectroObject',
25 26 'amdaPlotObj.PlotSauvaudObject',
26 27 'amdaPlotObj.PlotStatusBarObject',
... ... @@ -75,6 +76,8 @@ Ext.define(&#39;amdaPlotObj.PlotParamObject&#39;, {
75 76 return new amdaPlotObj.PlotSerieObject(data);
76 77 case 'histogram2d' :
77 78 return new amdaPlotObj.PlotHistogram2DSerieObject(data);
  79 + case 'histogram1d' :
  80 + return new amdaPlotObj.PlotHistogram1DSerieObject(data);
78 81 case 'orbit-serie' :
79 82 return new amdaPlotObj.PlotOrbitSerieObject(data);
80 83 case 'spectro' :
... ... @@ -132,9 +135,13 @@ Ext.define(&#39;amdaPlotObj.PlotParamObject&#39;, {
132 135 case 'xyPlot' :
133 136 return [
134 137 {'key' : 'serie', 'value' : 'Serie'},
135   - {'key' : 'orbit-serie', 'value' : 'Orbit Serie'},
136   - {'key' : 'histogram2d', 'value' : '2D Histogram'}
  138 + {'key' : 'orbit-serie', 'value' : 'Orbit Serie'}
137 139 ];
  140 + case 'histoPlot' :
  141 + return [
  142 + {'key' : 'histogram1d', 'value' : '1D Histogram'},
  143 + {'key' : 'histogram2d', 'value' : '2D Histogram'}
  144 + ];
138 145 case 'instantPlot' :
139 146 return [
140 147 {'key' : 'iserie', 'value' : 'Serie'},
... ...
js/app/views/CatalogUI.js
... ... @@ -17,6 +17,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
17 17 'Ext.ux.grid.filter.DateFilter',
18 18 'Ext.ux.grid.filter.NumericFilter',
19 19 'Ext.ux.grid.filter.StringFilter',
  20 + 'amdaUI.CustomFilters',
20 21 'amdaUI.OperationsTT',
21 22 'amdaUI.DescriptionField',
22 23 'Ext.grid.plugin.BufferedRenderer',
... ... @@ -125,7 +126,9 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
125 126  
126 127 updateCount: function () {
127 128 this.object.set('nbIntervals', this.TTGrid.getStore().getTotalCount());
  129 + this.object.set('nbColumns', this.TTGrid.headerCt.getGridColumns().length-7);
128 130 this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals'));
  131 + this.formPanel.getForm().findField('nbColumns').setValue(this.object.get('nbColumns'));
129 132 },
130 133 generateTT: function () {
131 134 if (this.fclose()) {
... ... @@ -157,16 +160,10 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
157 160 updateSurveyDates : function(res){
158 161 if (this.TTGrid.getStore().getTotalCount() <= 0)
159 162 return;
160   -
161   - if(! this.object.get('surveyStart') ){
162   - this.object.set('surveyStart', res['minStart']);
163   - this.status.isModified = true;
164   - }
165   - if(! this.object.get('surveyStop') ){
166   - this.object.set('surveyStop', res['maxStop']);
167   - this.status.isModified = true;
168   - }
169   - },
  163 + this.object.set('surveyStart', res['minStart']);
  164 + this.object.set('surveyStop', res['maxStop']);
  165 + this.status.isModified = true;
  166 + },
170 167  
171 168 createTT: function (catId) {
172 169 var ttObj = Ext.create('amdaModel.TimeTable');
... ... @@ -377,7 +374,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
377 374 updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '1');
378 375 }
379 376 },
380   - filter: {type: 'numeric'}
  377 + filter: {type: 'customnumericfilter'}
381 378 },
382 379 {
383 380 xtype: 'gridcolumn',
... ... @@ -397,7 +394,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
397 394 updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '2');
398 395 }
399 396 },
400   - filter: {type: 'numeric'}
  397 + filter: {type: 'customnumericfilter'}
401 398 },
402 399 {
403 400 xtype: 'gridcolumn',
... ... @@ -417,7 +414,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
417 414 updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '3');
418 415 }
419 416 },
420   - filter: {type: 'numeric'}
  417 + filter: {type: 'customnumericfilter'}
421 418 },
422 419 {
423 420 xtype: 'gridcolumn',
... ... @@ -437,7 +434,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
437 434 updateDurationColumnsVisibility(this.ownerCt.getGridColumns(), amdaUI.CatalogUI.COL_TO_HIDE_DURATION + '4');
438 435 }
439 436 },
440   - filter: {type: 'numeric'}
  437 + filter: {type: 'customnumericfilter'}
441 438 }
442 439 ];
443 440 var pramColumnWidth = 120 * (1 - 0.7 * (1 - 1 / result.parameters.length));
... ... @@ -462,7 +459,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
462 459 xtype: 'gridcolumn',
463 460 width: pramColumnWidth * parseInt(obj.size),
464 461 editor: 'textfield',
465   - filter: {type: 'numeric', menuItemCfgs: {decimalPrecision: 10}},
  462 + filter: {type: 'customnumericfilter', menuItemCfgs: {decimalPrecision: 10}},
466 463 renderer :function(value){
467 464 return (value == "NAN") ? "nan": value;
468 465 },
... ... @@ -488,7 +485,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
488 485 hideTrigger: true,
489 486 format: 'Y-m-d\\TH:i:s.u'
490 487 },
491   - filter: {type: 'date', dateFormat: 'Y-m-d'},
  488 + filter: {type: 'customdatefilter', dateFormat: 'Y-m-d'},
492 489 renderer: function (value) {
493 490 if (value != null) {
494 491 if (Ext.isDate(value)) {
... ... @@ -510,14 +507,14 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
510 507 xtype: 'gridcolumn',
511 508 width: pramColumnWidth * parseInt(obj.size),
512 509 editor: 'textfield',
  510 + filter: {type: 'customstringfilter'},
513 511 renderer :function(value){
514 512 var renderedVal = value;
515 513 if(value.toLowerCase().startsWith("http://") ||value.toLowerCase().startsWith("https://")) {
516 514 renderedVal = '<a href="' + value + '" target="_blank">' + value +'</a>';
517 515 }
518 516 return renderedVal;
519   - },
520   - filter: {type: 'string'}
  517 + }
521 518 });
522 519 break;
523 520 case 3: //int
... ... @@ -528,7 +525,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
528 525 xtype: 'gridcolumn',
529 526 width: pramColumnWidth * parseInt(obj.size),
530 527 editor: 'textfield',
531   - filter: {type: 'numeric'}
  528 + filter: {type: 'customnumericfilter'}
532 529 });
533 530 break;
534 531 default:
... ... @@ -539,7 +536,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
539 536 xtype: 'gridcolumn',
540 537 width: pramColumnWidth * parseInt(obj.size),
541 538 editor: 'textfield',
542   - filter: {type: 'string'}
  539 + filter: {type: 'customstringfilter'}
543 540 });
544 541 }
545 542 fieldsConfig.push(field);
... ... @@ -1041,6 +1038,7 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
1041 1038  
1042 1039 init: function (config)
1043 1040 {
  1041 + amdaUI.CustomFilters.init();
1044 1042 var me = this;
1045 1043 this.object = config.object;
1046 1044 this.fieldName = new Ext.form.field.Text({
... ... @@ -1342,11 +1340,13 @@ Ext.define(&#39;amdaUI.CatalogUI&#39;, {
1342 1340 layout: 'hbox',
1343 1341 items: [{
1344 1342 xtype: 'datefield', fieldLabel: 'Creation date',
1345   - name: 'created', disabled: true,
  1343 + name: 'created', disabled: true,flex:8,
1346 1344 hideTrigger: true, format: 'Y/m/d H:i:s'
1347 1345 },
1348 1346 {xtype: 'splitter'},
1349   - {xtype: 'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', disabled: true}
  1347 + {xtype: 'textfield', fieldLabel: 'Intervals', name: 'nbIntervals', flex:5, disabled: true},
  1348 + {xtype: 'splitter'},
  1349 + {xtype: 'textfield', fieldLabel: '# Col.', name: 'nbColumns',flex:3, disabled: true}
1350 1350 ]
1351 1351 },
1352 1352 {
... ...
js/app/views/CustomFilters.js 0 โ†’ 100644
... ... @@ -0,0 +1,40 @@
  1 +// File: CustomFilters.js
  2 +
  3 +Ext.define('amdaUI.CustomFilters', {
  4 + singleton: true, // Ensure only one instance is created
  5 +
  6 + init: function () {
  7 + this.initCustomFilter('Numeric', 'NumericFilter', 'numericfilter');
  8 + this.initCustomFilter('Date', 'DateFilter', 'datefilter');
  9 + this.initCustomFilter('String', 'StringFilter', 'stringfilter');
  10 + },
  11 +
  12 + initCustomFilter: function (filterName, filterClass, aliasSuffix) {
  13 + Ext.define('amdaUI.Custom' + filterName + 'Filter', {
  14 + extend: 'Ext.ux.grid.filter.' + filterClass,
  15 + alias: 'gridfilter.custom' + aliasSuffix,
  16 +
  17 + helpTitle: 'Help on ' + filterName + ' filter',
  18 + helpFile: 'catalogTTFilterHelp',
  19 +
  20 + init: function () {
  21 + var me = this;
  22 + this.callParent(); // Ensure parent initialization
  23 +
  24 + // Add custom help menu item
  25 + this.menu.add(Ext.create('Ext.menu.Item', {
  26 + text: 'Help on filters',
  27 + iconCls: 'icon-help',
  28 + listeners: {
  29 + click: function (item, e, eOpts) {
  30 + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.info.id, true, function (module) {
  31 + module.createWindow(me.helpFile, me.helpTitle);
  32 + });
  33 + }
  34 + }
  35 + }));
  36 + }
  37 + });
  38 + }
  39 +});
  40 +
... ...
js/app/views/ParamArgumentsUI.js
... ... @@ -63,12 +63,23 @@ Ext.define(&#39;amdaUI.ParamArgumentsUI&#39;, {
63 63 }
64 64 if (paramRequestObject.get('type') == 2) {
65 65 //Tab2D
  66 + var dim1RelatedTable = me.getRelatedTableFromDim('dim1', paramInfo.data.tables);
66 67 var dim2RelatedTable = me.getRelatedTableFromDim('dim2', paramInfo.data.tables);
67   - if (!dim2RelatedTable.variable) {
68   - paramRequestObject.set('dim2-index', 0);
  68 + if (!dim2RelatedTable.mainDim) {
  69 + if (!dim2RelatedTable.variable) {
  70 + paramRequestObject.set('dim2-index', 0);
  71 + }
  72 + else {
  73 + paramRequestObject.set('dim2-sum-type', 1);
  74 + }
69 75 }
70 76 else {
71   - paramRequestObject.set('dim2-sum-type', 1);
  77 + if (!dim1RelatedTable.variable) {
  78 + paramRequestObject.set('dim1-index', 0);
  79 + }
  80 + else {
  81 + paramRequestObject.set('dim1-sum-type', 1);
  82 + }
72 83 }
73 84 }
74 85 }
... ...
js/app/views/ParameterUI.js
... ... @@ -462,7 +462,7 @@ Ext.define(&#39;amdaUI.ParameterUI&#39;,
462 462 this.samplingDefContainer,
463 463 {
464 464 itemId: 'formParamUnit',
465   - fieldLabel: 'Units',
  465 + fieldLabel: 'Unit',
466 466 name: 'units',
467 467 width: 150
468 468 },
... ...
js/app/views/PlotComponents/PlotHistogram1DSerieForm.js 0 โ†’ 100644
... ... @@ -0,0 +1,114 @@
  1 +/**
  2 + * Project  : TMA-AMDA
  3 + * Name : PlotHistogram1DSerieForm.js
  4 + * @class amdaPlotComp.PlotHistogram1DSerieForm
  5 + * @extends amdaPlotComp.PlotBaseSerieForm
  6 + * @brief Form to define specifics histogram1d serie options
  7 + * @author Furkan Erdogan
  8 + * @version $Id: PlotHistogram1DSerieForm.js furkan $
  9 + */
  10 +
  11 +Ext.define('amdaPlotComp.PlotHistogram1DSerieForm', {
  12 + extend: 'amdaPlotComp.PlotBaseSerieForm',
  13 +
  14 + setObject: function (object) {
  15 + this.callParent(arguments);
  16 + this.updateOptions(this.object.get('histo1d-function'));
  17 + },
  18 +
  19 + setParentObject: function (parentObject) {
  20 + this.callParent(arguments);
  21 + this.updateAxesRanges(parentObject);
  22 +
  23 + },
  24 + updateOptions: function(functionType) {
  25 + var isDensity = (functionType == 'density') || (functionType == 'normdensity');
  26 +
  27 + var yParamField = this.getForm().findField('histotype-param');
  28 + yParamField.setVisible(!isDensity)
  29 + },
  30 + updateAxesRanges: function(parentObject) {
  31 + var xAxisObj = parentObject.axes().getById('xaxis_id');
  32 +
  33 + this.getForm().findField('histo1d-xmin').setValue(xAxisObj.get('axis-range-min'));
  34 + this.getForm().findField('histo1d-xmax').setValue(xAxisObj.get('axis-range-max'));
  35 + },
  36 +
  37 + getRangeForms: function(){
  38 + var me = this;
  39 + return {
  40 + xtype: 'fieldset',
  41 + bodyStyle: { background: '#dfe8f6' },
  42 + title: 'X ranges',
  43 + name: 'histo1d-ranges',
  44 + renderTo: Ext.getBody(),
  45 + fieldDefaults: {
  46 + labelAlign: 'right',
  47 + msgTarget: 'side',
  48 + labelWidth: 40,
  49 + },
  50 + defaults: {
  51 + xtype: 'panel',
  52 + bodyStyle: {background: '#dfe8f6'},
  53 + flex: 1,
  54 + border:false,
  55 + layout: 'anchor',
  56 + },
  57 + layout:'hbox',
  58 + frame: true,
  59 + //bodyPadding: '5 5 5 5',
  60 + items:
  61 + [
  62 + {
  63 + items:[
  64 + me.addStandardFloat2('histo1d-xmin', 'X Min', -Number.MAX_VALUE, Number.MAX_VALUE, false, false, function(name, newValue, oldValue){
  65 + me.parentObject.axes().getById('xaxis_id').set('axis-range-min', newValue);
  66 + })
  67 + ]
  68 + },
  69 + {
  70 + items:[
  71 + me.addStandardFloat2('histo1d-xmax', 'X Max', -Number.MAX_VALUE, Number.MAX_VALUE, false, false, function(name, newValue, oldValue){
  72 + me.parentObject.axes().getById('xaxis_id').set('axis-range-max', newValue);
  73 + })
  74 + ]
  75 + }]
  76 + };
  77 +
  78 + },
  79 + getFormItems: function() {
  80 + var me = this;
  81 +
  82 + var histogram1DItems = [
  83 +
  84 + this.addStandardCombo('histo1d-yaxis', 'Y axis', amdaDefaultConfigs.availableYAxes, function (name, value, oldValue) {
  85 + me.object.set('histo1d-yaxis', value);
  86 + me.crtTree.refresh();
  87 + }),
  88 +
  89 + this.addStandardCombo('histo1d-style', 'Drawing Style', amdaDefaultConfigs.availableHistogram1DStyles, function(name, value, oldValue) {
  90 + me.object.set('histo1d-style', value);
  91 + }),
  92 + // this.addStandardParamDropTarget('serie-xaxis-param', 'X Parameter', function(name, value, oldValue) {
  93 + // me.object.set('serie-xaxis-param', value);
  94 + // me.crtTree.refresh();
  95 + // }),
  96 + me.getRangeForms(),
  97 + // this.addStandardCombo('serie-resampling-mode', 'Reference parameter for resampling', amdaDefaultConfigs.availableResamplingModes),
  98 +
  99 + this.addStandardCombo('histo1d-function', 'Function to apply', amdaDefaultConfigs.availableHistogram1DFunctions, function(name, value, oldValue) {
  100 + me.object.set('histo1d-function', value);
  101 + me.updateOptions(value);
  102 + }),
  103 + this.addStandardParamDropTarget('histotype-param', 'Y Parameter', function(name, value, oldValue) {
  104 + me.object.set('histotype-param', value);
  105 + me.crtTree.refresh();
  106 + }),
  107 +
  108 + this.addStandardInteger('histo1d-xbinnumber', 'Nb. of bins'),
  109 + this.addColorsPicker('histo1d-color', 'Color', amdaDefaultConfigs.availableColorsNew, 'none')
  110 +
  111 + ];
  112 + return histogram1DItems;
  113 + }
  114 +});
... ...
js/app/views/PlotComponents/PlotHistogram2DSerieForm.js
... ... @@ -95,6 +95,31 @@ Ext.define(&#39;amdaPlotComp.PlotHistogram2DSerieForm&#39;, {
95 95 me.object.set('serie-xaxis-param', value);
96 96 me.crtTree.refresh();
97 97 }),
  98 +
  99 + this.addStandardCombo('histo2d-yaxis', 'Y axis', amdaDefaultConfigs.availableYAxes, function (name, value, oldValue) {
  100 + me.object.set('histo2d-yaxis', value);
  101 + var yMinForm = me.getForm().findField('histo2d-ymin');
  102 + var yMaxForm = me.getForm().findField('histo2d-ymax');
  103 + yMaxForm.on('change', function(name, newValue, oldValue){
  104 + me.parentObject.axes().getById(value).set('axis-range-max', newValue);
  105 + if(value === 'y-left')
  106 + me.parentObject.axes().getById('y-right').set('axis-range-max','');
  107 + else if (value === 'y-right')
  108 + me.parentObject.axes().getById('y-left').set('axis-range-max','');
  109 + });
  110 + yMinForm.on('change', function(name, newValue, oldValue){
  111 + me.parentObject.axes().getById(value).set('axis-range-min', newValue);
  112 + if(value === 'y-left')
  113 + me.parentObject.axes().getById('y-right').set('axis-range-min','');
  114 + else if (value === 'y-right')
  115 + me.parentObject.axes().getById('y-left').set('axis-range-min','');
  116 + });
  117 + if(me.parentObject){
  118 + yMinForm.fireEvent('change', yMinForm, yMinForm.getValue(), yMinForm.getValue());
  119 + yMaxForm.fireEvent('change', yMaxForm, yMaxForm.getValue(), yMaxForm.getValue());
  120 + }
  121 + me.crtTree.refresh();
  122 + }),
98 123 me.getRangeForms(),
99 124 this.addStandardCombo('serie-resampling-mode', 'Reference parameter for resampling', amdaDefaultConfigs.availableResamplingModes),
100 125 this.addStandardCombo('histo2d-function', 'Function to apply', amdaDefaultConfigs.availableHistogram2DFunctions, function(name, value, oldValue) {
... ...
js/app/views/PlotComponents/PlotParamForm.js
... ... @@ -15,6 +15,7 @@ Ext.define(&#39;amdaPlotComp.PlotParamForm&#39;, {
15 15 'amdaPlotComp.PlotSerieForm',
16 16 'amdaPlotComp.PlotOrbitSerieForm',
17 17 'amdaPlotComp.PlotHistogram2DSerieForm',
  18 + 'amdaPlotComp.PlotHistogram1DSerieForm',
18 19 'amdaPlotComp.PlotSpectroForm',
19 20 'amdaPlotComp.PlotSauvaudForm',
20 21 'amdaPlotComp.PlotStatusBarForm',
... ... @@ -67,6 +68,9 @@ Ext.define(&#39;amdaPlotComp.PlotParamForm&#39;, {
67 68 case 'histogram2d':
68 69 this.drawingOptionsFormsManager.register(new amdaPlotComp.PlotHistogram2DSerieForm({ id: formId }));
69 70 break;
  71 + case 'histogram1d':
  72 + this.drawingOptionsFormsManager.register(new amdaPlotComp.PlotHistogram1DSerieForm({ id: formId }));
  73 + break;
70 74 case 'sauvaud':
71 75 if(this.object.get('type') !=2){
72 76 myDesktopApp.warningMsg('Sauvaud Plot requires <b>2D Parameter</b> ');
... ...
js/app/views/PlotComponents/PlotPreviewUI.js
... ... @@ -24,6 +24,7 @@ Ext.define(&#39;amdaPlotComp.PlotPreviewUI&#39;, {
24 24 ],
25 25  
26 26 isPlotFunction: false,
  27 + disableDownloadingData:false,
27 28 panelImage: null,
28 29 crtContext: null,
29 30 sliderPage: null,
... ... @@ -148,7 +149,7 @@ Ext.define(&#39;amdaPlotComp.PlotPreviewUI&#39;, {
148 149  
149 150 updatePlotImage: function (configResult, newPlot) {
150 151 this.crtContext = configResult.context;
151   - this.isPlotFunction = configResult.plotFile.includes("plotFunction");
  152 + this.isPlotFunction = configResult.plotFile.includes("plotFunction") || configResult.plotFile.includes("histoPlot");
152 153 this.interactiveId = configResult.interactiveId;
153 154 this.panelId = configResult.panelId;
154 155 this.folder = configResult.folder;
... ... @@ -176,7 +177,9 @@ Ext.define(&#39;amdaPlotComp.PlotPreviewUI&#39;, {
176 177 this.time = new Date(configResult.time);
177 178 this.time = Ext.Date.add(this.time, Ext.Date.MINUTE, this.time.getTimezoneOffset());
178 179 this.panelId = configResult.panelId;
179   - this.isPlotFunction = configResult.plotFile.includes("plotFunction");
  180 + //Solution temporaire
  181 + this.isPlotFunction = configResult.plotFile.includes("plotFunction") || configResult.plotFile.includes("histoPlot");
  182 + this.disableDownloadingData = configResult.plotFile.includes("histoPlot");
180 183 this.plotFile = configResult.plotFile;
181 184  
182 185 this.coordinatesField = new Ext.toolbar.TextItem({
... ... @@ -271,7 +274,7 @@ Ext.define(&#39;amdaPlotComp.PlotPreviewUI&#39;, {
271 274 dock: 'top',
272 275 items: [
273 276 this.gotoDateGroup,
274   - this.downloadDataBtn,
  277 + me.disableDownloadingData ? null: this.downloadDataBtn,
275 278 ]
276 279 }
277 280 var mouseToolbar = {
... ...
js/app/views/PlotComponents/PlotZoomPlug.js
... ... @@ -10,498 +10,125 @@
10 10 ********************************************************************************
11 11 * FT Id : Date : Name - Description
12 12 *******************************************************************************
13   - * :
14 13 */
15 14  
16   -
  15 +// Define a new class 'amdaPlotComp.PlotZoomPlug' that extends 'Ext.util.Observable'
17 16 Ext.define('amdaPlotComp.PlotZoomPlug', {
18 17 extend: 'Ext.util.Observable',
19 18 alias: 'plugin.plotZoomPlugin',
20   - requires: [
21   - 'amdaPlotComp.plotFunction.ParamField', 'amdaPlotComp.plotFunction.FunctionType', 'amdaPlotComp.plotFunction.CreatePlot'],
22   -
23   - //id: 'plot-zoom-plug',
24   -
25   - ttModuleId: 'timetab-win',
26   - catModuleId: 'catalog-win',
  19 + requires: ['amdaPlotComp.intervalSelection.IntervalSelection'],
27 20  
28   - win: null,
29   - form: null,
30   - zoomType: '',
31   - interactiveId: '',
32   - panelId: -1,
33   -
34   - linkedTTCatNode: null,
35   - /**
36   - * Un composant de 'PlotFunction' qui permet d'afficher le min samplig de chaque paramรจtre et le nombre de points thรฉoriques entre un start time et stop time
37   - */
38   - plotFunctionParamField: null,
39   - /**
40   - * Un composant de 'PlotFunction' qui permet ร  l'utilisateur de sรฉlรฉctionner le type de fonction ร  appliquer : FFT, SUM, ...
41   - */
42   - plotFunctionType: null,
  21 + // Declare a variable to hold the interval selection component
  22 + intervalSelectionCmp: null,
43 23  
  24 + // Constructor function for the class
44 25 constructor: function (config) {
  26 + // Apply the configuration to this instance and call the parent class's constructor
45 27 Ext.apply(this, config);
46 28 this.callParent(arguments);
47 29 },
48 30  
  31 + // Function to be called when the object is destroyed
49 32 onDestroy: function () {
50   - this.win = null;
  33 + // Set the interval selection component to null
  34 + this.intervalSelectionCmp = null;
51 35 },
52 36  
  37 + // Initialization function for the class
53 38 init: function (cmp) {
  39 + // Set the host component for this instance
54 40 this.hostCmp = cmp;
55 41 },
56 42  
57   - /**
58   - * Set different parameters displayed on the current panel
59   - * @param {*} listParams_ parameters displayed on the current panel
60   - */
61   - /*setParameters: function (listParams_) {
62   - this.listParams = listParams_;
63   - //this.plotFunctionParamField = new amdaPlotComp.plotFunction.ParamField({ params: this.listParams });
64   - this.plotFunctionType = new amdaPlotComp.plotFunction.FunctionType({});
65   - },*/
66   -
67   -
  43 + // Function to set the minimum value of the interval selection component
68 44 setMinValue: function (min) {
69   - if (!this.form)
  45 + if (!this.intervalSelectionCmp)
70 46 return;
71   -
72   - if (this.zoomType == 'timeAxis') {
73   - this.form.getForm().findField('zoom-min-time').setValue(min);
74   -
75   - }
76   - else
77   - this.form.getForm().findField('zoom-min-float').setValue(min);
  47 + this.intervalSelectionCmp.setField1Value(min);
78 48 },
79 49  
  50 + // Function to set the maximum value of the interval selection component
80 51 setMaxValue: function (max) {
81   - if (!this.form)
82   - return;
83   -
84   - if (this.zoomType == 'timeAxis') {
85   - var minValue = this.form.getForm().findField('zoom-min-time').getValue();
86   - if (minValue <= max) {
87   - this.form.getForm().findField('zoom-max-time').setValue(max);
88   - //if (this.isPlotFunction)
89   - //this.plotFunctionParamField.setValues(minValue, max);
90   - }
91   - else {
92   - this.form.getForm().findField('zoom-min-time').setValue(max);
93   - this.form.getForm().findField('zoom-max-time').setValue(minValue);
94   - // if (this.isPlotFunction)
95   - // this.plotFunctionParamField.setValues(max, minValue);
96   - }
97   - }
98   - else {
99   - var minValue = this.form.getForm().findField('zoom-min-float').getValue();
100   - if (minValue <= max)
101   - this.form.getForm().findField('zoom-max-float').setValue(max);
102   - else {
103   - this.form.getForm().findField('zoom-min-float').setValue(max);
104   - this.form.getForm().findField('zoom-max-float').setValue(minValue);
105   - }
106   - }
107   - },
108   -
109   - /**
110   - * add Interval to Time table
111   - **/
112   - insertInterval: function () {
113   - if (this.zoomType != 'timeAxis')
  52 + if (!this.intervalSelectionCmp)
114 53 return;
115   -
116   - var start = this.form.getForm().findField('zoom-min-time').getValue();
117   - var stop = this.form.getForm().findField('zoom-max-time').getValue();
118   -
119   - var TTCatType = this.form.getForm().findField('ttcat-type').getValue();
120   - var isCatalog = (TTCatType == 'catalog');
121   -
122   - myDesktopApp.getLoadedModule(isCatalog ? this.catModuleId : this.ttModuleId, true, function (module) {
123   - var targetModuleUI = module.getUiContent();
124   - if (targetModuleUI)
125   - targetModuleUI.addInterval(start, stop);
126   - });
  54 + this.intervalSelectionCmp.setField2Value(max);
127 55 },
128 56  
129 57 /**
130   - * creation of the window
  58 + * Function to create and show a window with specific configuration
131 59 */
132   - show: function (interactiveId, zoomType, panelId, isPlotFunction_ = false) {
133   - this.isPlotFunction = isPlotFunction_;
134   - if (this.win) { this.close() };
135   - this.win = new Ext.Window({
136   - id: 'plot-zoom-win-' + this.hostCmp.ownerCt.getId(), // Plot window ID
137   - width: 250,
138   - x: 0, y: 0,
139   - baseCls: 'x-panel',
140   - title: 'Zoom',
141   - constrain: true,
142   - collapsible: true,
143   - resizable: false,
144   - ghost: false,
145   - renderTo: this.hostCmp.ownerCt.body,
146   - items: this.getFormConfig(),
147   - listeners: {
148   - scope: this,
149   - beforeclose: function () {
150   - this.hostCmp.panelImage.hidePanelMarker();
151   - this.hostCmp.panelImage.stopZoom();
152   - },
153   - show: function(win, eOpts) {
154   - this.hostCmp.panelImage.showPanelMarker(panelId);
155   - }
  60 + show: function (interactiveId, zoomType, panelId, panelContext) {
  61 + let config = {
  62 + id: 'plot-zoom-win-' + this.hostCmp.ownerCt.getId(),
  63 + interactiveId: interactiveId,
  64 + panelId: panelId,
  65 + panelContext: panelContext,
  66 + hostCmp: this.hostCmp,
  67 + renderTo: this.hostCmp.ownerCt.body,
  68 + listeners: {
  69 + scope: this,
  70 + beforeclose: function () {
  71 + this.hostCmp.panelImage.hidePanelMarker();
  72 + this.hostCmp.panelImage.stopZoom();
156 73 },
157   - getConstrainVector: function (constrainTo) {
158   - var me = this;
159   - if (me.constrain || me.constrainHeader) {
160   - constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container || me.el.getScopeParent();
161   - return (me.constrainHeader ? me.header.el : me.el).getConstrainVector(constrainTo);
162   - }
  74 + show: function (win, eOpts) {
  75 + this.hostCmp.panelImage.showPanelMarker(panelId);
163 76 }
164   - });
165   -
166   - this.win.on('destroy', this.onDestroy, this);
167   -
168   - this.interactiveId = interactiveId;
169   - this.updateWinByType(zoomType, panelId);
170   - this.win.show();
171   - this.win.setPosition(0, 0);
172   - },
173   -
174   - close: function () {
175   - if (this.win == null)
176   - return;
177   - this.win.close();
178   - },
  77 + },
  78 + getConstrainVector: function (constrainTo) {
  79 + const self = this;
  80 + if (self.constrain || self.constrainHeader) {
  81 + constrainTo = constrainTo || (self.floatParent && self.floatParent.getTargetEl()) || self.container || self.el.getScopeParent();
  82 + return (self.constrainHeader ? self.header.el : self.el).getConstrainVector(constrainTo);
  83 + }
  84 + }
  85 + };
179 86  
180   - updateWinByType: function (zoomType, panelId) {
181   - if (this.win == null)
182   - return;
  87 + if (this.intervalSelectionCmp) { this.close() };
183 88  
184   - this.zoomType = zoomType;
185   - this.panelId = panelId;
  89 + let intervalSelectionCmpType;
186 90  
187 91 switch (zoomType) {
188 92 case 'timeAxis':
189   - if (this.isPlotFunction) {
190   - const title = "Apply a Fct on Interval";
191   - this.win.setTitle(title + '-Panel Id: ' + panelId);
192   - } else {
193   - this.win.setTitle('Zoom on time axis & Interval selection - Panel Id : ' + panelId);
194   - }
  93 + intervalSelectionCmpType = 'amdaPlotComp.intervalSelection.DateZoomIntervalSelection';
195 94 break;
196 95 case 'y-left':
197   - this.win.setTitle('Zoom on Y Left axis - Panel Id : ' + panelId);
198   - break;
199 96 case 'y-right':
200   - this.win.setTitle('Zoom on Y Right axis - Panel Id : ' + panelId);
201   - break;
202 97 case 'xaxis_id':
203   - this.win.setTitle('Zoom on X axis - Panel Id : ' + panelId);
  98 + intervalSelectionCmpType = 'amdaPlotComp.intervalSelection.NumberZoomIntervalSelection';
  99 + let title = "";
  100 + if (zoomType === 'y-left') {
  101 + title = 'Zoom on Y Left axis';
  102 + } else if (zoomType === 'y-right') {
  103 + title = 'Zoom on Y Right axis';
  104 + } else {
  105 + title = 'Zoom on X axis';
  106 + }
  107 + config["type"] = zoomType;
  108 + config["title"] = title;
  109 + break;
  110 + case 'plotFunction':
  111 + intervalSelectionCmpType = 'amdaPlotComp.intervalSelection.PlotFunctionIntervalSelection';
204 112 break;
205 113 }
206 114  
207   - this.form.getForm().findField('zoom-min-time').setVisible(this.zoomType == 'timeAxis');
208   - this.form.getForm().findField('zoom-max-time').setVisible(this.zoomType == 'timeAxis');
209   -
210   - this.form.getForm().findField('zoom-min-float').setVisible(this.zoomType != 'timeAxis');
211   - this.form.getForm().findField('zoom-max-float').setVisible(this.zoomType != 'timeAxis');
212   -
213   - var ttCatNameField = this.form.getForm().findField('ttcat-name');
214   - if (ttCatNameField)
215   - ttCatNameField.findParentByType('fieldset').setVisible(this.zoomType == 'timeAxis');
  115 + // Create a new instance of the interval selection component with the specified type and configuration
  116 + this.intervalSelectionCmp = Ext.create(intervalSelectionCmpType, config);
  117 + // Add a listener for the destroy event of the interval selection component
  118 + this.intervalSelectionCmp.on('destroy', this.onDestroy, this);
  119 + // Show the interval selection component
  120 + this.intervalSelectionCmp.show();
216 121 },
217 122  
218   - resetMinMaxValue: function () {
219   - if (this.zoomType == 'timeAxis') {
220   - this.form.getForm().findField('zoom-min-time').setValue('');
221   - this.form.getForm().findField('zoom-max-time').setValue('');
222   - }
223   - else {
224   - this.form.getForm().findField('zoom-min-float').setValue(null);
225   - this.form.getForm().findField('zoom-max-float').setValue(null);
226   - }
227   -
228   - this.hostCmp.panelImage.resetZoom();
229   - },
230   - setTimePlot: function () {
231   - var timeObj = new Object();
232   - timeObj.start = this.form.getForm().findField('zoom-min-time').getValue();
233   - timeObj.stop = this.form.getForm().findField('zoom-max-time').getValue();
234   - timeObj.interactiveId = this.interactiveId;
235   - var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id);
236   - plotModule.setTimeInterval(timeObj);
237   - },
238   - /**
239   - * Main form
240   - */
241   - getFormConfig: function () {
242   - var intervalFieldSet = {
243   - xtype: 'fieldset',
244   - title: 'Interval Selection',
245   - name: 'interval-selection-fieldset',
246   - collapsible: false,
247   - layout: {
248   - type: 'vbox',
249   - pack: 'start',
250   - align: 'stretch'
251   - },
252   - items: [
253   - {
254   - xtype: 'datefield', name: 'zoom-min-time', fieldLabel: 'Start Time',
255   - format: 'Y/m/d H:i:s.u',
256   - },
257   - {
258   - xtype: 'datefield', name: 'zoom-max-time', fieldLabel: 'Stop Time',
259   - format: 'Y/m/d H:i:s.u'
260   - },
261   - {
262   - xtype: 'numberfield', name: 'zoom-min-float', fieldLabel: 'Min Value'
263   - },
264   - {
265   - xtype: 'numberfield', name: 'zoom-max-float', fieldLabel: 'Max Value'
266   - },
267   - {
268   - xtype: 'button',
269   - width: 100,
270   - text: 'Reset',
271   - scope: this,
272   - handler: function () {
273   - this.resetMinMaxValue();
274   - }
275   - },
276   - {
277   - xtype: 'button',
278   - width: 100,
279   - text: 'Use in Time Selection',
280   - scope: this,
281   - handler: function () {
282   - this.setTimePlot();
283   - }
284   - }
285   - ]
286   - };
287   -
288   - var insertTypeStore = Ext.create('Ext.data.Store', {
289   - fields: ['key', 'name'],
290   - data: [
291   - { "key": "timeTable", "name": "TimeTable" },
292   - { "key": "catalog", "name": "Catalog" }
293   - ]
294   - });
295   -
296   - var me = this;
297   - this.insertTTFieldSet = {
298   - xtype: 'fieldset',
299   - title: 'Add in Time Table or Catalog',
300   - name: 'tt-insertion-fieldset',
301   - collapsible: false,
302   - layout: {
303   - type: 'vbox',
304   - pack: 'start',
305   - align: 'stretch'
306   - },
307   - items: [
308   - {
309   - xtype: 'combo',
310   - fieldLabel: 'Insert In',
311   - store: insertTypeStore,
312   - queryMode: 'local',
313   - displayField: 'name',
314   - valueField: 'key',
315   - editable: false,
316   - value: 'timeTable',
317   - name: 'ttcat-type'
318   - },
319   - {
320   - xtype: 'textfield',
321   - fieldLabel: 'Name',
322   - name: 'ttcat-name',
323   - listeners:
324   - {
325   - render: function (o, op) {
326   - var field = this;
327   - var el = this.el;
328   - var dropTarget = Ext.create('Ext.dd.DropTarget', el, {
329   - ddGroup: 'explorerTree',
330   - notifyOver: function (ddSource, e, data) {
331   - var TTCatType = me.form.getForm().findField('ttcat-type').getValue();
332   - if (data.records[0].data.leaf && (data.records[0].data.nodeType == TTCatType)) {
333   - this.valid = true;
334   - return this.dropAllowed;
335   - }
336   - this.valid = false;
337   - return this.dropNotAllowed;
338   - },
339   - notifyDrop: function (ddSource, e, data) {
340   - if (!this.valid)
341   - return false;
342   - field.setValue(data.records[0].get('text'));
343   - return true;
344   - }
345   - });
346   - }
347   - }
348   - },
349   - {
350   - xtype: 'button',
351   - width: 100,
352   - text: 'Insert Interval',
353   - scope: this,
354   - handler: function () {
355   - var me = this;
356   -
357   - var TTCatType = this.form.getForm().findField('ttcat-type').getValue();
358   - var TTCatName = this.form.getForm().findField('ttcat-name').getValue();
359   -
360   - var isCatalog = (TTCatType == 'catalog');
361   - myDesktopApp.getLoadedModule(isCatalog ? this.catModuleId : this.ttModuleId, true, function (module) {
362   - var targetModuleUI = module.getUiContent();
363   - if (me.linkedTTCatNode && (me.linkedTTCatNode.get('text') == TTCatName) && (me.linkedTTCatNode.get('nodeType') == TTCatType)) {
364   - if (targetModuleUI)
365   - me.insertInterval();
366   - else {
367   - me.linkedTTCatNode.editLeaf(function () {
368   - me.insertInterval();
369   - });
370   - }
371   - }
372   - else {
373   - var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
374   - var ttCatRootNode = explorerTree.getRootNode().findChild('id', isCatalog ? 'catalog-treeRootNode' : 'timeTable-treeRootNode', true);
375   - amdaModel.InteractiveNode.preloadNodes(ttCatRootNode, function () {
376   - var nodeWithSameName = null;
377   -
378   - if (TTCatName != '')
379   - nodeWithSameName = ttCatRootNode.findChild('text', TTCatName, true);
380   -
381   - if (nodeWithSameName !== null)
382   - me.linkedTTCatNode = nodeWithSameName;
383   - else {
384   - module.createLinkedNode();
385   - module.getLinkedNode().set('text', TTCatName);
386   - me.linkedTTCatNode = module.getLinkedNode();
387   - var obj = {
388   - name: TTCatName,
389   - fromPlugin: true
390   - };
391   - if (isCatalog) {
392   - Ext.Msg.prompt('Define Parameters', 'Please enter parameters number for the new catalog:', function (btn, text) {
393   - if (btn == 'ok') {
394   - obj.nbParameters = parseInt(text, 10);
395   - if (isNaN(obj.nbParameters)) {
396   - obj.nbParameters = 1;
397   - }
398   - module.createObject(obj);
399   - me.linkedTTCatNode.editLeaf(function () {
400   - me.insertInterval();
401   - });
402   - }
403   - });
404   - return;
405   - }
406   - else {
407   - module.createObject(obj);
408   - }
409   - }
410   -
411   - me.linkedTTCatNode.editLeaf(function () {
412   - me.insertInterval();
413   - });
414   - });
415   - }
416   - });
417   - }
418   - }
419   - ]
420   - };
421   -
422   - this.plotFunctionType = new amdaPlotComp.plotFunction.FunctionType({});
423   -
424   - this.form = new Ext.form.FormPanel({
425   - frame: true,
426   - width: 255,
427   - layout: {
428   - type: 'vbox',
429   - pack: 'start',
430   - align: 'stretch'
431   - },
432   - fieldDefaults: {
433   - labelWidth: 60
434   - },
435   - items: [
436   - intervalFieldSet,
437   - this.isPlotFunction ? this.plotFunctionType : this.insertTTFieldSet
438   - ],
439   - fbar: [
440   - {
441   - text: me.isPlotFunction ? "Apply The Function" : 'Apply Zoom',
442   - width: me.isPlotFunction ? 200 : 100,
443   - scope: this,
444   - handler: function () {
445   - if (this.zoomType == 'timeAxis') {
446   - var minZoom = Ext.Date.format(this.form.getForm().findField('zoom-min-time').getValue(), 'Y-m-d\\TH:i:s.u');
447   - var maxZoom = Ext.Date.format(this.form.getForm().findField('zoom-max-time').getValue(), 'Y-m-d\\TH:i:s.u');
448   - }
449   - else {
450   - var minZoom = this.form.getForm().findField('zoom-min-float').getValue();
451   - var maxZoom = this.form.getForm().findField('zoom-max-float').getValue();
452   - }
453   -
454   - if (!maxZoom || !minZoom || !this.form.getForm().isValid()) {
455   - myDesktopApp.warningMsg('Error in values definition');
456   - return;
457   - }
458   -
459   - if (me.isPlotFunction) {
460   - let request_to_send = {};
461   -
462   - request_to_send = Object.assign({}, me.plotFunctionType.getValues()/*, me.plotFunctionParamField.getValues()*/);
463   - request_to_send = Object.assign({}, request_to_send, {
464   - 'action': 'plotFunction',
465   - 'interactiveId': this.interactiveId,
466   - 'panelId': this.panelId,
467   - 'starttime': minZoom,
468   - 'stoptime': maxZoom
469   - });
470   -
471   - this.hostCmp.callInteractivePlot(request_to_send);
472   - } else {
473   - this.hostCmp.callInteractivePlot({
474   - 'action': 'zoom',
475   - 'interactiveId': this.interactiveId,
476   - 'panelId': this.panelId,
477   - 'axeId': this.zoomType,
478   - 'min': minZoom,
479   - 'max': maxZoom
480   - });
481   - }
482   -
483   - this.hostCmp.panelImage.resetZoom();
484   - }
485   - },
486   - me.isPlotFunction ? null :
487   - {
488   - text: 'Undo Zoom',
489   - width: 100,
490   - scope: this,
491   - handler: function () {
492   - this.hostCmp.callInteractivePlot({
493   - 'action': 'undozoom',
494   - 'interactiveId': this.interactiveId,
495   - 'panelId': this.panelId,
496   - 'axeId': this.zoomType
497   - });
498   - this.hostCmp.panelImage.resetZoom();
499   - }
500   - }
501   - ]
502   - });
503   -
504   - return this.form;
  123 + // Function to close the interval selection component
  124 + close: function () {
  125 + if (this.intervalSelectionCmp == null)
  126 + return;
  127 + this.intervalSelectionCmp.close();
505 128 },
506 129  
  130 + // Function to reset the minimum and maximum values of the interval selection component
  131 + resetMinMaxValue: function () {
  132 + this.intervalSelectionCmp.reset();
  133 + }
507 134 });
... ...
js/app/views/PlotComponents/intervalSelection/DateZoomIntervalSelection.js 0 โ†’ 100644
... ... @@ -0,0 +1,19 @@
  1 +Ext.define('amdaPlotComp.intervalSelection.DateZoomIntervalSelection', {
  2 + extend: 'amdaPlotComp.intervalSelection.ZoomIntervalSelection', // This class extends from amdaPlotComp.intervalSelection.ZoomIntervalSelection
  3 + requires: ['amdaPlotComp.intervalSelection.InsertToTTCatlog'], // This class requires the InsertToTTCatlog class from amdaPlotComp.intervalSelection
  4 +
  5 + type: 'timeAxis', // The type of axis for this interval selection is timeAxis
  6 + title: "Zoom on time axis & Interval selection", // The title of this interval selection
  7 + insertToTTCatlog: null, // An instance of the InsertToTTCatlog class, initially set to null
  8 +
  9 + /**
  10 + * Initializes the component.
  11 + * It calls the parent's initComponent method, then creates a new instance of InsertToTTCatlog and adds it to the form.
  12 + */
  13 + initComponent: function () {
  14 + this.callParent(arguments);
  15 + this.insertToTTCatlog = new amdaPlotComp.intervalSelection.InsertToTTCatlog({ parent: this });
  16 + this.form.add(this.insertToTTCatlog);
  17 + },
  18 +
  19 +});
... ...
js/app/views/PlotComponents/intervalSelection/InsertToTTCatlog.js 0 โ†’ 100644
... ... @@ -0,0 +1,173 @@
  1 +Ext.define('amdaPlotComp.intervalSelection.InsertToTTCatlog', {
  2 + extend: 'Ext.form.FieldSet',
  3 +
  4 + collapsible: false,
  5 + layout: LAYOUT_STYLE,
  6 + title: 'Add in Time Table or Catalog',
  7 + name: 'tt-insertion-fieldset',
  8 +
  9 + fieldTypeTTCat: 'ttcat-type',
  10 + fieldTypeName: 'ttcat-name',
  11 + ttModuleId: 'timetab-win',
  12 + catModuleId: 'catalog-win',
  13 + linkedTTCatNode: null,
  14 +
  15 + parent: null,
  16 +
  17 + initComponent: function () {
  18 + const self = this;
  19 +
  20 + const insertTypeStore = Ext.create('Ext.data.Store', {
  21 + fields: ['key', 'name'],
  22 + data: [
  23 + { "key": "timeTable", "name": "TimeTable" },
  24 + { "key": "catalog", "name": "Catalog" }
  25 + ]
  26 + });
  27 +
  28 + Ext.apply(self, {
  29 + items: [{
  30 + xtype: 'combo',
  31 + fieldLabel: 'Insert In',
  32 + store: insertTypeStore,
  33 + queryMode: 'local',
  34 + displayField: 'name',
  35 + valueField: 'key',
  36 + editable: false,
  37 + value: 'timeTable',
  38 + name: self.fieldTypeTTCat,
  39 + itemId: self.fieldTypeTTCat,
  40 + },
  41 + {
  42 + xtype: 'textfield',
  43 + fieldLabel: 'Name',
  44 + name: self.fieldTypeName,
  45 + itemId: self.fieldTypeName,
  46 + listeners:
  47 + {
  48 + render: function (o, op) {
  49 + var field = this;
  50 + var el = this.el;
  51 + Ext.create('Ext.dd.DropTarget', el, {
  52 + ddGroup: 'explorerTree',
  53 + notifyOver: function (ddSource, e, data) {
  54 + var TTCatType = self._getFieldTypeTTCat().getValue();
  55 + if (data.records[0].data.leaf && (data.records[0].data.nodeType == TTCatType)) {
  56 + this.valid = true;
  57 + return this.dropAllowed;
  58 + }
  59 + this.valid = false;
  60 + return this.dropNotAllowed;
  61 + },
  62 + notifyDrop: function (ddSource, e, data) {
  63 + if (!this.valid)
  64 + return false;
  65 + field.setValue(data.records[0].get('text'));
  66 + return true;
  67 + }
  68 + });
  69 + }
  70 + }
  71 + },
  72 + {
  73 + xtype: 'button',
  74 + width: width,
  75 + text: 'Insert Interval',
  76 + scope: this,
  77 + handler: function () {
  78 + var me = this;
  79 +
  80 + var TTCatType = self._getFieldTypeTTCat().getValue();
  81 + var TTCatName = self._getFieldNameTTCat().getValue();
  82 +
  83 + var isCatalog = (TTCatType == 'catalog');
  84 + myDesktopApp.getLoadedModule(isCatalog ? this.catModuleId : this.ttModuleId, true, function (module) {
  85 + var targetModuleUI = module.getUiContent();
  86 + if (me.linkedTTCatNode && (me.linkedTTCatNode.get('text') == TTCatName) && (me.linkedTTCatNode.get('nodeType') == TTCatType)) {
  87 + if (targetModuleUI)
  88 + me.insertInterval();
  89 + else {
  90 + me.linkedTTCatNode.editLeaf(function () {
  91 + me.insertInterval();
  92 + });
  93 + }
  94 + }
  95 + else {
  96 + var explorerTree = Ext.getCmp(amdaUI.ExplorerUI.RESRC_TAB.TREE_ID);
  97 + var ttCatRootNode = explorerTree.getRootNode().findChild('id', isCatalog ? 'catalog-treeRootNode' : 'timeTable-treeRootNode', true);
  98 + amdaModel.InteractiveNode.preloadNodes(ttCatRootNode, function () {
  99 + var nodeWithSameName = null;
  100 +
  101 + if (TTCatName != '')
  102 + nodeWithSameName = ttCatRootNode.findChild('text', TTCatName, true);
  103 +
  104 + if (nodeWithSameName !== null)
  105 + me.linkedTTCatNode = nodeWithSameName;
  106 + else {
  107 + module.createLinkedNode();
  108 + module.getLinkedNode().set('text', TTCatName);
  109 + me.linkedTTCatNode = module.getLinkedNode();
  110 + var obj = {
  111 + name: TTCatName,
  112 + fromPlugin: true
  113 + };
  114 + if (isCatalog) {
  115 + Ext.Msg.prompt('Define Parameters', 'Please enter parameters number for the new catalog:', function (btn, text) {
  116 + if (btn == 'ok') {
  117 + obj.nbParameters = parseInt(text, 10);
  118 + if (isNaN(obj.nbParameters)) {
  119 + obj.nbParameters = 1;
  120 + }
  121 + module.createObject(obj);
  122 + me.linkedTTCatNode.editLeaf(function () {
  123 + me.insertInterval();
  124 + });
  125 + }
  126 + });
  127 + return;
  128 + }
  129 + else {
  130 + module.createObject(obj);
  131 + }
  132 + }
  133 +
  134 + me.linkedTTCatNode.editLeaf(function () {
  135 + me.insertInterval();
  136 + });
  137 + });
  138 + }
  139 + });
  140 + }
  141 + }
  142 + ]
  143 + });
  144 +
  145 + self.callParent(arguments);
  146 + },
  147 +
  148 +
  149 + _getFieldTypeTTCat: function () {
  150 + return this.down('#' + this.fieldTypeTTCat);
  151 + },
  152 +
  153 + _getFieldNameTTCat: function () {
  154 + return this.down('#' + this.fieldTypeName);
  155 + },
  156 +
  157 + /**
  158 + * add Interval to Time table or Catalog
  159 + */
  160 + insertInterval: function () {
  161 + const start = this.parent.getField1Value();
  162 + const stop = this.parent.getField2Value();
  163 +
  164 + const TTCatType = this._getFieldTypeTTCat().getValue();
  165 + const isCatalog = (TTCatType == 'catalog');
  166 +
  167 + myDesktopApp.getLoadedModule(isCatalog ? this.catModuleId : this.ttModuleId, true, function (module) {
  168 + var targetModuleUI = module.getUiContent();
  169 + if (targetModuleUI)
  170 + targetModuleUI.addInterval(start, stop);
  171 + });
  172 + }
  173 +});
... ...
js/app/views/PlotComponents/intervalSelection/IntervalSelection.js 0 โ†’ 100644
... ... @@ -0,0 +1,246 @@
  1 +// Define a constant for the layout style of the form
  2 +const LAYOUT_STYLE = {
  3 + type: 'vbox', // vertical box layout
  4 + pack: 'start', // controls the vertical alignment of child items
  5 + align: 'stretch' // each child item is stretched to fill the width of the container
  6 +};
  7 +
  8 +// Width of button
  9 +const width = 100;
  10 +
  11 +// Define the parent class for all classes to use time interval selection.
  12 +Ext.define('amdaPlotComp.intervalSelection.IntervalSelection', {
  13 + extend: 'Ext.window.Window', // This class extends from Ext.window.Window
  14 + // Window configurations
  15 + x: 0, y: 0, // The initial position of the window
  16 + requires:['amdaUI.StandardFloatField'],
  17 + title: 'Interval Selection', // The title of the window
  18 + constrain: true, // Constrains the window to within the boundaries of its containing element
  19 + collapsible: true, // Allows the window to be collapsed
  20 + resizable: false, // Prevents the window from being resizable
  21 + ghost: false, // Disables "ghosting" (semi-transparent representation of the window body) when moving or resizing
  22 +
  23 + form: null, // a panel which contains all components
  24 + hostCmp: null, // The host component from which this class is instantiated.
  25 + interactiveId: '',
  26 + panelId: -1,
  27 +
  28 + // Attributes of this class
  29 + config: {
  30 + field1Type: 'datefield', // The xtype of field1. By default is datefield because we are working with time series.
  31 + field1Label: 'Start Time', // The label of field1.
  32 + field1Format: 'Y/m/d H:i:s.u',
  33 + field2Type: 'datefield', // The xtype of field2. By default is datefield.
  34 + field2Label: 'Stop Time', // The label of field2.
  35 + field2Format: 'Y/m/d H:i:s.u',
  36 + buttonApply: 'Apply'
  37 + },
  38 +
  39 + // Define the itemIds as constants
  40 + // These will be used to reference the fields later in the code
  41 + FIELD1_ITEM_ID: 'field1',
  42 + FIELD2_ITEM_ID: 'field2',
  43 + buttonUseTime: 'button-use-time',
  44 +
  45 + initComponent: function () {
  46 + const self = this; // Reference to this instance for use in event handlers
  47 + this.form = new Ext.form.FormPanel({ // Create a new FormPanel instance and assign it to form
  48 + frame: true, // Display a frame around the panel
  49 + width: 255, // Set the width of the panel
  50 + layout: LAYOUT_STYLE, // Set the layout style of the panel
  51 + fieldDefaults: {
  52 + labelWidth: 60 // Set default label width for fields in this panel
  53 + },
  54 + items: [{
  55 + xtype: 'fieldset', // Create a new FieldSet to group related fields together
  56 + title: 'Interval Selection',
  57 + name: 'interval-selection-fieldset',
  58 + collapsible: false,
  59 + layout: LAYOUT_STYLE,
  60 + items: [{
  61 + xtype: this.field1Type,
  62 + fieldLabel: this.field1Label,
  63 + itemId: this.FIELD1_ITEM_ID,
  64 + format: this.field1Format,
  65 + listeners: {
  66 + change: function (field, newValue) {
  67 + if (newValue === null || newValue === undefined || newValue === '') return;
  68 + var field2 = self._getField2();
  69 + // Check if field2 is not empty
  70 + const value2 = parseFloat(field2.getValue());
  71 + if (value2 !== null && value2 !== undefined && value2 !== '') {
  72 + if (parseFloat(newValue) > value2) {
  73 + // Update both field1 and field2 to the new values
  74 + field2.suspendEvents();
  75 + field2.setValue(newValue);
  76 + field.setValue(value2);
  77 + field2.resumeEvents();
  78 + }
  79 + }
  80 + }
  81 + }
  82 + },
  83 + {
  84 + xtype: this.field2Type,
  85 + fieldLabel: this.field2Label,
  86 + itemId: this.FIELD2_ITEM_ID,
  87 + format: this.field2Format,
  88 + listeners: {
  89 + change: function (field, newValue) {
  90 + if (newValue === null || newValue === undefined || newValue === '') return;
  91 + var field1 = self._getField1();
  92 + // Check if field1 is not empty
  93 + const value1 = parseFloat(field1.getValue());
  94 + if (value1 !== null && value1 !== undefined && value1 !== '') {
  95 + if (parseFloat(newValue) < value1) {
  96 + // Update both field1 and field2 to the new values
  97 + field1.suspendEvents();
  98 + field1.setValue(newValue);
  99 + field.setValue(value1);
  100 + field1.resumeEvents();
  101 + }
  102 + }
  103 + }
  104 + }
  105 + }, {
  106 + xtype: 'button',
  107 + text: 'Reset',
  108 + width: width,
  109 + handler: function () {
  110 + self.reset();
  111 + }
  112 + },
  113 + {
  114 + xtype: 'button',
  115 + text: 'Use in Time Selection',
  116 + itemId: this.buttonUseTime,
  117 + handler: function () {
  118 + self._setTimeInterval();
  119 + }
  120 + }]
  121 + }],
  122 + fbar: [
  123 + {
  124 + xtype: 'button',
  125 + width: width,
  126 + text: this.buttonApply,
  127 + handler: function () {
  128 + self._apply();
  129 + }
  130 + }
  131 + ]
  132 + })
  133 +
  134 + Ext.apply(this, {
  135 + items: this.form
  136 + });
  137 +
  138 + this.setTitle(this.title + " - Panel Id : " + this.panelId);
  139 + this.callParent(arguments);
  140 + },
  141 +
  142 + /**
  143 + * Resets the time interval selection in the host component.
  144 + * This function calls the resetZoom method on the panelImage of the host component,
  145 + * effectively resetting any zoom applied to the image.
  146 + */
  147 + _resetHostCmpSelection: function () {
  148 + this.hostCmp.panelImage.resetZoom();
  149 + },
  150 +
  151 + /**
  152 + * Abstract method that must be implemented by subclasses.
  153 + * Throws an error if not overridden.
  154 + */
  155 + _apply: function () {
  156 + throw new Error('_apply() method must be implemented by subclass');
  157 + },
  158 +
  159 + /**
  160 + * Checks if the values of field1 and field2 are valid and if the form is valid.
  161 + * Returns true if any of these conditions are not met.
  162 + */
  163 + _notValidValues: function () {
  164 + return !this.getField1Value() || !this.getField2Value() || !this.form.getForm().isValid();
  165 + },
  166 +
  167 + /**
  168 + * Retrieves the component associated with FIELD1_ITEM_ID in the form.
  169 + * Returns the component if found, null otherwise.
  170 + */
  171 + _getField1: function () {
  172 + return this.form.down('#' + this.FIELD1_ITEM_ID);
  173 + },
  174 +
  175 + /**
  176 + * Retrieves the component associated with FIELD2_ITEM_ID in the form.
  177 + * Returns the component if found, null otherwise.
  178 + */
  179 + _getField2: function () {
  180 + return this.form.down('#' + this.FIELD2_ITEM_ID);
  181 + },
  182 +
  183 + /**
  184 + * Sets the time interval of the plot based on the values of the fields.
  185 + * This method is triggered when the buttonUseTime is clicked.
  186 + * It creates a new time object with start, stop, and interactiveId properties,
  187 + * and then calls the setTimeInterval method on the plot module with this object.
  188 + */
  189 + _setTimeInterval: function () {
  190 + const timeObj = new Object();
  191 + timeObj.start = this.getField1Value();
  192 + timeObj.stop = this.getField2Value();
  193 + timeObj.interactiveId = this.interactiveId;
  194 + const plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id);
  195 + plotModule.setTimeInterval(timeObj);
  196 + },
  197 +
  198 + /**
  199 + * Hides the buttonUseTime when it's not needed.
  200 + * For example, when we call Zoom on y-left axis we should not see this button.
  201 + * It finds the button by its ID and then calls the hide method on it.
  202 + */
  203 + _removeUseTimeButton: function () {
  204 + const buttonToHide = this.form.down('#' + this.buttonUseTime);
  205 + buttonToHide.hide();
  206 + },
  207 +
  208 + /**
  209 + * Retrieves the value of field1 from the form.
  210 + */
  211 + getField1Value: function () {
  212 + return this._getField1().getValue();
  213 + },
  214 +
  215 + /**
  216 + * Retrieves the value of field2 from the form.
  217 + */
  218 + getField2Value: function () {
  219 + return this._getField2().getValue();
  220 + },
  221 +
  222 + /**
  223 + * Sets a new value for field1 in the form.
  224 + */
  225 + setField1Value: function (value) {
  226 + this._getField1().setValue(value);
  227 + },
  228 +
  229 + /**
  230 + * Sets a new value for field2 in the form.
  231 + */
  232 + setField2Value: function (value) {
  233 + this._getField2().setValue(value);
  234 + },
  235 +
  236 + /**
  237 + * Resets the values of fields and host component selection.
  238 + * It calls the reset method on field1 and field2, and then calls _resetHostCmpSelection.
  239 + */
  240 + reset: function () {
  241 + this._getField1().reset();
  242 + this._getField2().reset();
  243 + this._resetHostCmpSelection();
  244 + }
  245 +
  246 +});
... ...
js/app/views/PlotComponents/intervalSelection/NumberZoomIntervalSelection.js 0 โ†’ 100644
... ... @@ -0,0 +1,21 @@
  1 +Ext.define('amdaPlotComp.intervalSelection.NumberZoomIntervalSelection', {
  2 + extend: 'amdaPlotComp.intervalSelection.ZoomIntervalSelection', // This class extends from amdaPlotComp.intervalSelection.ZoomIntervalSelection
  3 +
  4 + field1Type: 'standardfloatfield', // The type of the first field is a number field
  5 + field1Label: 'Min Value', // The label for the first field is 'Min Value'
  6 + field1Format: null, // The format for the first field is initially set to null
  7 + field2Type: 'standardfloatfield', // The type of the second field is a number field
  8 + field2Label: 'Max value', // The label for the second field is 'Max value'
  9 + field2Format: null, // The format for the second field is initially set to null
  10 +
  11 + type: null, // The type of interval selection is initially set to null
  12 +
  13 + /**
  14 + * Initializes the component.
  15 + * It calls the parent's initComponent method, then removes the use time button.
  16 + */
  17 + initComponent: function () {
  18 + this.callParent(arguments);
  19 + this._removeUseTimeButton();
  20 + }
  21 +});
... ...
js/app/views/PlotComponents/intervalSelection/PlotFunctionIntervalSelection.js 0 โ†’ 100644
... ... @@ -0,0 +1,43 @@
  1 +Ext.define('amdaPlotComp.intervalSelection.PlotFunctionIntervalSelection', {
  2 + extend: 'amdaPlotComp.intervalSelection.IntervalSelection', // This class extends from amdaPlotComp.intervalSelection.IntervalSelection
  3 + requires: ['amdaPlotComp.plotFunction.FunctionType'], // This class requires the FunctionType class from amdaPlotComp.plotFunction
  4 +
  5 + title: "Plot Function", // The title of the window
  6 + plotFunctionType: null, // An instance of the FunctionType class, initially set to null
  7 +
  8 + /**
  9 + * Initializes the component.
  10 + * It calls the parent's initComponent method, then creates a new instance of FunctionType and adds it to the form.
  11 + */
  12 + initComponent: function () {
  13 + this.callParent(arguments);
  14 + this.plotFunctionType = Ext.create('amdaPlotComp.plotFunction.FunctionType', {
  15 + panelContext: this.panelContext
  16 + });
  17 +
  18 + this.form.add(this.plotFunctionType);
  19 + },
  20 +
  21 + /**
  22 + * Applies the plot function based on the values of the fields.
  23 + * If the values are not valid, it shows a warning message.
  24 + * Otherwise, it calls the interactive plot with the plotFunction action and resets the host component selection.
  25 + */
  26 + _apply: function () {
  27 + if (this._notValidValues()) {
  28 + myDesktopApp.warningMsg('Please note that either the Start Time or the Stop Time has not been defined. To proceed, ensure both times are properly set.');
  29 + } else {
  30 + const request_to_send = Object.assign({}, this.plotFunctionType.getValues(), {
  31 + 'action': 'plotFunction',
  32 + 'interactiveId': this.interactiveId,
  33 + 'panelId': this.panelId,
  34 + 'starttime': this.getField1Value(),
  35 + 'stoptime': this.getField2Value(),
  36 + });
  37 +
  38 + this.hostCmp.callInteractivePlot(request_to_send);
  39 + this._resetHostCmpSelection();
  40 + }
  41 + },
  42 +
  43 +});
... ...
js/app/views/PlotComponents/intervalSelection/ZoomIntervalSelection.js 0 โ†’ 100644
... ... @@ -0,0 +1,61 @@
  1 +Ext.define('amdaPlotComp.intervalSelection.ZoomIntervalSelection', {
  2 + extend: 'amdaPlotComp.intervalSelection.IntervalSelection', // This class extends from amdaPlotComp.intervalSelection.IntervalSelection
  3 +
  4 + buttonApply: "Apply Zoom",
  5 + type: null,
  6 +
  7 + /**
  8 + * Initializes the component.
  9 + * Adds an 'Undo Zoom' button to the bottom toolbar of the form.
  10 + */
  11 + initComponent: function () {
  12 + const self = this;
  13 + this.callParent(arguments);
  14 + this.form.getDockedItems('toolbar[dock="bottom"]')[0].add({
  15 + xtype: 'button',
  16 + width: width,
  17 + text: 'Undo Zoom',
  18 + handler: function () {
  19 + self._undoZoom();
  20 + }
  21 + });
  22 + },
  23 +
  24 + /**
  25 + * Applies the zoom based on the values of the fields.
  26 + * If the values are not valid, it shows a warning message.
  27 + * Otherwise, it calls the interactive plot with the zoom action and resets the host component selection.
  28 + */
  29 + _apply: function () {
  30 + if (this._notValidValues()) {
  31 + myDesktopApp.warningMsg('The Input Values are not defined');
  32 + } else {
  33 + this.hostCmp.callInteractivePlot({
  34 + 'action': 'zoom',
  35 + 'interactiveId': this.interactiveId,
  36 + 'panelId': this.panelId,
  37 + 'axeId': this.type,
  38 + 'min': this.getField1Value(),
  39 + 'max': this.getField2Value()
  40 + });
  41 +
  42 + this._resetHostCmpSelection();
  43 + }
  44 + },
  45 +
  46 + /**
  47 + * Undoes the zoom.
  48 + * It calls the interactive plot with the undozoom action and resets the host component selection.
  49 + */
  50 + _undoZoom: function () {
  51 + this.hostCmp.callInteractivePlot({
  52 + 'action': 'undozoom',
  53 + 'interactiveId': this.interactiveId,
  54 + 'panelId': this.panelId,
  55 + 'axeId': this.type
  56 + });
  57 +
  58 + this._resetHostCmpSelection();
  59 + }
  60 +
  61 +});
... ...
js/app/views/PlotComponents/plotFunction/BaseComponent.js 0 โ†’ 100644
... ... @@ -0,0 +1,16 @@
  1 +// Define the base class
  2 +Ext.define('amdaPlotComp.plotFunction.BaseComponent', {
  3 + extend: 'Ext.form.FieldSet',
  4 +
  5 + collapsible: false,
  6 + layout: LAYOUT_STYLE,
  7 +
  8 + /**
  9 + * Subclasses are expected to implement this method to retrieve values.
  10 + * @returns {Object} The values.
  11 + * @throws {Error} If the method is not implemented.
  12 + */
  13 + getValues: function () {
  14 + throw new Error('getValues() method must be implemented by subclass');
  15 + }
  16 +});
... ...
js/app/views/PlotComponents/plotFunction/CreatePlot.js deleted
... ... @@ -1,195 +0,0 @@
1   -/**
2   - * Un composant de 'PlotFunction' qui permet ร  l'utilisateur de sรฉlรฉctionner le type de fonction ร  appliquer : FFT, SUM, ...
3   - */
4   -Ext.define('amdaPlotComp.plotFunction.CreatePlot', {
5   - extend: 'Ext.window.Window',
6   - requires: [
7   - 'amdaUI.PlotlyContainer'
8   - ],
9   -
10   - initComponent: function () {
11   -
12   - this.emptyChartConfig = {
13   - xtype: 'amdaUI.PlotlyContainer',
14   - id: 'visu-chart',
15   - };
16   -
17   - const config =
18   - {
19   - title: 'Apply a Function on Interval',
20   - width: 700,
21   - height: 500,
22   - layout: 'fit',
23   - bodyStyle: { background: '#FFFFFF' },
24   - modal: false,
25   - resizable: true,
26   - maximizable: true,
27   - items: [
28   - this.emptyChartConfig
29   - ]
30   - };
31   -
32   - Ext.apply(this, config);
33   - this.callParent(arguments);
34   - },
35   -
36   - getXYData: function (data, serie_label) {
37   - const separatorItems = "|";
38   - const separator = ";";
39   -
40   - let legends = serie_label.split(separator);
41   - legends.pop();
42   -
43   - let items = data.split(separatorItems);
44   - items.pop();
45   -
46   - const xs = [];
47   - const ys = [];
48   - const labels = [];
49   - for (j = 0; j < legends.length; j++) {
50   - let i;
51   - const y = [];
52   - const x = [];
53   - for (i = 0; i < items.length; i++) {
54   - const temp = items[i].split(separator);
55   - x.push(this.timeConverter(temp[0]));
56   - y.push(temp[j + 1]);
57   - }
58   - ys.push(y);
59   - xs.push(x);
60   - labels.push(legends[j]);
61   - }
62   -
63   - return { xs: xs, ys: ys, labels: labels };
64   - },
65   -
66   - timeConverter: function (_timestamp) {
67   - var a = new Date(_timestamp * 1000);
68   - var year = a.getUTCFullYear();
69   - var month = a.getUTCMonth() + 1;
70   - var date = a.getUTCDate();
71   - var hour = a.getUTCHours();
72   - var min = a.getUTCMinutes();
73   - var sec = a.getUTCSeconds();
74   - var time = year + '-' + month + '-' + date + ' ' + hour + ':' + min + ':' + sec;
75   - return time;
76   - },
77   -
78   - applyFunction: function (y, dimSize) {
79   - const type = this.plotFunctionType;
80   - const valDict = type.getValues();
81   - const fct = valDict[type.plotFunctionItems.type.name];
82   - let out_y = [];
83   - switch (fct) {
84   - case type.plotFunctionItems.type.values.sum:
85   - out_y = y;
86   - break;
87   - case type.plotFunctionItems.type.values.fft:
88   -
89   - break;
90   - case type.plotFunctionItems.type.values.avg:
91   - if (dimSize === -1) {
92   - out_y = y.map(e => e / y.length);
93   - } else {
94   - out_y = y.map(e => e / dimSize);
95   - }
96   - break;
97   -
98   - default:
99   - break;
100   - }
101   - return out_y;
102   - },
103   -
104   -
105   -
106   - plot: function () {
107   - const param = this.xmlDoc.getElementsByTagName('parameter');
108   - const traces = [];
109   - let yAxisLabel = "";
110   - let i;
111   - for (i = 0; i < param.length; i++) {
112   - const param_name = param[i].getAttribute('name');
113   - const param_unit = param[i].getAttribute('unit');
114   - const serie = param[i].getElementsByTagName('serie');
115   -
116   - yAxisLabel += param_unit + "<br>";
117   -
118   - for (let si = 0; si < serie.length; si++) {
119   - const serie_label = serie[si].getAttribute('serie_label');
120   - const data_ = this.getXYData(serie[si].getAttribute('data'), serie_label);
121   - let k;
122   -
123   - const dimSize = serie[si].getAttribute('dimSize');
124   -
125   - for (k = 0; k < data_.ys.length; k++) {
126   - let trace = {};
127   - trace.x = data_.xs[k];
128   - trace.y = this.applyFunction(data_.ys[k], parseInt(dimSize));
129   - trace.mode = 'lines+markers';
130   - trace.name = param_name + " (" + data_.labels[k] + ")";
131   - trace.type = 'scatter';
132   -
133   - traces.push(trace);
134   - }
135   - }
136   - }
137   -
138   - var chart = Ext.getCmp(this.emptyChartConfig.id);
139   -
140   - var config = this.emptyChartConfig;
141   -
142   - config.data = traces;
143   -
144   - const config_ = {
145   - showgrid: true,
146   - zeroline: true,
147   - showline: true,
148   - mirror: 'ticks',
149   - gridcolor: '#bdbdbd',
150   - gridwidth: 1,
151   - zerolinecolor: '#969696',
152   - zerolinewidth: 1,
153   - linecolor: '#636363',
154   - linewidth: 1
155   - };
156   -
157   - let config_x = {
158   - title: {
159   - text: "Time, UT"
160   - },
161   - type: 'date',
162   - };
163   -
164   - let config_y = {
165   - title: {
166   - text: this.format_label(yAxisLabel)
167   - },
168   - exponentformat: "e"
169   - }
170   -
171   - for (var key in config_) {
172   - config_x[key] = config_[key];
173   - config_y[key] = config_[key];
174   - }
175   -
176   - config.layout = {
177   - xaxis: config_x,
178   - yaxis: config_y
179   - };
180   -
181   - if (chart) {
182   - var chartPanel = chart.up();
183   - chartPanel.remove(chart);
184   - }
185   - var testPlotly = new amdaUI.PlotlyContainer(config);
186   - chartPanel.insert(testPlotly);
187   - },
188   - format_label: function (label) {
189   - const power_2 = "\xB2";
190   - const power_3 = "\xB3";
191   - const amda_power_2 = "#u2";
192   - const amda_space = "#d";
193   - return label.replace(amda_power_2, power_2).replace(amda_space, " ");
194   - }
195   -});
196 0 \ No newline at end of file
js/app/views/PlotComponents/plotFunction/FFTCmpt.js 0 โ†’ 100644
... ... @@ -0,0 +1,53 @@
  1 +Ext.define('amdaPlotComp.plotFunction.FFTCmpt', {
  2 + extend: 'amdaPlotComp.plotFunction.BaseComponent', // This class extends from amdaPlotComp.plotFunction.BaseComponent
  3 + title: "FFT Arguments", // The title of this component
  4 + id: 'fftComboBox', // The id of this component
  5 +
  6 + /**
  7 + * Initializes the component.
  8 + * It creates a combo box with two options, 'Frequency' and 'Period', and adds it to the component.
  9 + */
  10 + initComponent: function () {
  11 + const me = this;
  12 +
  13 + // Define combo box store
  14 + const comboStore = Ext.create('Ext.data.Store', {
  15 + fields: ['label', 'value'],
  16 + data: [
  17 + { label: 'Frequency', value: 'Frequency' },
  18 + { label: 'Period', value: 'Period' }
  19 + ]
  20 + });
  21 +
  22 + // Create combo box
  23 + const fftCombo = Ext.create('Ext.form.field.ComboBox', {
  24 + itemId: me.id, // Add itemId here
  25 + fieldLabel: 'Abscisse',
  26 + store: comboStore,
  27 + queryMode: 'local',
  28 + displayField: 'label',
  29 + valueField: 'value',
  30 + editable: false,
  31 + value: 'Frequency'
  32 + });
  33 +
  34 + // Assign items to the component
  35 + me.items = [fftCombo];
  36 +
  37 + // Call the parent class's initComponent method
  38 + me.callParent(arguments);
  39 + },
  40 +
  41 + /**
  42 + * Retrieves the selected value from the combo box.
  43 + * Returns an object with a property 'abscisse' set to the selected value.
  44 + */
  45 + getValues: function () {
  46 + const fftComboBox = this.down('#' + this.id); // Retrieve ComboBox by itemId
  47 + const selectedValue = fftComboBox.getValue(); // Get selected value
  48 +
  49 + return {
  50 + abscisse: selectedValue
  51 + };
  52 + }
  53 +});
... ...
js/app/views/PlotComponents/plotFunction/FunctionType.js
1 1 /**
2   - * Un composant de 'PlotFunction' qui permet ร  l'utilisateur de sรฉlรฉctionner le type de fonction ร  appliquer : FFT, SUM, ...
  2 + * A 'PlotFunction' component that allows the user to select the type of function to apply: FFT, SUM, etc.
3 3 */
4 4 Ext.define('amdaPlotComp.plotFunction.FunctionType', {
5 5 extend: 'Ext.form.Panel',
6   -
7   - plotFunctionItems: {
8   - type: {
9   - name: "type",
10   - field: "Function Type",
11   - values: {
12   - fft: "FFT",
13   - dft: "DFT",
14   - sum: "SUM",
15   - avg: "AVG"
16   - },
17   - labels: {
18   - fft: "FFT (Magnitude^2)",
19   - dft: "DFT (Magnitude^2)",
20   - sum: "SUM",
21   - avg: "AVG"
22   - }
23   - },
24   - scale: {
25   - name: "scale_abscisse",
26   - field: "X-Axis Scale",
27   - values: {
28   - log: "logarithmic",
29   - linear: "linear",
30   - inherits: "Inherits"
31   - }
32   - },
33   - abscisse: {
34   - name: "abscisse",
35   - field: "Abscisse",
36   - values: {
37   - frequency: "Frequency",
38   - period: "Period"
39   - }
40   - },
41   - scale_ordonnee: {
42   - name: "scale_ordonnee",
43   - field: "Y-Axis Scale"
44   - }
  6 +
  7 + view: null, // A reference to the view of this component
  8 + currentModule: null, // A reference to the current module of this component
  9 +
  10 + functionComboBox: "type", // The name of the function combo box
  11 + x_axis: { label: "X Axis", value: "scale_abscisse" }, // The label and value for the x-axis combo box
  12 + y_axis: { label: "Y Axis", value: "scale_ordonnee" }, // The label and value for the y-axis combo box
  13 + scaleOptions: {
  14 + linear: { label: "Linear", value: "linear" }, // The label and value for the linear scale option
  15 + logarithmic: { label: "Logarithmic", value: "logarithmic" } // The label and value for the logarithmic scale option
  16 + },
  17 + functionOptions: {
  18 + fft: { label: "FFT (Magnitude^2)", value: "FFT" }, // The label and value for the FFT function option
  19 + dft: { label: "DFT (Magnitude^2)", value: "DFT" }, // The label and value for the DFT function option
  20 + sum: { label: "SUM", value: "SUM" }, // The label and value for the SUM function option
  21 + avg: { label: "AVG", value: "AVG" }, // The label and value for the AVG function option
  22 + hist: { label: "Histogram Plot 1D", value: 'histoPlot' } // The label and value for the Histogram Plot 1D function option
45 23 },
46 24  
47   - initComponent: function () {
48   - const key_ = "key";
49   - const name_ = "name";
50   -
51   - //Combobox to choose the type of fucntion to be applied
52   - const data_function_type = [];
53   - let item_type = {};
54   - item_type[key_] = this.plotFunctionItems.type.values.fft;
55   - item_type[name_] = this.plotFunctionItems.type.labels.fft;
56   - data_function_type.push(item_type);
57   - item_type = {};
58   - item_type[key_] = this.plotFunctionItems.type.values.dft;
59   - item_type[name_] = this.plotFunctionItems.type.labels.dft;
60   - // Disbale DFT momentarily
61   - data_function_type.push(item_type);
62   -
63   - item_type = {};
64   - item_type[key_] = this.plotFunctionItems.type.values.sum;
65   - item_type[name_] = this.plotFunctionItems.type.labels.sum;
66   - data_function_type.push(item_type);
67   - item_type = {};
68   - item_type[key_] = this.plotFunctionItems.type.values.avg;
69   - item_type[name_] = this.plotFunctionItems.type.labels.avg;
70   - data_function_type.push(item_type);
71   -
72   - const function_type = Ext.create('Ext.data.Store', {
73   - fields: [key_, name_],
74   - data: data_function_type
  25 + /**
  26 + * Creates a combo box for selecting the function type.
  27 + * @param {String} defaultSelection The default selected value for the combo box.
  28 + * @returns {Ext.form.field.ComboBox} The created combo box.
  29 + */
  30 + createFunctionComboBox: function (defaultSelection) {
  31 + const self = this;
  32 + const comboStore = Ext.create('Ext.data.Store', {
  33 + fields: ['label', 'value'],
  34 + data: Object.values(this.functionOptions)
75 35 });
76 36  
77   - //Combo to choose type of scaling
78   - const data_ = [];
79   - const item_inherits = {};
80   - item_inherits[key_] = this.plotFunctionItems.scale.values.inherits;
81   - item_inherits[name_] = this.plotFunctionItems.scale.values.inherits;
82   - // Disbale inherits momentarily
83   - //data_.push(item_inherits);
84   -
85   - const item_log = {};
86   - item_log[key_] = this.plotFunctionItems.scale.values.log;
87   - item_log[name_] = this.plotFunctionItems.scale.values.log;
88   - data_.push(item_log);
89   -
90   - const item_linear = {};
91   - item_linear[key_] = this.plotFunctionItems.scale.values.linear;
92   - item_linear[name_] = this.plotFunctionItems.scale.values.linear;
93   - data_.push(item_linear);
94   -
95   - const scale = Ext.create('Ext.data.Store', {
96   - fields: [key_, name_],
97   - data: data_
  37 + const combo = Ext.create('Ext.form.field.ComboBox', {
  38 + fieldLabel: 'Function',
  39 + store: comboStore,
  40 + queryMode: 'local',
  41 + displayField: 'label',
  42 + valueField: 'value',
  43 + editable: false,
  44 + name: this.functionComboBox,
  45 + value: defaultSelection || Object.values(this.functionOptions)[2].value, // Default value
  46 + listeners: {
  47 + change: function (combo, value) {
  48 + self.handleFunction(value);
  49 + }
  50 + }
98 51 });
99 52  
100   - //Combo to choose x type data of FFT
101   - const data__ = [];
102   - const item_frequency = {};
103   - item_frequency[key_] = this.plotFunctionItems.abscisse.values.frequency;
104   - item_frequency[name_] = this.plotFunctionItems.abscisse.values.frequency;
105   - data__.push(item_frequency);
106   -
107   - const item_period = {};
108   - item_period[key_] = this.plotFunctionItems.abscisse.values.period;
109   - item_period[name_] = this.plotFunctionItems.abscisse.values.period;
110   - data__.push(item_period);
111   -
112   - const abscisse = Ext.create('Ext.data.Store', {
113   - fields: [key_, name_],
114   - data: data__
  53 + return combo;
  54 + },
  55 +
  56 + /**
  57 + * Creates a combo box for selecting the scale type for an axis.
  58 + * @param {Object} axis An object with a label and a value for the axis.
  59 + * @returns {Ext.form.field.ComboBox} The created combo box.
  60 + */
  61 + createAxisComboBox: function (axis) {
  62 + const comboStore = Ext.create('Ext.data.Store', {
  63 + fields: ['label', 'value'],
  64 + data: Object.values(this.scaleOptions)
115 65 });
116 66  
117   - const me = this;
  67 + const combo = Ext.create('Ext.form.field.ComboBox', {
  68 + fieldLabel: axis.label,
  69 + store: comboStore,
  70 + queryMode: 'local',
  71 + displayField: 'label',
  72 + valueField: 'value',
  73 + editable: false,
  74 + name: axis.value,
  75 + value: Object.values(this.scaleOptions)[0].value // Default value
  76 + });
118 77  
119   - var tabParams = Ext.create('Ext.form.FieldSet', {
120   - collapsible: false,
121   - layout: {
122   - type: 'vbox',
123   - pack: 'start',
124   - align: 'stretch',
125   - },
126   - bodyStyle: 'background: none',
127   - items: [
128   - {
129   - xtype: 'combo',
130   - fieldLabel: this.plotFunctionItems.type.field,
131   - store: function_type,
132   - queryMode: 'local',
133   - displayField: name_,
134   - valueField: key_,
135   - editable: false,
136   - value: this.plotFunctionItems.type.values.sum,
137   - name: this.plotFunctionItems.type.name,
138   - listeners: {
139   - change: function (combo, value) {
140   - if (value === me.plotFunctionItems.type.values.fft || value === me.plotFunctionItems.type.values.dft) {
141   - me.getForm().findField(me.plotFunctionItems.abscisse.name).setVisible(true);
142   - }
143   - else {
144   - me.getForm().findField(me.plotFunctionItems.abscisse.name).setVisible(false);
145   - }
  78 + return combo;
  79 + },
  80 +
  81 +
  82 + /**
  83 + * Handles the change of function type by removing the current module and adding a new one based on the selected value.
  84 + * @param {String} value The selected value from the function combo box.
  85 + */
  86 + handleFunction: function (value) {
  87 + if (this.currentModule) {
  88 + this.view.remove(this.currentModule, true);
  89 + this.currentModule = null;
  90 + }
  91 +
  92 + switch (value) {
  93 + case this.functionOptions.fft.value:
  94 + this.currentModule = Ext.create('amdaPlotComp.plotFunction.FFTCmpt');
  95 + break;
  96 + case this.functionOptions.dft.value:
  97 + this.currentModule = Ext.create('amdaPlotComp.plotFunction.FFTCmpt', { title: "DFT Arguments" });
  98 + break;
  99 + case this.functionOptions.hist.value:
  100 + var histoConfig = {};
  101 + if (this.panelContext && this.panelContext.plotArea.axes) {
  102 + Ext.Array.each(this.panelContext.plotArea.axes, function(axis) {
  103 + if ((axis['id'] == 'y-left') || (axis['id'] == 'y-right')) {
  104 + histoConfig['xmin'] = axis['min'];
  105 + histoConfig['xmax'] = axis['max'];
  106 + histoConfig['yAxis'] = axis['id'];
146 107 }
147   - }
148   - },
149   - {
150   - xtype: 'combo',
151   - fieldLabel: this.plotFunctionItems.scale.field,
152   - store: scale,
153   - queryMode: 'local',
154   - displayField: name_,
155   - valueField: key_,
156   - editable: false,
157   - value: this.plotFunctionItems.scale.values.log,
158   - name: this.plotFunctionItems.scale.name
159   - },
160   - {
161   - xtype: 'combo',
162   - fieldLabel: this.plotFunctionItems.abscisse.field,
163   - store: abscisse,
164   - queryMode: 'local',
165   - displayField: name_,
166   - valueField: key_,
167   - editable: false,
168   - hidden: true,
169   - value: this.plotFunctionItems.abscisse.values.frequency,
170   - name: this.plotFunctionItems.abscisse.name
171   - },
172   - {
173   - xtype: 'combo',
174   - fieldLabel: this.plotFunctionItems.scale_ordonnee.field,
175   - store: scale,
176   - queryMode: 'local',
177   - displayField: name_,
178   - valueField: key_,
179   - editable: false,
180   - value: this.plotFunctionItems.scale.values.log,
181   - name: this.plotFunctionItems.scale_ordonnee.name
  108 + });
182 109 }
183   - ]
  110 + this.currentModule = Ext.create('amdaPlotComp.plotFunction.Histogram', histoConfig);
  111 + break;
  112 + default:
  113 + break;
  114 + }
  115 + if (this.currentModule)
  116 + this.view.add(this.currentModule);
  117 + },
  118 +
  119 +
  120 + /**
  121 + * Initializes the component by creating a field set with a function combo box and two axis combo boxes.
  122 + */
  123 + initComponent: function () {
  124 + this.view = Ext.create('Ext.form.FieldSet', {
  125 + collapsible: false,
  126 + layout: LAYOUT_STYLE,
  127 + bodyStyle: 'background: none',
  128 + items: [this.createFunctionComboBox(), this.createAxisComboBox(this.x_axis), this.createAxisComboBox(this.y_axis)]
184 129 });
185 130  
186 131 const config =
187 132 {
188   - title: 'Function Type',
  133 + title: 'Function To Apply',
189 134 bodyStyle: { background: '#dfe8f6' },
190   - items: [tabParams]
  135 + items: [this.view]
191 136 };
192 137  
193 138 Ext.apply(this, config);
... ... @@ -195,21 +140,21 @@ Ext.define(&#39;amdaPlotComp.plotFunction.FunctionType&#39;, {
195 140 },
196 141  
197 142 /**
198   - * Retournes les valeurs des comboboxes associรฉes ร  ce composant
199   - * @returns les valeurs des comboboxes se forme d'un dictionnaire
  143 + * Returns the values of the combo boxes associated with this component.
  144 + * @returns {Object} An object with properties set to the values of the combo boxes.
200 145 */
201 146 getValues: function () {
202   - const value_scale = this.getForm().findField(this.plotFunctionItems.scale.name).getValue();
203   - const value_abscisse = this.getForm().findField(this.plotFunctionItems.abscisse.name).getValue();
204   - const value_scale_ordonnee = this.getForm().findField(this.plotFunctionItems.scale_ordonnee.name).getValue();
205   - const type_function = this.getForm().findField(this.plotFunctionItems.type.name).getValue();
  147 + let out = {
  148 + [this.functionComboBox]: this.getForm().findField(this.functionComboBox).getValue(),
  149 + [this.x_axis.value]: this.getForm().findField(this.x_axis.value).getValue(),
  150 + [this.y_axis.value]: this.getForm().findField(this.y_axis.value).getValue()
  151 + };
206 152  
207   - let out = {};
208   - out[this.plotFunctionItems.type.name] = type_function;
209   - out[this.plotFunctionItems.abscisse.name] = value_abscisse;
210   - out[this.plotFunctionItems.scale.name] = value_scale;
211   - out[this.plotFunctionItems.scale_ordonnee.name] = value_scale_ordonnee;
  153 + if (this.currentModule) {
  154 + Object.assign(out, this.currentModule.getValues());
  155 + }
212 156  
213 157 return out;
214 158 }
215   -});
216 159 \ No newline at end of file
  160 +});
  161 +
... ...
js/app/views/PlotComponents/plotFunction/Histogram.js 0 โ†’ 100644
... ... @@ -0,0 +1,106 @@
  1 +Ext.define('amdaPlotComp.plotFunction.Histogram', {
  2 + extend: 'amdaPlotComp.plotFunction.BaseComponent', // This class extends from amdaPlotComp.plotFunction.BaseComponent
  3 + title: "Histogram Arguments", // The title of this component
  4 +
  5 + // Define the IDs for the function, bins, and xMin and xMax fields
  6 + functionId: 'histo1d-function',
  7 + binsId: 'histo1d-xbinnumber',
  8 + xMinId: "histo1d-xmin",
  9 + xMaxId: 'histo1d-xmax',
  10 +
  11 +
  12 + /**
  13 + * Initializes the component.
  14 + * It creates a combo box for selecting the density type and number fields for entering the xMin, xMax, and number of bins.
  15 + */
  16 + initComponent: function () {
  17 + const self = this;
  18 +
  19 + // Define combo box store
  20 + const comboStore = Ext.create('Ext.data.Store', {
  21 + fields: ['label', 'value'],
  22 + data: [
  23 + { value: 'density', label: 'Density' },
  24 + { value: 'normdensity', label: 'Normalised Density' }
  25 + ]
  26 + });
  27 +
  28 + // Create combo box for selecting the density type
  29 + const densityTypeCombo = Ext.create('Ext.form.field.ComboBox', {
  30 + fieldLabel: 'Density Type',
  31 + name: self.functionId,
  32 + store: comboStore,
  33 + queryMode: 'local',
  34 + displayField: 'label',
  35 + valueField: 'value',
  36 + editable: false,
  37 + value: 'density'
  38 + });
  39 +
  40 + // Add items to the component
  41 + Ext.apply(self, {
  42 + items: [
  43 + {
  44 + xtype: 'numberfield',
  45 + fieldLabel: 'X Min',
  46 + name: self.xMinId,
  47 + allowDecimals: true,
  48 + hideTrigger: true,
  49 + keyNavEnabled: false,
  50 + value: self.xmin,
  51 + },
  52 + {
  53 + xtype: 'numberfield',
  54 + fieldLabel: 'X Max',
  55 + name: self.xMaxId,
  56 + allowDecimals: true,
  57 + hideTrigger: true,
  58 + keyNavEnabled: false,
  59 + value: self.xmax,
  60 + },
  61 + {
  62 + xtype: 'numberfield',
  63 + fieldLabel: 'Number of Bins',
  64 + name: self.binsId,
  65 + minValue: 1,
  66 + value: 100,
  67 + allowDecimals: false,
  68 + keyNavEnabled: false,
  69 + },
  70 + densityTypeCombo
  71 + ]
  72 + });
  73 +
  74 + // Call the parent class's initComponent method
  75 + self.callParent(arguments);
  76 + },
  77 +
  78 + /**
  79 + * Retrieves the selected values from the combo box and number fields.
  80 + * Returns an object with properties set to these values.
  81 + */
  82 + getValues: function () {
  83 + const densityTypeCombo = this.query('[name=' + this.functionId + ']')[0];
  84 + const densityTypeValue = densityTypeCombo.getValue();
  85 +
  86 + const numBinsField = this.query('[name=' + this.binsId + ']')[0];
  87 + const numBinsValue = numBinsField.getValue();
  88 +
  89 + const xMinField = this.query('[name=' + this.xMinId + ']')[0];
  90 + const xMinValue = xMinField.getValue();
  91 +
  92 + const xMaxField = this.query('[name=' + this.xMaxId + ']')[0];
  93 + const xMaxValue = xMaxField.getValue();
  94 +
  95 +
  96 + let out = {};
  97 +
  98 + out[this.functionId] = densityTypeValue;
  99 + out[this.binsId] = numBinsValue;
  100 + out[this.xMinId] = xMinValue;
  101 + out[this.xMaxId] = xMaxValue;
  102 + out['histo1d-yaxis'] = this.yAxis;
  103 +
  104 + return out;
  105 + }
  106 +});
... ...
js/app/views/PlotComponents/plotFunction/ParamField.js deleted
... ... @@ -1,124 +0,0 @@
1   -/**
2   - * Un composant de 'PlotFunction' qui permet d'afficher le min samplig de chaque paramรจtre et le nombre de points thรฉoriques entre un start time et stop time
3   - */
4   -Ext.define('amdaPlotComp.plotFunction.ParamField', {
5   - extend: 'Ext.form.Panel',
6   - /**
7   - * id du composant de type numberfield qui hรฉbรฉrge le min sampling
8   - */
9   - label_number_field: "NUMBERFIELD",
10   - /**
11   - * id du composant de type numberfield qui hรฉbรฉrge le nombre de points
12   - */
13   - label_number_field1: "NUMBERFIELD1",
14   - /**
15   - * Le composant parent de celui-ci
16   - */
17   - parent: null,
18   -
19   - initComponent: function () {
20   - const items_params = [];
21   - const minSampling = "Sampling Time (s)";
22   - const minValue = 0;
23   - const labelWitdh = 120;
24   - const width = 30;
25   -
26   - for (p in this.params) {
27   - const param = this.params[p];
28   - const fieldSet = {
29   - xtype: 'fieldset',
30   - name: 'FIELDSET' + param.id,
31   - title: param.id,
32   - collapsible: false,
33   - layout: {
34   - type: 'vbox',
35   - align: 'stretch',
36   - },
37   - items: [
38   - {
39   - xtype: 'numberfield',
40   - name: this.label_number_field + param.id,
41   - labelWidth: labelWitdh,
42   - width: width,
43   - value: param.MinSampling,
44   - minValue: minValue,
45   - disabled: true,
46   - fieldLabel: minSampling
47   - },
48   - {
49   - xtype: 'numberfield',
50   - name: this.label_number_field1 + param.id,
51   - labelWidth: labelWitdh,
52   - width: width,
53   - value: 0,
54   - minValue: minValue,
55   - fieldLabel: "Nb Points"
56   - }
57   - ]
58   - };
59   -
60   - items_params.push(fieldSet);
61   - }
62   -
63   - const tabParams = Ext.create('Ext.tab.Panel', {
64   - layout: 'fit',
65   - plain: true,
66   - bodyStyle: 'background: none',
67   - items: items_params
68   - });
69   -
70   - const config =
71   - {
72   - title: 'Parameters Sampling',
73   - layout: 'fit',
74   - bodyStyle: { background: '#dfe8f6' },
75   - items: [tabParams]
76   - };
77   -
78   - Ext.apply(this, config);
79   - //Les arguments sont les paramรจtres, chaque paramรจtre contient un id et un min Sampling
80   - this.callParent(arguments);
81   - },
82   -
83   - /**
84   - * Set parent
85   - * @param {*} parent_ le parent qui contient ce composant
86   - */
87   - setParent: function (parent_) {
88   - this.parent = parent_;
89   - },
90   -
91   - /**
92   - * Retourne les valeurs d'id, min sampling et nb_points de tout les parametres passรฉs comme argument
93   - * @returns id1@minSampling1@nb_points1@id2@minSampling2@nb_points2....
94   - */
95   - getValues: function () {
96   - let list = "";
97   - const delimeter = "@";
98   - let i = 0;
99   - for (p in this.params) {
100   - let param = this.params[p];
101   - const ui_item = this.parent.findField(this.label_number_field1 + param.id);
102   - if (i > 0) list += delimeter;
103   - if (ui_item !== undefined && ui_item !== null) {
104   - list += param.id + delimeter + param.MinSampling + delimeter + ui_item.getValue() + delimeter + "5";
105   - }
106   - i++;
107   - }
108   - return { "param_nb_points": list };
109   - },
110   -
111   - /**
112   - * Mettre ร  jour le nb_points en fonction de la valeur de start time et stop time passรฉs en paramรจtres
113   - * @param {*} startTime le start time issu du ZoomPlugin
114   - * @param {*} stopTime le stop time issu du ZoomPlugin
115   - */
116   - setValues: function (startTime, stopTime) {
117   - for (p in this.params) {
118   - let param = this.params[p];
119   - const nb_points = (stopTime.getTime() - startTime.getTime()) / (1000. * param.MinSampling);
120   - const ui_item = this.parent.findField(this.label_number_field1 + param.id);
121   - ui_item.setValue(parseInt(nb_points));
122   - }
123   - }
124   -});
js/app/views/PlotTabResultUI.js
... ... @@ -153,7 +153,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
153 153 me.contextualMenu.add({
154 154 text: 'Zoom on Time Axis',
155 155 handler: function (item, e) {
156   - zoomPlugin.show(me.interactiveId, axis.id, panelContext.id);
  156 + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id, panelContext);
157 157 zoomPlugin.resetMinMaxValue();
158 158 me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection);
159 159 },
... ... @@ -163,7 +163,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
163 163 plotFunctionItem = {
164 164 text: 'Apply a Function on Interval',
165 165 handler: function (item, e) {
166   - zoomPlugin.show(me.interactiveId, axis.id, panelContext.id, true);
  166 + zoomPlugin.show(me.interactiveId, "plotFunction", panelContext.id, panelContext);
167 167 zoomPlugin.resetMinMaxValue();
168 168 me.panelImage.startZoom(true, 0, size.height, onMinTimeSelection, onMaxTimeSelection);
169 169 },
... ... @@ -172,7 +172,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
172 172 insertIntervalItem = {
173 173 text: 'Insert Interval in TimeTable or Catalog',
174 174 handler: function (item, e) {
175   - zoomPlugin.show(me.interactiveId, axis.id, panelContext.id);
  175 + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id, panelContext);
176 176 zoomPlugin.resetMinMaxValue();
177 177 me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection);
178 178 },
... ... @@ -183,7 +183,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
183 183 me.contextualMenu.add({
184 184 text: 'Zoom on Y Left Axis',
185 185 handler: function (item, e) {
186   - zoomPlugin.show(me.interactiveId, axis.id, panelContext.id);
  186 + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id, panelContext);
187 187 zoomPlugin.resetMinMaxValue();
188 188 me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection);
189 189 }
... ... @@ -193,7 +193,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
193 193 me.contextualMenu.add({
194 194 text: 'Zoom on Y Right Axis',
195 195 handler: function (item, e) {
196   - zoomPlugin.show(me.interactiveId, axis.id, panelContext.id);
  196 + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id, panelContext);
197 197 zoomPlugin.resetMinMaxValue();
198 198 me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection);
199 199 }
... ... @@ -203,7 +203,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
203 203 me.contextualMenu.add({
204 204 text: 'Zoom on X Axis',
205 205 handler: function (item, e) {
206   - zoomPlugin.show(me.interactiveId, axis.id, panelContext.id);
  206 + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id, panelContext);
207 207 zoomPlugin.resetMinMaxValue();
208 208 me.panelImage.startZoom(true, me.toPixelOnResultImage(panelContext.y), me.toPixelOnResultImage(panelContext.height), onMinXValueSelection, onMaxXValueSelection);
209 209 }
... ... @@ -266,11 +266,11 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
266 266  
267 267 // Creating the value scale
268 268 var interval = (axis.max - axis.min) / ( colorListArray.length- 1);
269   - valuesListArray = new Array(colorListArray.length+1);
  269 + valuesListArray = new Array(colorListArray.length);
270 270  
271   - for(var i=0;i< colorListArray.length+1; i++)
  271 + for(var i=0;i< colorListArray.length; i++)
272 272 valuesListArray[i] = axis.min + i * interval;
273   -
  273 +
274 274 // Computation of the closest r,g,b values to the cursorColor
275 275 lowestChi = new Array(2);
276 276 for(var i=0;i< colorListArray.length; i++){
... ... @@ -285,10 +285,12 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
285 285 }
286 286  
287 287 // Returning values
288   -
289   - if(axis.logarithmic)
290   - return "[1e"+valuesListArray[lowestChi[0]].toFixed(3)+",1e"+valuesListArray[lowestChi[0]+1].toFixed(4)+"]";
291   - return "["+valuesListArray[lowestChi[0]].toFixed(4)+","+valuesListArray[lowestChi[0]+1].toFixed(4)+"]";
  288 + if (lowestChi[0] == 0)
  289 + return "<= "+(axis.logarithmic ? "1e" : "")+valuesListArray[lowestChi[0]+1].toFixed(3);
  290 + else if (lowestChi[0] == colorListArray.length- 1)
  291 + return ">= "+(axis.logarithmic ? "1e" : "")+valuesListArray[lowestChi[0]-1].toFixed(3);
  292 + else
  293 + return "~ "+(axis.logarithmic ? "1e" : "")+valuesListArray[lowestChi[0]].toFixed(3);
292 294 }
293 295 return "";
294 296 },
... ... @@ -502,7 +504,7 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
502 504 this.crtContext = configResult.context;
503 505  
504 506 var zoomPlugin = this.getPlugin('plot-zoom-plugin-id-'+this.interactiveId);
505   - if (zoomPlugin)
  507 + if (zoomPlugin && newPlot)
506 508 zoomPlugin.close();
507 509  
508 510 this.crtTTFileIndex = configResult.ttFileIndex;
... ... @@ -607,11 +609,10 @@ Ext.define(&#39;amdaUI.PlotTabResultUI&#39;, {
607 609 var ttFileIndex = this.crtTTFileIndex;
608 610 var ttintervalIndex = this.crtContext.page.ttIndex;
609 611  
610   - if (ttintervalIndex <= 0 && ttFileIndex > 0) {
  612 + --ttintervalIndex;
  613 + if(ttintervalIndex < 0)
611 614 --ttFileIndex;
612   - }
613   - else
614   - --ttintervalIndex;
  615 +
615 616 this.callInteractivePlot({ 'action': 'goto', 'interactiveId': this.interactiveId, 'ttFileIndex': ttFileIndex, 'intIndex': ttintervalIndex });
616 617 }
617 618 },
... ...
js/app/views/StandardFloatField.js 0 โ†’ 100644
... ... @@ -0,0 +1,34 @@
  1 +Ext.define('amdaUI.StandardFloatField', {
  2 + extend: 'Ext.form.field.Text',
  3 +
  4 + xtype: 'standardfloatfield',
  5 +
  6 + // Additional configurations and custom logic can be added here
  7 + regex: /[-+]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][-+]?\d+)?/,
  8 + min:-Number.MAX_VALUE,
  9 + max: Number.MAX_VALUE,
  10 +
  11 + initComponent: function () {
  12 + this.callParent();
  13 +
  14 + // Set up validation and change event handling
  15 + this.validator = this.createValidator();
  16 + },
  17 +
  18 + createValidator: function () {
  19 + var me = this;
  20 +
  21 + return function (val) {
  22 + var errMsg = null;
  23 + if (!me.allowBlank && Ext.isEmpty(val)) {
  24 + errMsg = 'Blank value not allowed';
  25 + } else if ((typeof me.min !== 'undefined' && me.min !== null) && (parseFloat(val) < me.min)) {
  26 + errMsg = 'Min. allowed value is ' + me.min;
  27 + } else if ((typeof me.max !== 'undefined' && me.max !== null) && (parseFloat(val) > me.max)) {
  28 + errMsg = 'Max. allowed value is ' + me.max;
  29 + }
  30 +
  31 + return errMsg ? errMsg : true;
  32 + };
  33 + },
  34 +});
... ...
js/app/views/TimeTableUI.js
... ... @@ -16,6 +16,7 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
16 16 'Ext.ux.grid.FiltersFeature',
17 17 'Ext.ux.grid.filter.DateFilter',
18 18 'Ext.ux.grid.filter.NumericFilter',
  19 + 'amdaUI.CustomFilters',
19 20 'amdaUI.OperationsTT',
20 21 'amdaUI.StatisticalPlug',
21 22 'amdaUI.DescriptionField',
... ... @@ -399,6 +400,7 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
399 400  
400 401 init: function (config)
401 402 {
  403 + amdaUI.CustomFilters.init();
402 404 this.object = config.object;
403 405  
404 406 this.fieldName = new Ext.form.field.Text({
... ... @@ -508,12 +510,12 @@ Ext.define(&#39;amdaUI.TimeTableUI&#39;, {
508 510 encode: true, // json encode the filter query
509 511 local: false, // defaults to false (remote filte
510 512 filters: [
511   - {type: 'numeric', dataIndex: 'durationDay'},
512   - {type: 'numeric', dataIndex: 'durationHour'},
513   - {type: 'numeric', dataIndex: 'durationMin'},
514   - {type: 'numeric', dataIndex: 'durationSec'},
515   - {type: 'date', dataIndex: 'start', dateFormat: 'c'},
516   - {type: 'date', dataIndex: 'stop', dateFormat: 'c'}
  513 + {type: 'customnumericfilter', dataIndex: 'durationDay'},
  514 + {type: 'customnumericfilter', dataIndex: 'durationHour'},
  515 + {type: 'customnumericfilter', dataIndex: 'durationMin'},
  516 + {type: 'customnumericfilter', dataIndex: 'durationSec'},
  517 + {type: 'customdatefilter', dataIndex: 'start', dateFormat: 'c'},
  518 + {type: 'customdatefilter', dataIndex: 'stop', dateFormat: 'c'}
517 519 ]
518 520 };
519 521 var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', {
... ...
js/app/views/VisuUI.js
... ... @@ -131,12 +131,19 @@ Ext.define(&#39;amdaUI.VisuUI&#39;, {
131 131  
132 132 me.reset();
133 133 }
134   -
  134 + var type = "";
  135 + if(this.object.get('id').includes('sharedcatalog'))
  136 + type = 'sharedcatalog'
  137 + else if(this.object.get('id') == "")
  138 + type = 'uploaded'
  139 + else
  140 + type = 'object'
135 141 var opt = {
136 142 'typeTT': 'catalog', 'id': this.object.get('id'),
137   - 'name': this.object.get('name')
  143 + 'name': this.object.get('name'),
  144 + 'type': type,
  145 + 'format': this.object.get('objFormat')
138 146 };
139   -
140 147 this.formPanel.getForm().loadRecord(this.object);
141 148 AmdaAction.readIntervalsForChart(opt, onAfterInit);
142 149 },
... ...
php/WebServices/WebServer.php
... ... @@ -50,7 +50,11 @@ class WebServer
50 50 $this->userPWD = $vars['password'];
51 51 else
52 52 $this->userPWD = WSConfigClass::getAnonymousUserPwd();
53   -
  53 +
  54 + if (isset($vars['referenceTime']))
  55 + $this->referenceTime = $vars['referenceTime'];
  56 + else
  57 + $this->referenceTime = NULL;
54 58 return array('success' => true, 'vars' => $vars);
55 59 }
56 60  
... ... @@ -114,6 +118,12 @@ class WebServer
114 118  
115 119 return $dataSetDom;
116 120 }
  121 +
  122 + private function getUserInfo($data)
  123 + {
  124 + $res = $this->init($data);
  125 + $this->initUserMgr();
  126 + }
117 127  
118 128 /*
119 129 * get user TimeTables list; Shared for anonymous user ('impex')
... ... @@ -327,6 +337,42 @@ class WebServer
327 337 if (!$locParamSrcDom->save(WSConfigClass::getWsResultDir().$locParamDst))
328 338 $this->throwError('workspaceError', 'Cannot save Amda Local DataBase Parameters description file'.$this->userID);
329 339 }
  340 +
  341 + private function injectTemplateInfo($locParamFile) {
  342 + $paramTemplateListFile = WSConfigClass::getParamTemplateListFilePath();
  343 +
  344 + $paramTemplateListFileDom = new DomDocument("1.0");
  345 + if (!@$paramTemplateListFileDom->load($paramTemplateListFile))
  346 + $this->throwError("getObsDataTree", "Cannot load Amda Templated Parameters description file".$this->userID);
  347 +
  348 + $paramTemplateNodes = $paramTemplateListFileDom->getElementsByTagName('paramTemplate');
  349 +
  350 + $locParamFileDom = new DomDocument("1.0");
  351 + $locParamFileDom->preserveWhiteSpace = FALSE; /// Important !!! otherwise removeChild() leaves empty text nodes
  352 +
  353 + if (!@$locParamFileDom->load(WSConfigClass::getWsResultDir().$locParamFile))
  354 + $this->throwError("getObsDataTree", "Cannot load Amda Local DataBase Parameters description file ".$this->userID);
  355 +
  356 + $xp = new domxpath($locParamFileDom);
  357 +
  358 + foreach ($paramTemplateNodes as $paramTemplateNode) {
  359 + $paramTemplateId = $paramTemplateNode->getAttribute('paramId');
  360 + $paramFileName = $paramTemplateNode->getAttribute('fileName');
  361 + $parameterNodes = $xp->query("//parameter[@template='$paramFileName']");
  362 + $argumentsNodes = $paramTemplateNode->getElementsByTagName("arguments");
  363 + if ($argumentsNodes->length < 1)
  364 + continue;
  365 + $argumentsNode = $argumentsNodes->item(0);
  366 + foreach ($parameterNodes as $parameterNode) {
  367 + $node = $locParamFileDom->importNode($argumentsNode, TRUE);
  368 + $parameterNode->appendChild($node);
  369 + }
  370 + }
  371 +
  372 +
  373 + if (!$locParamFileDom->save(WSConfigClass::getWsResultDir().$locParamFile))
  374 + $this->throwError('workspaceError', 'Cannot save Amda Local DataBase Parameters description file'.$this->userID);
  375 + }
330 376  
331 377 private function checkInputTime($startTime, $stopTime)
332 378 {
... ... @@ -349,19 +395,26 @@ class WebServer
349 395 /*
350 396 * public data only : anonymous user (impex)
351 397 */
352   - public function getObsDataTree()
  398 + public function getObsDataTree($data)
353 399 {
354   - $res = $this->init();
  400 + $res = $this->init($data);
355 401 $this->initUserMgr();
  402 +
  403 + $injectTemplateInfo = array_key_exists('templateInfo', $data) && (!empty($data["templateInfo"]));
356 404  
357 405 $locParamSrc = USERWSDIR.'LocalParams.xml';
358 406  
359   - $locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml';
  407 + $locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.($injectTemplateInfo ? 'withtemplate_' : '').$this->requestTime.'_AmdaLocalDataBaseParameters.xml';
360 408  
361 409 // if (!copy($locParamSrc,WSConfigClass::getWsResultDir().$locParamDst))
362 410 // $this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file');
363 411  
364 412 $this->excludePrivateNodes($locParamSrc,$locParamDst);
  413 +
  414 + if ($injectTemplateInfo) {
  415 + $this->injectTemplateInfo($locParamDst);
  416 + }
  417 +
365 418 return array('success' => true,'WorkSpace' => array("LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst));
366 419 }
367 420  
... ...
php/classes/APISMgr.php
... ... @@ -27,7 +27,7 @@
27 27  
28 28 function get($planet, $startTime, $stopTime, $datasets = null)
29 29 {
30   - $planetNewName = ucfirst($planet);
  30 + $planetNewName = ucfirst($planet);
31 31 list($y, $mo, $d, $h, $mi, $s) = sscanf($startTime,"%4d-%02d-%02dT%02d:%02d:%02d");
32 32 $start = mktime($h,$mi,$s,$mo,$d,$y);
33 33  
... ... @@ -37,10 +37,11 @@
37 37 $req = "SELECT * FROM apis.epn_core";
38 38 $req .= " WHERE target_name='".$planetNewName."'";
39 39 $req .= " AND dataproduct_type='im'";
40   - $req .= " AND time_min>".$this->jday($start);
  40 + $req .= " AND access_format='image/fits'";
  41 + $req .= " AND time_min>".$this->jday($start);
41 42 $req .= " AND time_min<".$this->jday($stop);
42   -
43   - if (isset($datasets) && !in_array("all",$datasets))
  43 +
  44 + if (isset($datasets) && !in_array("all",$datasets))
44 45 {
45 46 $req .= " AND (";
46 47 $firstDatasetId = true;
... ... @@ -72,7 +73,7 @@
72 73 curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
73 74 $req_res = curl_exec($curl);
74 75 curl_close($curl);
75   -
  76 +
76 77 if (!$req_res)
77 78 return array('success' => false, 'message' => 'Error during TAP request');
78 79  
... ...
php/classes/AmdaAction.php
... ... @@ -189,9 +189,13 @@ class AmdaAction
189 189 case 'catalog':
190 190 if ($isLeaf) {
191 191 $info = '<b>Nb intervals:</b> '.$child->getAttribute('intervals').'<br/>';
192   -
193 192 $objectMgr = new TimeTableMgr();
  193 +
194 194 $obj_info = $objectMgr->getObject($id, $nodeType);
  195 +
  196 + if($nodeType == "catalog")
  197 + $info .='<b>Nb columns:</b> '.$obj_info['nbParam']. '<br/>';
  198 +
195 199 if (!empty($obj_info) && !empty($obj_info['description'])) {
196 200 $info .= '<b>Description:</b> '. $obj_info['description'] . '<br/>';
197 201 }
... ... @@ -299,10 +303,10 @@ class AmdaAction
299 303  
300 304 if ($child->tagName == 'parameter') {
301 305 $isParameter = true;
302   - if ($child->hasAttribute('TemplatedParameter'))
  306 + if ($child->hasAttribute('template'))
303 307 $needsArgs = true;
304 308  
305   - if ($child->hasAttribute('PredefinedTemplatedParameter'))
  309 + if ($child->hasAttribute('predefined'))
306 310 $predefinedArgs = true;
307 311  
308 312 if ($child->parentNode->hasAttribute('dataStart')) {
... ... @@ -1229,7 +1233,10 @@ class AmdaAction
1229 1233 public function readIntervalsForChart($o)
1230 1234 {
1231 1235 $objMgr = new CatalogCacheMgr(TRUE);
1232   - $objMgr->initFromObject($o->id, $o->type);
  1236 + if($o->type == 'uploaded')
  1237 + $objMgr->initFromUploadedFile($o->name, $o->format);
  1238 + else
  1239 + $objMgr->initFromObject($o->id, $o->type);
1233 1240 return $objMgr->getIntervalsForChart();
1234 1241 }
1235 1242  
... ...
php/classes/AmdaNews.php
... ... @@ -7,7 +7,7 @@ class AmdaNews {
7 7  
8 8 public $user, $userdir, $infodir;
9 9  
10   - public function __construct($user) {
  10 + public function __construct($user = "") {
11 11 if ($user) {
12 12 $this->user = $user;
13 13 $this->userdir = USERPATH."/".$user."/";
... ... @@ -19,7 +19,6 @@ class AmdaNews {
19 19 * Add new info message and mark user dir with newInfo file
20 20 */
21 21 public function addInfo($group){
22   -
23 22 // special dir for group news
24 23 if ($group) $this->infodir = BASE_PATH.'help/'.$group.'_INFO/';
25 24 else $this->infodir = BASE_PATH.'help/INFO/';
... ... @@ -56,7 +55,6 @@ class AmdaNews {
56 55 * Concate individual info messages into one to be shown to user
57 56 */
58 57 public function makeInfo($groups){
59   -
60 58 if (file_exists($this->userdir.'lastLogin')) {
61 59  
62 60 $timeStamp = filemtime($this->userdir.'lastLogin');
... ...
php/classes/CatalogCacheFilterObject.php
... ... @@ -47,9 +47,9 @@ class CatalogCacheFilterPartObject extends TimeTableCacheFilterPartObject
47 47 $param_value = floatval($params[$this->paramId]);
48 48 switch ($this->op) {
49 49 case self::$OPERATION_LT :
50   - return ($param_value < $this->value);
51   - case self::$OPERATION_GT :
52 50 return ($param_value > $this->value);
  51 + case self::$OPERATION_GT :
  52 + return ($param_value < $this->value);
53 53 case self::$OPERATION_EQ :
54 54 return ($param_value != $this->value);
55 55 default :
... ... @@ -62,9 +62,9 @@ class CatalogCacheFilterPartObject extends TimeTableCacheFilterPartObject
62 62 $param_value = intval($params[$this->paramId]);
63 63 switch ($this->op) {
64 64 case self::$OPERATION_LT :
65   - return ($param_value < $this->value);
66   - case self::$OPERATION_GT :
67 65 return ($param_value > $this->value);
  66 + case self::$OPERATION_GT :
  67 + return ($param_value < $this->value);
68 68 case self::$OPERATION_EQ :
69 69 return (!(($param_value >= $this->value) && ($param_value <= $this->value+86400)));
70 70 default :
... ... @@ -84,9 +84,9 @@ class CatalogCacheFilterPartObject extends TimeTableCacheFilterPartObject
84 84 $param_value = intval($params[$this->paramId]);
85 85 switch ($this->op) {
86 86 case self::$OPERATION_LT :
87   - return ($param_value < $this->value);
88   - case self::$OPERATION_GT :
89 87 return ($param_value > $this->value);
  88 + case self::$OPERATION_GT :
  89 + return ($param_value < $this->value);
90 90 case self::$OPERATION_EQ :
91 91 return ($param_value != $this->value);
92 92 default :
... ...
php/classes/SharedObjectHeaderFile.php
... ... @@ -117,7 +117,7 @@ class SharedObjectHeaderFile {
117 117 if (count($infoNodes) == 0)
118 118 return "";
119 119  
120   - $infoNodes->item(0)->nodeValue = $infoValue;
  120 + $infoNodes->item(0)->textContent = $infoValue;
121 121  
122 122 $this->doc->save($this->filePath);
123 123 }
... ...
php/classes/TimeTableMgr.php
... ... @@ -74,8 +74,14 @@ class TimeTableMgr extends AmdaObjectMgr
74 74 $attributes = $objToGet->childNodes;
75 75  
76 76 $nbInt = 0;
  77 + $nbParam = 0;
77 78 foreach ($attributes as $attribute) {
78 79 if ($attribute->nodeType == XML_ELEMENT_NODE) {
  80 + if($attribute->tagName == 'parameters'){
  81 + foreach($attribute->childNodes as $parameter){
  82 + $nbParam++;
  83 + }
  84 + }
79 85 /*if ($attribute->tagName == 'intervals') {
80 86 $start = $attribute -> getElementsByTagName('start')->item(0) -> nodeValue;
81 87 $stop = $attribute -> getElementsByTagName('stop')->item(0) -> nodeValue;
... ... @@ -116,6 +122,7 @@ class TimeTableMgr extends AmdaObjectMgr
116 122 if($attributesToReturn['surveyStop'] == "" )
117 123 $attributesToReturn['surveyStop'] = $stop;
118 124 $attributesToReturn['nbIntervals'] = $nbInt;
  125 + $attributesToReturn['nbParam'] = $nbParam;
119 126  
120 127 return $attributesToReturn;
121 128 }
... ... @@ -541,6 +548,14 @@ class TimeTableMgr extends AmdaObjectMgr
541 548 $this->objectDom->documentElement->appendChild($newInterval);
542 549 }
543 550  
  551 + // Update SurveyStart & SurveyStop
  552 + $surveyStartNodes = $objToGet->getElementsByTagName('surveyStart');
  553 + $surveyStopNodes = $objToGet->getElementsByTagName('surveyStop');
  554 + if ($surveyStartNodes->length > 0 && $surveyStopNodes->length > 0) {
  555 + $surveyStartNodes->item(0)->nodeValue = TimeUtils::stamp2iso($minStart);
  556 + $surveyStopNodes->item(0)->nodeValue = TimeUtils::stamp2iso($maxStop);
  557 + }
  558 +
544 559 //save modifications
545 560 $this->id = $id;
546 561 $this->resFileName = USERTTDIR . $this->id . '.xml';
... ... @@ -756,7 +771,7 @@ class TimeTableMgr extends AmdaObjectMgr
756 771 $descriptionNode = $descriptionNodes->item(0);
757 772 }
758 773  
759   - $descriptionNode->nodeValue = $newDescription;
  774 + $descriptionNode->textContent = $newDescription;
760 775 }
761 776  
762 777 $dstFilePath = $dst_path . "/" . $newId . ".xml";
... ...
php/classes/UserMgr.php
... ... @@ -294,7 +294,7 @@ class UserMgr
294 294 $init_res = $this->paramMgr->init();
295 295  
296 296 $this->baseExtXml = new DomDocument("1.0");
297   -
  297 +
298 298 if ($init_res['success']) { // USERWSDIR.'RemoteParams.xml' exists
299 299 // check/change access rights
300 300 $basesWS = $this->paramMgr->xmlDom->getElementsByTagName('dataCenter'); // RemoteParams.xml
... ... @@ -565,6 +565,12 @@ class UserMgr
565 565  
566 566 $loginCommd = "DDHtmlLogin ".$this->user." ".$this->passwd." ".$this->IP;
567 567 system($loginCommd, $res);
  568 +
  569 + if ($this->isGuest && ($res != 0)) {
  570 + $guest = new Guest($this->user);
  571 + $guest->deleteGuest();
  572 + }
  573 +
568 574  
569 575 return $res;
570 576 }
... ...
php/config.php
... ... @@ -19,6 +19,9 @@ error_reporting(E_ERROR);
19 19 # Load AMDA_Integration config
20 20 require_once(INTEGRATION_BASE_PATH.'/config/AMDAIntegrationConfig.php');
21 21  
  22 +//Version
  23 +define('AMDA_IHM_VERSION','2.1.0');
  24 +
22 25 //AKKA - For compatibility with IHM
23 26 define('BASE_PATH', IHM_SRC_DIR."/");
24 27 define('AMDA_IHM', IHM_SRC_DIR."/");
... ... @@ -50,7 +53,7 @@ define(&#39;DISK_QUOTA_standard&#39;, 1024*1024*200); // 200MB
50 53 define('MAX_FILE_INDEX_TO_SHOW', 100);
51 54  
52 55 // EPN-TAP services
53   -define('EPNTAP_APIS', 'http://voparis-tap.obspm.fr/__system__/tap/run/tap/sync');
  56 +define('EPNTAP_APIS', 'http://voparis-tap-planeto.obspm.fr/__system__/tap/run/sync');
54 57 define('EPNTAP_AMDA', 'http://cdpp-epntap.irap.omp.eu/__system__/tap/run/tap/sync');
55 58  
56 59 // PHP run-time settings
... ...
php/downloadPlot.php
... ... @@ -62,7 +62,12 @@ function download_plot($sessionId, $interactiveId, $preview, $preview_function)
62 62 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
63 63 header("Cache-Control: private",false); // required for certain browsers
64 64 header("Content-Type: $ctype");
65   - header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
  65 + $newName ;
  66 + preg_match('/(\d+)/', basename($fullPath), $matches);
  67 + if (isset($matches[0])) {
  68 + $newName = str_replace('.png', '_'.date('YmdHis').'.png', str_replace($matches[0], (string)$matches[0]+1, basename($fullPath)));
  69 + }
  70 + header("Content-Disposition: attachment; filename=\"".$newName."\";" );
66 71 header("Content-Transfer-Encoding: binary");
67 72 header("Content-Length: ".$fsize);
68 73 ob_clean();
... ...
php/rest/getObsDataTree.php
... ... @@ -5,6 +5,10 @@
5 5 * @apiDescription Provides the hierarchy of public access data in AMDA.
6 6 * @apiName getObsDataTree
7 7 * @apiGroup webservices
  8 + *
  9 + * @apiParam {String} [userID] Identifier of the user in AMDA (*mandatory for user owned data*)
  10 + * @apiParam {String} [password] Password of the user in AMDA (*mandatory for user owned data*)
  11 + * @apiParam {Boolean} [templateInfo] `1` to include info about templated parameters - Default `0`.
8 12 *
9 13 * @apiSuccess {String} success true.
10 14 * @apiSuccess {String} workspace URL of the XML file containing the list of "public" parameters in AMDA.
... ...