Commit 21e0d0c4a31013fe8e4734f4e9d6a278a34df474
Exists in
master
and in
100 other branches
Merge branch 'master' of https://gitlab.irap.omp.eu/CDPP/AMDA_IHM
Showing
8 changed files
with
218 additions
and
28 deletions
Show diff stats
... | ... | @@ -0,0 +1,8 @@ |
1 | +<h2>Catalogue statistical information</h2> | |
2 | +When hitting the <b>"Apply"</b> button the following data on the edited catalogue are computed from the list of intervals :</br></br> | |
3 | +<ul> | |
4 | +<li>The <b>minimum</b> and <b>maximum</b> durations with corresponding intervals (following the '--' signs)</li></br> | |
5 | +<li>The <b>mean</b>, <b>the standard deviation (St. dev)</b> and the <b>median</b> of interval durations</li><br/> | |
6 | +<li>The <b>density</b> of the catalogue in the global time span : this is the ratio of the sum of all interval durations over the global time span, i.e. the duration of the interval starting with the min 'Start' and finishing with the max 'Stop'.</li> | |
7 | +</ul> | |
8 | +The <b>density</b> is an indication of the occurrence frequency of the event described in a catalogue. | |
... | ... |
help/statisticalHelp renamed to help/statisticalHelptimeTableUi
js/app/views/CatalogUI.js
... | ... | @@ -12,10 +12,14 @@ Ext.define('amdaUI.CatalogUI', { |
12 | 12 | alias: 'widget.panelCatalog', |
13 | 13 | |
14 | 14 | requires: [ |
15 | - 'Ext.grid.plugin.BufferedRenderer' | |
15 | + 'Ext.grid.plugin.BufferedRenderer', | |
16 | + 'amdaUI.StatisticalPlug' | |
16 | 17 | ], |
17 | 18 | |
18 | 19 | isCatalog : true, |
20 | + statics: { | |
21 | + COL_TO_HIDE_DURATION : 'colToHideDuration' | |
22 | + }, | |
19 | 23 | |
20 | 24 | constructor: function(config) { |
21 | 25 | this.init(config); |
... | ... | @@ -34,6 +38,20 @@ Ext.define('amdaUI.CatalogUI', { |
34 | 38 | this.object = object; |
35 | 39 | // load object into view |
36 | 40 | this.loadObject(); |
41 | + // show the default duration column | |
42 | + this.TTGrid.headerCt.getGridColumns(); | |
43 | + | |
44 | + Ext.Array.each(this.TTGrid.headerCt.getGridColumns(), function(item,index,all){ | |
45 | + // if item is the default duration column | |
46 | + if ( item.id == amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'2' ) { | |
47 | + // show this column | |
48 | + item.show(); | |
49 | + } | |
50 | + }); | |
51 | + // fire the refresh event (to statistical plugin) | |
52 | + this.fireEvent("refresh"); | |
53 | + // global event | |
54 | + myDesktopApp.EventManager.fireEvent("refresh"); | |
37 | 55 | }, |
38 | 56 | |
39 | 57 | /** |
... | ... | @@ -102,14 +120,72 @@ Ext.define('amdaUI.CatalogUI', { |
102 | 120 | |
103 | 121 | if (me.toReconfigure) |
104 | 122 | { |
105 | - var fields = [], columns = [], i = 3, width, index; | |
123 | + var fields = [], columns = [], width, index; | |
124 | + var fieldsConfig = [ | |
125 | + { name : 'start', | |
126 | + convert: function(value,rec) { | |
127 | + if (!Ext.isDate(value)){ | |
128 | + var valueString = new String(value); | |
129 | + var date = new Date(valueString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | |
130 | + return Ext.Date.format(date,'Y-m-d\\TH:i:s'); | |
131 | + } | |
132 | + return value; | |
133 | + } | |
134 | + }, | |
135 | + { name : 'stop', | |
136 | + convert: function(value,rec) { | |
137 | + if (!Ext.isDate(value)){ | |
138 | + var valueString = new String(value); | |
139 | + var date = new Date(valueString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | |
140 | + | |
141 | + return Ext.Date.format(date,'Y-m-d\\TH:i:s'); | |
142 | + } | |
143 | + return value; | |
144 | + } | |
145 | + }, | |
146 | + {name:'durationHour', | |
147 | + convert: function(value, rec){ | |
148 | + starteDate=rec.get('start') ;stopDate=rec.get('stop') ; | |
149 | + | |
150 | + d1=new Date(rec.get('start')); | |
151 | + d2=new Date(rec.get('stop')); | |
152 | + if (d1 && d2 && (d2-d1>=0)) { | |
153 | + return (d2-d1)/3600000.0; | |
154 | + } | |
155 | + }, | |
156 | + }, | |
157 | + { | |
158 | + name: 'durationMin', | |
159 | + type: 'float', | |
160 | + convert: function(value, rec){ | |
161 | + d1=new Date(rec.get('start')); | |
162 | + d2=new Date(rec.get('stop')); | |
163 | + if (d1 && d2 && (d2-d1>=0)) { | |
164 | + return (d2-d1)/60000.0; | |
165 | + } | |
166 | + }, | |
167 | + persist: false, | |
168 | + | |
169 | + }, | |
170 | + { | |
171 | + name: 'durationSec', | |
172 | + type: 'float', | |
173 | + convert: function(value, rec){ | |
174 | + d1=new Date(rec.get('start')); | |
175 | + d2=new Date(rec.get('stop')); | |
176 | + if (d1 && d2 && (d2-d1>=0)) { | |
177 | + return (d2-d1)/1000.0; | |
178 | + } | |
179 | + }, | |
180 | + persist: false, | |
181 | + | |
182 | + }, | |
183 | + { name: 'cacheId', type : 'int'}, | |
184 | + { name: 'isNew', type : 'boolean', defaultValue: false }, | |
185 | + { name: 'isModified', type : 'boolean', defaultValue: false} | |
186 | + ]; | |
106 | 187 | |
107 | - var fieldsConfig = [{ name : 'start' },{ name : 'stop' },{ name: 'cacheId', type : 'int'}, | |
108 | - { name: 'isNew', type : 'boolean', defaultValue: false }, | |
109 | - { name: 'isModified', type : 'boolean', defaultValue: false} | |
110 | - ]; | |
111 | 188 | |
112 | - for (var j = 0; j < 5; j++) fields[j] = Ext.create('Ext.data.Field', fieldsConfig[j]); | |
113 | 189 | |
114 | 190 | columns[0] = Ext.create('Ext.grid.column.RowNumberer', { width: 50, |
115 | 191 | renderer: function(value, metaData, record){ |
... | ... | @@ -121,15 +197,81 @@ Ext.define('amdaUI.CatalogUI', { |
121 | 197 | return msg; |
122 | 198 | } |
123 | 199 | }); |
124 | - | |
125 | 200 | columns[1] = Ext.create('Ext.grid.column.Column', { text: 'Start Time', sortable : true, dataIndex: 'start', |
126 | 201 | width : 120, menuDisabled: false, editor : { xtype:'datefield', allowBlank:false, hideTrigger: true, format : 'Y-m-d\\TH:i:s'}}); |
127 | 202 | columns[2] = Ext.create('Ext.grid.column.Column', { text: 'Stop Time', sortable : true, dataIndex: 'stop', |
128 | 203 | width : 120, menuDisabled: false, editor : { xtype:'datefield', allowBlank:false, hideTrigger: true, format : 'Y-m-d\\TH:i:s'}}); |
129 | - | |
204 | + columns[3] = Ext.create('Ext.grid.column.Column', { text: 'Duration (hour)', sortable : true, dataIndex: 'durationHour', | |
205 | + width : 120, menuDisabled: false, | |
206 | + hidden:true, | |
207 | + id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'1', | |
208 | + renderer: function(value) { | |
209 | + return Ext.util.Format.number(value,'0.00'); | |
210 | + }, | |
211 | + listeners: { | |
212 | + beforeshow : function(){ | |
213 | + Ext.Array.each(this.ownerCt.getGridColumns(), function(item,index,all){ | |
214 | + // if item is a column to hide automatically | |
215 | + if ( Ext.util.Format.substr(item.id, 0, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length) == amdaUI.CatalogUI.COL_TO_HIDE_DURATION ) { | |
216 | + // if item isn't the column which is being declared and is not hidden | |
217 | + if ( item.id != amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'1' && !item.isHidden() ){ | |
218 | + // hide this column | |
219 | + item.hide(); | |
220 | + } | |
221 | + } | |
222 | + }); | |
223 | + } | |
224 | + }}); | |
225 | + columns[4] = Ext.create('Ext.grid.column.Column', { text: 'Duration (Min)', sortable : true, dataIndex: 'durationMin', | |
226 | + width : 120, menuDisabled: false, | |
227 | + hidden:false, | |
228 | + id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'2', | |
229 | + renderer: function(value) { | |
230 | + return Ext.util.Format.number(value,'0.00'); | |
231 | + }, | |
232 | + listeners: { | |
233 | + beforeshow : function(){ | |
234 | + Ext.Array.each(this.ownerCt.getGridColumns(), function(item,index,all){ | |
235 | + // if item is a column to hide automatically | |
236 | + if ( Ext.util.Format.substr(item.id, 0, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length) == amdaUI.CatalogUI.COL_TO_HIDE_DURATION ) { | |
237 | + // if item isn't the column which is being declared and is not hidden | |
238 | + if ( item.id != amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'2' && !item.isHidden() ){ | |
239 | + // hide this column | |
240 | + item.hide(); | |
241 | + } | |
242 | + } | |
243 | + }); | |
244 | + } | |
245 | + }}); | |
246 | + columns[5] = Ext.create('Ext.grid.column.Column', { text: 'Duration (Sec)', sortable : true, dataIndex: 'durationSec', | |
247 | + width : 120, menuDisabled: false,hidden:true, | |
248 | + id: amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'3', | |
249 | + renderer: function(value) { | |
250 | + return Ext.util.Format.number(value,'0.00'); | |
251 | + }, | |
252 | + listeners: { | |
253 | + beforeshow : function(){ | |
254 | + Ext.Array.each(this.ownerCt.getGridColumns(), function(item,index,all){ | |
255 | + // if item is a column to hide automatically | |
256 | + if ( Ext.util.Format.substr(item.id, 0, amdaUI.CatalogUI.COL_TO_HIDE_DURATION.length) == amdaUI.CatalogUI.COL_TO_HIDE_DURATION ) { | |
257 | + // if item isn't the column which is being declared and is not hidden | |
258 | + if ( item.id != amdaUI.CatalogUI.COL_TO_HIDE_DURATION+'3' && !item.isHidden() ){ | |
259 | + // hide this column | |
260 | + item.hide(); | |
261 | + } | |
262 | + } | |
263 | + }); | |
264 | + } | |
265 | + } | |
266 | + }); | |
267 | + | |
268 | + i=columns.length | |
269 | + columsTotalNumber=columns.length+2 | |
270 | + for (var j = 0; j < columsTotalNumber; j++) fields[j] = Ext.create('Ext.data.Field', fieldsConfig[j]); | |
271 | + | |
130 | 272 | Ext.Array.each(result.parameters, function(obj) |
131 | 273 | { |
132 | - index = 'param'+(i-1).toString(); | |
274 | + index = 'param'+(i-4).toString(); | |
133 | 275 | |
134 | 276 | fields[i+2] = Ext.create('Ext.data.Field',{ name : index }); |
135 | 277 | |
... | ... | @@ -146,7 +288,6 @@ Ext.define('amdaUI.CatalogUI', { |
146 | 288 | } |
147 | 289 | i++; |
148 | 290 | }); |
149 | - | |
150 | 291 | var store = Ext.create('Ext.data.Store', { |
151 | 292 | fields: fields, |
152 | 293 | autoDestroy: false, |
... | ... | @@ -173,8 +314,8 @@ Ext.define('amdaUI.CatalogUI', { |
173 | 314 | me.TTGrid.getView().refresh(); |
174 | 315 | me.TTGrid.getSelectionModel().refresh(); |
175 | 316 | me.updateCount(); |
176 | - //Statistical plugin | |
177 | - // this.fireEvent("refresh"); | |
317 | + //Statistical plugin | |
318 | + this.fireEvent("refresh"); | |
178 | 319 | } |
179 | 320 | } |
180 | 321 | }); |
... | ... | @@ -196,6 +337,8 @@ Ext.define('amdaUI.CatalogUI', { |
196 | 337 | me.TTGrid.getStore().load(); |
197 | 338 | |
198 | 339 | me.status = result.status; |
340 | + //Statistical plugin | |
341 | + me.fireEvent("refresh"); | |
199 | 342 | }, |
200 | 343 | |
201 | 344 | /** |
... | ... | @@ -228,6 +371,8 @@ Ext.define('amdaUI.CatalogUI', { |
228 | 371 | AmdaAction.initTTCacheFromTT(this.object.get('id'), typeTT, this.onAfterInit, this); |
229 | 372 | } |
230 | 373 | } |
374 | + //Statistical plugin | |
375 | + this.fireEvent("refresh"); | |
231 | 376 | }, |
232 | 377 | |
233 | 378 | checkIntervalsStatusForSave : function(onStatusOk) { |
... | ... | @@ -510,6 +655,7 @@ Ext.define('amdaUI.CatalogUI', { |
510 | 655 | } |
511 | 656 | }] |
512 | 657 | }, |
658 | + | |
513 | 659 | { |
514 | 660 | xtype: 'toolbar', |
515 | 661 | dock: 'bottom', |
... | ... | @@ -603,7 +749,25 @@ Ext.define('amdaUI.CatalogUI', { |
603 | 749 | // }); |
604 | 750 | // } |
605 | 751 | // }, |
606 | - { | |
752 | + | |
753 | + ] | |
754 | + }, | |
755 | + //statistical info | |
756 | + { | |
757 | + xtype: 'toolbar', | |
758 | + dock: 'bottom', | |
759 | + ui: 'footer', | |
760 | + items:[{ | |
761 | + xtype: 'button', | |
762 | + text: 'Statistical info', | |
763 | + scope: this, | |
764 | + //dock: 'bottom', | |
765 | + //ui: 'footer', | |
766 | + handler: function() { | |
767 | + this.fireEvent('info','catalogUI'); | |
768 | + } | |
769 | + }, | |
770 | + { | |
607 | 771 | type: 'button', |
608 | 772 | text: 'Visualize', |
609 | 773 | scope: this, |
... | ... | @@ -618,8 +782,9 @@ Ext.define('amdaUI.CatalogUI', { |
618 | 782 | module.createWindow(); |
619 | 783 | }); |
620 | 784 | } |
621 | - }] | |
622 | - }] | |
785 | + } | |
786 | + ] | |
787 | + }] | |
623 | 788 | }, |
624 | 789 | { |
625 | 790 | xtype: 'form', |
... | ... | @@ -654,8 +819,10 @@ Ext.define('amdaUI.CatalogUI', { |
654 | 819 | url: helpDir+'catalogHOWTO' |
655 | 820 | } |
656 | 821 | } |
657 | - ] | |
822 | + ] , | |
823 | + plugins: [ {ptype: 'statisticalPlugin'} ] | |
658 | 824 | }; |
659 | 825 | Ext.apply (this, Ext.apply(arguments, myConf)); |
660 | - } | |
826 | + } | |
827 | + | |
661 | 828 | }); |
... | ... |
js/app/views/OperationsTT.js
js/app/views/StatisticalPlug.js
... | ... | @@ -45,7 +45,7 @@ Ext.define('amdaUI.StatisticalPlug', { |
45 | 45 | }*/ |
46 | 46 | }, |
47 | 47 | |
48 | - onInfo: function() { | |
48 | + onInfo: function(type) { | |
49 | 49 | if (!this.win) { |
50 | 50 | this.win = new Ext.Window({ |
51 | 51 | id: 'statistical-win', |
... | ... | @@ -63,7 +63,8 @@ Ext.define('amdaUI.StatisticalPlug', { |
63 | 63 | type:'help', |
64 | 64 | qtip: 'Help on Statistical info', |
65 | 65 | handler: function(event, toolEl, panel){ |
66 | - AmdaAction.getInfo({name : 'statisticalHelp'}, function(res,e) { | |
66 | + | |
67 | + AmdaAction.getInfo({name : 'statisticalHelp'+type}, function(res,e) { | |
67 | 68 | if (res.success) myDesktopApp.infoMsg(res.result); |
68 | 69 | }); |
69 | 70 | } |
... | ... | @@ -90,8 +91,9 @@ Ext.define('amdaUI.StatisticalPlug', { |
90 | 91 | */ |
91 | 92 | statTT: function(){ |
92 | 93 | if (this.win) { |
94 | + var type =this.hostCmp[0]['id']; | |
93 | 95 | var me = this; |
94 | - AmdaAction.getTTCacheStatistics(function (result, e) { | |
96 | + AmdaAction.getTTCacheStatistics({name : type }, function (result, e) { | |
95 | 97 | if (!result || !result.success) |
96 | 98 | { |
97 | 99 | if (result.message) |
... | ... |
php/classes/AmdaAction.php
... | ... | @@ -1183,9 +1183,16 @@ class AmdaAction |
1183 | 1183 | return $cacheMgr->mergeIntervals(); |
1184 | 1184 | } |
1185 | 1185 | |
1186 | - public function getTTCacheStatistics() | |
1187 | - { | |
1188 | - $cacheMgr = new TimeTableCacheMgr(); | |
1186 | + public function getTTCacheStatistics($obj) | |
1187 | + { | |
1188 | + error_log("name",$obj->name ); | |
1189 | + if($obj->name == "timeTableUi"){ | |
1190 | + $cacheMgr = new TimeTableCacheMgr(); | |
1191 | + }elseif($obj->name == "catalogUI"){ | |
1192 | + $cacheMgr = new CatalogCacheMgr(); | |
1193 | + }else{ | |
1194 | + return array('success' => false, 'message' => 'unkown type: '.$obj->name); | |
1195 | + } | |
1189 | 1196 | return $cacheMgr->getStatistics(); |
1190 | 1197 | } |
1191 | 1198 | |
... | ... |
php/classes/UserMgr.php
... | ... | @@ -270,7 +270,7 @@ class UserMgr |
270 | 270 | } |
271 | 271 | |
272 | 272 | if ($base->hasAttribute('addable')) { |
273 | - // keep this base tree | |
273 | + // keep this base tree | |
274 | 274 | // error_log($baseId,1,email); |
275 | 275 | } |
276 | 276 | else { |
... | ... | @@ -282,7 +282,13 @@ class UserMgr |
282 | 282 | } |
283 | 283 | else { |
284 | 284 | $center = new $baseId(); |
285 | - $centerNode = $center->makeCenterNode($this->paramMgr->xmlDom); | |
285 | + if (method_exists($center, 'makeCenterNode')) | |
286 | + $centerNode = $center->makeCenterNode($this->paramMgr->xmlDom); | |
287 | + else { | |
288 | + // keep this base tree | |
289 | + error_log("Attention : $baseId has no makeCenterNode method", 1, email); | |
290 | + continue; | |
291 | + } | |
286 | 292 | $centerNode->setAttribute('available', TRUE); |
287 | 293 | } |
288 | 294 | |
... | ... |
php/config.php
... | ... | @@ -167,7 +167,7 @@ $API = array( |
167 | 167 | 'modifyTTCacheInterval'=>array('len'=>1), |
168 | 168 | 'operationTTCacheIntervals'=>array('len'=>2), |
169 | 169 | 'mergeTTCacheIntervals'=>array('len'=>0), |
170 | - 'getTTCacheStatistics'=>array('len'=>0), | |
170 | + 'getTTCacheStatistics'=>array('len'=>1), | |
171 | 171 | 'sendFeedback'=>array('len'=>1), |
172 | 172 | 'saveState'=>array('len'=>1), |
173 | 173 | 'loadState'=>array('len'=>1), |
... | ... |