Commit 444a796ab1d826187be07bf335c19cace76b817b
Exists in
master
and in
112 other branches
Merge branch 'master' of https://gitlab.irap.omp.eu/CDPP/AMDA_IHM
Showing
10 changed files
with
576 additions
and
11 deletions
Show diff stats
js/app/AmdaApp.js
... | ... | @@ -20,6 +20,13 @@ Ext.define('amdaApp.AmdaApp', { |
20 | 20 | ], |
21 | 21 | |
22 | 22 | dynamicModules: { |
23 | + visu : { | |
24 | + id : 'visu-win', | |
25 | + icon : 'icon-visu_catalog', | |
26 | + title : 'Visualization', | |
27 | + source : 'amdaDesktop.VisuModule', | |
28 | + useLauncher : true | |
29 | + }, | |
23 | 30 | statistics : { |
24 | 31 | id : 'statistics-win', |
25 | 32 | icon : 'icon-statistics', |
... | ... | @@ -57,7 +64,7 @@ Ext.define('amdaApp.AmdaApp', { |
57 | 64 | }, |
58 | 65 | plot : { |
59 | 66 | id : 'plot-win', |
60 | - icon : 'icon-plot', | |
67 | + icon : 'icon-plot', | |
61 | 68 | title : 'Plot Manager', |
62 | 69 | source : 'amdaDesktop.PlotModule', |
63 | 70 | useLauncher : true |
... | ... | @@ -281,7 +288,7 @@ Ext.define('amdaApp.AmdaApp', { |
281 | 288 | { name: 'Manage TimeTables', iconCls: 'timeTable', module: 'timetab-win' }, |
282 | 289 | { name: 'TimeTables operations', iconCls: 'operations', module: 'ttsOpe-win' }, |
283 | 290 | { name: 'Manage catalogs', iconCls: 'catalog', module: 'catalog-win'}, |
284 | - { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visucatalog-win'}, | |
291 | + { name: 'Visualize catalogs', iconCls: 'visu_catalog', module: 'visu-win'}, | |
285 | 292 | { name: 'Interoperability', iconCls: 'interop', module: 'interop-win' } |
286 | 293 | ] |
287 | 294 | }), |
... | ... |
... | ... | @@ -0,0 +1,35 @@ |
1 | +/** | |
2 | + * Project AMDA-NG | |
3 | + * Name VisuModule.js | |
4 | + * @class amdaDesktop.VisuModule | |
5 | + * @extends amdaDesktop.InteractiveModule | |
6 | + * @brief Visualization Module controller definition | |
7 | + * @author elena | |
8 | + */ | |
9 | + | |
10 | +Ext.define('amdaDesktop.VisuModule', { | |
11 | + extend: 'amdaDesktop.InteractiveModule', | |
12 | + | |
13 | + requires: [ | |
14 | + 'amdaUI.VisuUI' | |
15 | + ], | |
16 | + | |
17 | + contentId : 'visuUI', | |
18 | + | |
19 | + /** | |
20 | + * @cfg {String} data models | |
21 | + * @required | |
22 | + */ | |
23 | + nodeDataModel : 'amdaModel.CatalogNode', // 'amdaModel.MyDataNode' | |
24 | + | |
25 | + /** | |
26 | + * @cfg {String} window definitions | |
27 | + * @required | |
28 | + */ | |
29 | + width : 800, | |
30 | + height: 700, | |
31 | + uiType : 'panelVisu', | |
32 | + helpTitle : 'Help on Visualization Module', | |
33 | + helpFile : 'visuHelp' | |
34 | + | |
35 | +}); | |
... | ... |
js/app/models/CatalogNode.js
... | ... | @@ -38,11 +38,11 @@ Ext.define('amdaModel.CatalogNode', { |
38 | 38 | fnId : 'leaf-download', |
39 | 39 | text : 'Download '+ this.self.objectName, |
40 | 40 | hidden : true |
41 | - }/*,{ | |
42 | - fnId : 'leaf-operations', | |
43 | - text : 'Operations', | |
41 | + },{ | |
42 | + fnId : 'leaf-visu', | |
43 | + text : 'Visualize '+ this.self.objectName, | |
44 | 44 | hidden : true |
45 | - }*/]; | |
45 | + }]; | |
46 | 46 | |
47 | 47 | return menuItems; |
48 | 48 | }, |
... | ... | @@ -69,5 +69,16 @@ Ext.define('amdaModel.CatalogNode', { |
69 | 69 | |
70 | 70 | downloadMulti: function() { |
71 | 71 | alert('NOT IMPLEMENTED YET'); |
72 | + }, | |
73 | + | |
74 | + visu : function(contextNode) { | |
75 | + | |
76 | + var me = this; | |
77 | + | |
78 | + myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.visu.id, true, function (module) { | |
79 | + // Opening parameter window | |
80 | + module.createWindow(); | |
81 | + module.getUiContent().setObject(me.get('text'), me.get('id')); | |
82 | + }); | |
72 | 83 | } |
73 | 84 | }); |
... | ... |
js/app/models/TimeTableNode.js
js/app/views/ExplorerUI.js
... | ... | @@ -353,7 +353,9 @@ Ext.define('amdaUI.ExplorerUI', { |
353 | 353 | switch (targetNode.data.nodeType) |
354 | 354 | { |
355 | 355 | case 'localParam' : |
356 | - case 'myData' : | |
356 | + case 'remoteParam' : | |
357 | + case 'remoteSimuParam' : | |
358 | + case 'myData' : | |
357 | 359 | return false; |
358 | 360 | default : |
359 | 361 | if (draggedRecord.data.id == targetNode.data.nodeType+'-treeRootNode') |
... | ... |
... | ... | @@ -0,0 +1,413 @@ |
1 | +/** | |
2 | + * Project AMDA-NG | |
3 | + * Name VisuUI.js | |
4 | + * @class amdaUI.visuUI | |
5 | + * @extends Ext.container.Container | |
6 | + * @brief Visualization Module UI definition (View) | |
7 | + * @author elena | |
8 | + */ | |
9 | + | |
10 | +Ext.define('amdaUI.VisuUI', { | |
11 | + extend: 'Ext.container.Container', | |
12 | + alias: 'widget.panelVisu', | |
13 | + | |
14 | + constructor: function(config) | |
15 | + { | |
16 | + this.init(config); | |
17 | + this.callParent(arguments); | |
18 | + | |
19 | + //if (this.object) this.loadObject(); | |
20 | + }, | |
21 | + | |
22 | + setObject : function (name,id) | |
23 | + { | |
24 | + // set object | |
25 | + this.object.set('id',id); | |
26 | + this.object.set('name',name); | |
27 | + // load object into view | |
28 | + this.loadObject(); | |
29 | + }, | |
30 | + | |
31 | + /** | |
32 | + * set params description into this.object | |
33 | + */ | |
34 | + setParamInfo : function(parameters) | |
35 | + { | |
36 | + var params = []; | |
37 | + Ext.Array.each(parameters, function(item, index) { | |
38 | + params[index] = item; | |
39 | + }, this); | |
40 | + | |
41 | + this.object.set('parameters', params); | |
42 | + }, | |
43 | + | |
44 | + updateCount : function() | |
45 | + { | |
46 | +// this.object.set('nbIntervals',this.TTGrid.getStore().getTotalCount()); | |
47 | +// this.formPanel.getForm().findField('nbIntervals').setValue(this.object.get('nbIntervals')); | |
48 | + }, | |
49 | + | |
50 | + /** | |
51 | + * load object catalog into this view | |
52 | + */ | |
53 | + loadObject : function() | |
54 | + { | |
55 | + // load object into form | |
56 | + | |
57 | + var me = this; | |
58 | + | |
59 | + var onAfterInit = function(result, e) | |
60 | + { | |
61 | + if (!result || !result.success) | |
62 | + { | |
63 | + if (result.message) | |
64 | + myDesktopApp.errorMsg(result.message); | |
65 | + else | |
66 | + myDesktopApp.errorMsg('Unknown error during catalog cache initialisation'); | |
67 | + return; | |
68 | + } | |
69 | + | |
70 | + | |
71 | + | |
72 | + var fields = [], i = 0, index; | |
73 | + | |
74 | + Ext.Array.each(result.parameters, function(obj) | |
75 | + { | |
76 | + | |
77 | + index = 'param'+i.toString(); | |
78 | + fields[i] = Ext.create('Ext.data.Field', { name : index, id: index, text : obj.name, | |
79 | + convert: function(value, record) { | |
80 | + return parseFloat(value); | |
81 | + } | |
82 | + } | |
83 | + ); | |
84 | + | |
85 | + i++; | |
86 | + }); | |
87 | + | |
88 | + var newStore = Ext.create('Ext.data.Store', { | |
89 | + fields : [ 'text', 'id'], | |
90 | + data : fields | |
91 | + }); | |
92 | + | |
93 | + me.parCombo.bindStore(newStore); | |
94 | + me.parCombo1.bindStore(newStore); | |
95 | + | |
96 | + me.chartStore = Ext.create('Ext.data.Store', { | |
97 | + fields : fields, | |
98 | + autoDestroy: false, | |
99 | + // pageSize : 200, | |
100 | + // buffered : true, | |
101 | + // purgePageCount: 0, | |
102 | + // remoteSort: true, | |
103 | + autoload: false, | |
104 | + proxy: { | |
105 | + type: 'direct', | |
106 | + api : | |
107 | + { | |
108 | + read : AmdaAction.readIntervalsForChart | |
109 | + }, | |
110 | + // remplir automatiquement tt, sharedtt , catalog, shared catalog | |
111 | + extraParams : {'typeTT' : 'catalog', 'id' : me.object.get('id')}, | |
112 | + reader: | |
113 | + { | |
114 | + type: 'json', | |
115 | + root: 'intervals', | |
116 | + totalProperty : 'totalCount' | |
117 | + } | |
118 | + }, | |
119 | + listeners: { | |
120 | + scope : me, | |
121 | + load: function(store,records) { | |
122 | + //TODO enable plot button | |
123 | + } | |
124 | + } | |
125 | + }); | |
126 | + | |
127 | + me.chartStore.load(); | |
128 | + | |
129 | + } | |
130 | + | |
131 | + AmdaAction.initForChartFromTT(this.object.get('id'), 'catalog', onAfterInit); | |
132 | + | |
133 | + }, | |
134 | + | |
135 | + /** | |
136 | + * updated object catalog into this view | |
137 | + */ | |
138 | + updateObject : function() | |
139 | + { | |
140 | + // load object into form | |
141 | + //this.formPanel.getForm().loadRecord(this.object); | |
142 | + | |
143 | + var me = this; | |
144 | + | |
145 | + }, | |
146 | + | |
147 | + /** | |
148 | + * Check if changes were made before closing window | |
149 | + * @return true if changes | |
150 | + */ | |
151 | + fclose : function() | |
152 | + { | |
153 | + | |
154 | + return false; | |
155 | + }, | |
156 | + | |
157 | + plotChart : function () { | |
158 | + | |
159 | + this.chartConfig.store=this.chartStore; | |
160 | + | |
161 | + var chart = Ext.create('Ext.chart.Chart', this.chartConfig); | |
162 | + // chart.bindStore(this.chartStore); | |
163 | + var chartPanel = this.items.items[0].items.items[1]; | |
164 | + var oldChart = chartPanel.down('chart'); | |
165 | + oldIndex = chartPanel.items.indexOf(oldChart); | |
166 | + chartPanel.remove(oldChart); | |
167 | + chartPanel.insert(oldIndex, chart); | |
168 | + }, | |
169 | + | |
170 | + init : function (config) | |
171 | + { | |
172 | + var store = Ext.create('Ext.data.Store', { | |
173 | + fields : [], | |
174 | + autoload : false | |
175 | + }); | |
176 | + | |
177 | + this.chartConfig = { | |
178 | + width: 500, | |
179 | + height: 500, | |
180 | + animate: true, | |
181 | + mask: true, | |
182 | + // theme:'Category2', | |
183 | + store: store, | |
184 | + axes: [{ | |
185 | + type: 'Numeric', | |
186 | + position: 'bottom', | |
187 | + fields: [], | |
188 | + title: 'x axe', | |
189 | + grid : true | |
190 | + }, { | |
191 | + type: 'Numeric', | |
192 | + position: 'left', | |
193 | + fields: [], | |
194 | + title: 'y axe', | |
195 | + grid: true | |
196 | + }], | |
197 | + series: [{ | |
198 | + type: 'scatter', | |
199 | + markerConfig: { | |
200 | + radius: 5, | |
201 | + size: 5 | |
202 | + }, | |
203 | + // // axes: ['left', 'bottom'], | |
204 | + xField: '', | |
205 | + yField: '', | |
206 | + label: { | |
207 | +// display: 'under', | |
208 | +// render: function(value) { | |
209 | +// return parseFloat(value); | |
210 | +// } | |
211 | + } | |
212 | + }] | |
213 | + } | |
214 | + | |
215 | + var plotTypeList = Ext.create('Ext.data.Store', { | |
216 | + fields: ['type'], | |
217 | + data: [ | |
218 | + { 'type': 'line' }, | |
219 | + { 'type': 'scatter' } | |
220 | + ] | |
221 | + }); | |
222 | + | |
223 | + var parList = Ext.create('Ext.data.Store', { | |
224 | + fields: [], | |
225 | + autoload : false | |
226 | + }); | |
227 | + | |
228 | + var chart = Ext.create('Ext.chart.Chart', this.chartConfig); | |
229 | + | |
230 | + this.parCombo = Ext.create('Ext.form.ComboBox', { | |
231 | + emptyText: 'select parameter', | |
232 | + editable: false, | |
233 | + store: parList, | |
234 | + queryMode: 'local', | |
235 | + displayField: 'text', | |
236 | + valueField: 'id', | |
237 | + listeners : { | |
238 | + scope : this, | |
239 | + change : function(combo, newValue, oldValue) { | |
240 | + | |
241 | + this.chartConfig.axes[0].fields = [newValue]; | |
242 | + var rec = combo.findRecordByValue(newValue); | |
243 | + this.chartConfig.axes[0].title = rec.get('text'); | |
244 | + this.chartConfig.series[0].xField = newValue; | |
245 | + } | |
246 | + } | |
247 | + }); | |
248 | + | |
249 | + this.parCombo1 = Ext.create('Ext.form.ComboBox', { | |
250 | + emptyText: 'select parameter', | |
251 | + editable: false, | |
252 | + store: parList, | |
253 | + queryMode: 'local', | |
254 | + displayField: 'text', | |
255 | + valueField: 'id', | |
256 | + listeners : { | |
257 | + scope : this, | |
258 | + change : function(combo, newValue, oldValue) { | |
259 | + | |
260 | + this.chartConfig.axes[1].fields = [newValue]; | |
261 | + var rec = combo.findRecordByValue(newValue); | |
262 | + this.chartConfig.axes[1].title = rec.get('text'); | |
263 | + this.chartConfig.series[0].yField = newValue; | |
264 | + } | |
265 | + } | |
266 | + }); | |
267 | + | |
268 | + var plotTypeCombo = Ext.create('Ext.form.ComboBox', { | |
269 | + emptyText: 'select plot type', | |
270 | + editable: false, | |
271 | + store: plotTypeList, | |
272 | + queryMode: 'local', | |
273 | + displayField: 'type', | |
274 | + valueField: 'type', | |
275 | + listeners : { | |
276 | + scope : this, | |
277 | + change : function(combo, newValue, oldValue) { | |
278 | + this.chartConfig.series[0].type = newValue; | |
279 | + } | |
280 | + } | |
281 | + }); | |
282 | + | |
283 | + | |
284 | + var formPanel = Ext.create('Ext.form.Panel', { | |
285 | + region : 'center', | |
286 | + layout: 'hbox', | |
287 | + bodyStyle: {background : '#dfe8f6'}, | |
288 | + defaults: { border : false, align: 'stretch', padding: '3'}, | |
289 | + fieldDefaults: { labelWidth: 80, labelAlign : 'top' }, | |
290 | + items: [ | |
291 | + { | |
292 | + xtype: 'form', | |
293 | + flex : 1, | |
294 | + bodyStyle: {background : '#dfe8f6'}, | |
295 | + items: [ | |
296 | + { | |
297 | + xtype : 'fieldset', | |
298 | + title : 'X axis', | |
299 | + items : [ | |
300 | + this.parCombo, | |
301 | + { | |
302 | + xtype : 'fieldcontainer', | |
303 | + layout: 'hbox', | |
304 | + items: [{ | |
305 | + xtype: 'textfield', | |
306 | + flex: 1 | |
307 | + }, { | |
308 | + xtype: 'splitter' | |
309 | + }, { | |
310 | + xtype: 'textfield', | |
311 | + flex: 1 | |
312 | + }] | |
313 | + }, | |
314 | + { xtype : 'checkbox' }, | |
315 | + { xtype : 'checkbox' } | |
316 | + ] | |
317 | + }, | |
318 | + { | |
319 | + xtype : 'fieldset', | |
320 | + title : 'Y axis', | |
321 | + items : [ | |
322 | + this.parCombo1, | |
323 | + { | |
324 | + xtype : 'fieldcontainer', | |
325 | + layout: 'hbox', | |
326 | + items: [{ | |
327 | + xtype: 'textfield', | |
328 | + flex: 1 | |
329 | + }, { | |
330 | + xtype: 'splitter' | |
331 | + }, { | |
332 | + xtype: 'textfield', | |
333 | + flex: 1 | |
334 | + } | |
335 | + ] | |
336 | + }, | |
337 | + { xtype : 'checkbox' }, | |
338 | + { xtype : 'checkbox' } | |
339 | + ] | |
340 | + }, | |
341 | + { | |
342 | + xtype : 'fieldset', | |
343 | + title : 'Plotting Options', | |
344 | + items : [ | |
345 | + plotTypeCombo | |
346 | + ] | |
347 | + } | |
348 | + ], | |
349 | + fbar:[ | |
350 | + { | |
351 | + type: 'button', | |
352 | + text: 'Plot', | |
353 | + scope : this, | |
354 | + handler: this.plotChart | |
355 | + | |
356 | + },{ | |
357 | + type: 'button', | |
358 | + text: 'Reset' | |
359 | + | |
360 | + } | |
361 | + ] | |
362 | + }, { | |
363 | + xtype: 'form', | |
364 | + // padding: '3', | |
365 | + flex: 2, | |
366 | + items : [ | |
367 | + chart | |
368 | + ], | |
369 | + fbar:[ | |
370 | + { | |
371 | + type: 'button', | |
372 | + text: 'Save Chart', | |
373 | + scope: this, | |
374 | + handler: function() { | |
375 | + var chartPanel = this.items.items[0].items.items[1]; | |
376 | + var chart = chartPanel.down('chart'); | |
377 | + chart.save({ | |
378 | + type: 'image/png' | |
379 | + }); | |
380 | + } | |
381 | + | |
382 | + } | |
383 | + ] | |
384 | + } | |
385 | + ] | |
386 | + }); | |
387 | + | |
388 | + | |
389 | + var myConf = { | |
390 | + layout: 'border', | |
391 | + items: [ | |
392 | + formPanel, | |
393 | + { | |
394 | + xtype: 'panel', | |
395 | + region: 'south', | |
396 | + title: 'Information', | |
397 | + collapsible: true, | |
398 | + height: 100, | |
399 | + autoHide: false, | |
400 | + bodyStyle: 'padding:5px', | |
401 | + iconCls: 'icon-information', | |
402 | + loader: { | |
403 | + autoLoad: true, | |
404 | + url: helpDir+'visuHOWTO' | |
405 | + } | |
406 | + } | |
407 | + ] | |
408 | + }; | |
409 | + | |
410 | + Ext.apply (this, Ext.apply(arguments, myConf)); | |
411 | + } | |
412 | + | |
413 | +}); | |
... | ... |
php/classes/AmdaAction.php
... | ... | @@ -954,6 +954,14 @@ class AmdaAction { |
954 | 954 | return $cacheMgr->initFromTT($id, $type); |
955 | 955 | } |
956 | 956 | |
957 | + public function initForChartFromTT($id, $type) | |
958 | + { | |
959 | + if ($type == 'catalog') $objMgr = new CatalogMgr(); | |
960 | + | |
961 | + | |
962 | + return $objMgr->initForChartFromTT($id, $type); | |
963 | + } | |
964 | + | |
957 | 965 | public function initTTCacheFromTmpObject($folderId, $name, $isCatalog = false) |
958 | 966 | { |
959 | 967 | if (!$isCatalog) $cacheMgr = new TimeTableCacheMgr(); |
... | ... | @@ -978,7 +986,15 @@ class AmdaAction { |
978 | 986 | |
979 | 987 | return $cacheMgr->getIntervals($o->start,$o->limit,$o->sort,$o->filter); |
980 | 988 | } |
981 | - | |
989 | + | |
990 | + public function readIntervalsForChart($o) | |
991 | + { | |
992 | + if ($o->typeTT == 'catalog') $objMgr = new CatalogMgr(); | |
993 | + | |
994 | + | |
995 | + return $objMgr->getIntervalsForChart($o->id, $o->typeTT); | |
996 | + } | |
997 | + | |
982 | 998 | public function saveTTCacheIntervalsInTT($o) |
983 | 999 | { |
984 | 1000 | $cacheMgr = new TimeTableCacheMgr(); |
... | ... |
php/classes/CatalogMgr.php
... | ... | @@ -249,6 +249,74 @@ class CatalogMgr extends TimeTableMgr { |
249 | 249 | |
250 | 250 | } |
251 | 251 | |
252 | + public function initForChartFromTT($id, $typeTT) | |
253 | + { | |
254 | + $intervals_res = $this->loadIntervalsFromTT($id,$typeTT); | |
255 | + | |
256 | + if (!$intervals_res['success']) | |
257 | + return $intervals_res; | |
258 | + | |
259 | + $paramHeaders = []; | |
260 | + | |
261 | + foreach ( $intervals_res['parameters'] as $param ) { | |
262 | + | |
263 | + if ($param['size'] > 1) { | |
264 | + | |
265 | + for ($i = 0; $i < $param['size']; $i++) { | |
266 | + $paramComp = array(); | |
267 | + $paramComp['id'] = $param['id'].'_'.$i; | |
268 | + $paramComp['name'] = $param['name'].'_'.$i; | |
269 | + // $paramComp['size'] = 1; | |
270 | + | |
271 | + $paramHeaders[] = $paramComp; | |
272 | + } | |
273 | + } | |
274 | + else { | |
275 | + $paramHeaders[] = $param; | |
276 | + } | |
277 | + } | |
278 | + | |
279 | + unset($intervals_res); | |
280 | + | |
281 | + return array('success' => true, 'parameters' => $paramHeaders); | |
282 | + } | |
283 | + | |
284 | + public function getIntervalsForChart($id, $type) { | |
285 | + | |
286 | + $intervals_res = $this->loadIntervalsFromTT($id,$type); | |
287 | + | |
288 | + if (!$intervals_res['success']) | |
289 | + return $intervals_res; | |
290 | + | |
291 | + $newIntervals = array(); | |
292 | + | |
293 | + foreach ($intervals_res['intervals'] as $interval) | |
294 | + { | |
295 | + $newIntervalComp = array(); | |
296 | + $k = 0; | |
297 | + | |
298 | + for ( $j = 0; $j < count($interval['paramTable']); $j++ ) { | |
299 | + | |
300 | + $param = $interval['paramTable'][$j]; | |
301 | + $tempArr = explode(',',$param); | |
302 | + | |
303 | + if (count($tempArr) > 1) { | |
304 | + for ($i = 0; $i < count($tempArr); $i++) { | |
305 | + $newIntervalComp['param'.$k] = $tempArr[$i]; | |
306 | + $k++; | |
307 | + } | |
308 | + } | |
309 | + else { | |
310 | + $newIntervalComp['param'.$k] = $param; | |
311 | + $k++; | |
312 | + } | |
313 | + } | |
314 | + $newIntervals[] = $newIntervalComp; | |
315 | + } | |
316 | + | |
317 | + return array('success' => true, 'intervals' => $newIntervals); | |
318 | + | |
319 | + } | |
252 | 320 | |
253 | 321 | } |
254 | 322 | ?> |
... | ... |
php/config.php
... | ... | @@ -241,9 +241,9 @@ $API = array( |
241 | 241 | 'modifyObject'=>array( |
242 | 242 | 'len'=>1 |
243 | 243 | ), |
244 | - 'validNameObject'=>array( | |
245 | - 'len'=>1 | |
246 | - ), | |
244 | + 'validNameObject'=>array( | |
245 | + 'len'=>1 | |
246 | + ), | |
247 | 247 | 'getJobs'=>array( |
248 | 248 | 'len'=>0 |
249 | 249 | ), |
... | ... | @@ -278,6 +278,9 @@ $API = array( |
278 | 278 | 'initTTCacheFromTT' => array( |
279 | 279 | 'len'=>2 |
280 | 280 | ), |
281 | + 'initForChartFromTT' => array( | |
282 | + 'len'=>2 | |
283 | + ), | |
281 | 284 | 'initTTCacheFromTmpObject' => array( |
282 | 285 | 'len'=>3 |
283 | 286 | ), |
... | ... | @@ -287,6 +290,9 @@ $API = array( |
287 | 290 | 'readTTCacheIntervals'=>array( |
288 | 291 | 'len'=>1 |
289 | 292 | ), |
293 | + 'readIntervalsForChart'=>array( | |
294 | + 'len'=>1 | |
295 | + ), | |
290 | 296 | 'addTTCacheInterval'=>array ( |
291 | 297 | 'len'=>1 |
292 | 298 | ), |
... | ... |