~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to dhis-2/dhis-web/dhis-web-reporting/src/main/webapp/dhis-web-reporting/javascript/pivot.js

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
// -----------------------------------------------------------------------------
 
3
// Global variables
 
4
// -----------------------------------------------------------------------------
 
5
 
 
6
var indicators = []; // Array->associative array (id,name)
 
7
var periods = []; // Array->associative array (id,name)
 
8
var orgunits = []; // Array->associative array (id,name)
 
9
var data = []; // Associative array [(indicator-period-orgunit), (indicatorValue)]
 
10
 
 
11
var sizes = []; // Associative array (dimension, size)
 
12
 
 
13
var pivotIndicator = true; // Should correspond to init value in form
 
14
var pivotPeriod = false;
 
15
var pivotOrgunit = false;
 
16
 
 
17
var currentIndicator = 0;
 
18
var currentPeriod = 0;
 
19
var currentOrgunit = 0;
 
20
 
 
21
// -----------------------------------------------------------------------------
 
22
// Public methods
 
23
// -----------------------------------------------------------------------------
 
24
 
 
25
/**
 
26
 * This method is called from the UI and is responsible for retrieving data from 
 
27
 * the server and setting the global variables.
 
28
 */
 
29
function getData()
 
30
{
 
31
  clearGlobalVariables();
 
32
  
 
33
  var indicatorGroupList = document.getElementById( "indicatorGroup" );
 
34
  var periodTypeList = document.getElementById( "periodType" );
 
35
  var levelList = document.getElementById( "level" );
 
36
  
 
37
  var indicatorGroupId = indicatorGroupList.options[ indicatorGroupList.selectedIndex ].value;
 
38
  var indicatorGroupName = indicatorGroupList.options[ indicatorGroupList.selectedIndex ].text;
 
39
  var startDate = document.getElementById( "startDate" ).value;
 
40
  var endDate = document.getElementById( "endDate" ).value;
 
41
  var periodTypeName = periodTypeList.options[ periodTypeList.selectedIndex ].value;
 
42
  var level = levelList.options[ levelList.selectedIndex ].value;
 
43
  
 
44
  /* DEBUG 
 
45
  indicatorGroupId = "1152";
 
46
  periodTypeName = "Monthly";
 
47
  startDate = "2006-01-01";
 
48
  endDate = "2007-01-01";
 
49
  level = "4";  
 
50
  /* DEBUG */
 
51
  
 
52
  document.getElementById( "dataLabel" ).innerHTML = 
 
53
    i18n_indicator_group + ": " + indicatorGroupName +
 
54
    ", " + i18n_start_date + ": " + startDate + 
 
55
    ", " + i18n_end_date + ": " + endDate + 
 
56
    ", " + i18n_period_type + ": " + periodTypeName +
 
57
    ", " + i18n_organisation_unit_level + ": " + level;
 
58
  
 
59
  var url = "getPivotTable.action";
 
60
  
 
61
  $.getJSON(
 
62
    url,
 
63
    {
 
64
      "indicatorGroupId": indicatorGroupId, 
 
65
      "periodTypeName": periodTypeName, 
 
66
      "startDate": startDate, 
 
67
      "endDate": endDate, 
 
68
      "level": level 
 
69
    },
 
70
    function( json ) 
 
71
    {
 
72
      var pivot = json.pivotTable;
 
73
      
 
74
      indicators = pivot.indicators;
 
75
      periods = pivot.periods;
 
76
      orgunits = pivot.organisationUnits;
 
77
      
 
78
      sizes["indicator"] = pivot.sizeIndicators;
 
79
      sizes["period"] = pivot.sizePeriods;
 
80
      sizes["orgunit"] = pivot.sizeOrganisationUnits;
 
81
      
 
82
      data = pivot.indicatorValues[0];
 
83
      
 
84
      generateTable();
 
85
    }
 
86
  );
 
87
}
 
88
 
 
89
/**
 
90
 * This method is called from the UI and is responsible for pivoting the table.
 
91
 */
 
92
function pivotData()
 
93
{
 
94
  pivotIndicator = document.getElementById( "indicatorBox" ).checked;
 
95
  pivotPeriod = document.getElementById( "periodBox" ).checked;
 
96
  pivotOrgunit = document.getElementById( "orgunitBox" ).checked;
 
97
  
 
98
  generateTable();
 
99
}
 
100
 
 
101
/**
 
102
 * This method is called from the UI and shows a chart with the selected data.
 
103
 */
 
104
function viewChart( chartIndicators, chartDimension )
 
105
{
 
106
  var chartWidth = 750;
 
107
    
 
108
  var url = "generateChart.action";
 
109
    
 
110
  if ( chartIndicators == "single" && chartDimension == "period" )
 
111
  {
 
112
    url += "?indicatorId=" + currentIndicator + "&organisationUnitId=" + currentOrgunit + "&dimension=period&regression=true";
 
113
    
 
114
    for ( p in periods )
 
115
    {
 
116
      url += "&periodId=" + periods[p].id;
 
117
    }
 
118
  }
 
119
  else if ( chartIndicators == "single" && chartDimension == "orgunit" )
 
120
  {
 
121
    url += "?indicatorId=" + currentIndicator + "&periodId=" + currentPeriod + "&dimension=organisationUnit&regression=false";
 
122
    
 
123
    for ( o in orgunits )
 
124
    {
 
125
      url += "&organisationUnitId=" + orgunits[o].id;
 
126
    }
 
127
  }
 
128
  else if ( chartIndicators == "all" && chartDimension == "period" )
 
129
  {
 
130
    url += "?organisationUnitId=" + currentOrgunit + "&dimension=period&regression=false&chartWidth=950";
 
131
    
 
132
    for ( i in indicators )
 
133
    {
 
134
      url += "&indicatorId=" + indicators[i].id;
 
135
    }
 
136
    
 
137
    for ( p in periods )
 
138
    {
 
139
      url += "&periodId=" + periods[p].id;
 
140
    }
 
141
    
 
142
    chartWidth = 1000;
 
143
  }
 
144
  else if ( chartIndicators == "all" && chartDimension == "orgunit" )
 
145
  {
 
146
    url += "?periodId=" + currentPeriod + "&dimension=organisationUnit&regression=false&chartWidth=950";
 
147
    
 
148
    for ( i in indicators )
 
149
    {
 
150
      url += "&indicatorId=" + indicators[i].id;
 
151
    }
 
152
    
 
153
    for ( o in orgunits )
 
154
    {
 
155
      url += "&organisationUnitId=" + orgunits[o].id;
 
156
    }
 
157
    
 
158
    chartWidth = 1000;
 
159
  }
 
160
  
 
161
  hideDropDown();
 
162
  
 
163
  window.open( url, "_blank", "directories=no, height=550, width=" + chartWidth + ", location=no, menubar=no, status=no, toolbar=no, scrollbars=no" );
 
164
}
 
165
 
 
166
/**
 
167
 * This method is called from the UI and will display the chart menu.
 
168
 * 
 
169
 * @param indicatorId the indicator identifier
 
170
 * @param periodId the period identifier
 
171
 * @param orgunitId the organisation unit identifier
 
172
 */
 
173
function viewChartMenu( indicatorId, periodId, orgunitId )
 
174
{
 
175
  currentIndicator = indicatorId;
 
176
  currentPeriod = periodId;
 
177
  currentOrgunit = orgunitId;
 
178
  
 
179
  showDropDown( "pivotMenu" );
 
180
}
 
181
 
 
182
/**
 
183
 * Loads the event listeners for the pivot table. Called after page is loaded.
 
184
 */
 
185
function loadListeners()
 
186
{
 
187
  var table = document.getElementById( "pivotTable" );
 
188
  
 
189
  table.addEventListener( "click", setPosition, false );
 
190
}
 
191
 
 
192
// -----------------------------------------------------------------------------
 
193
// Supportive methods
 
194
// -----------------------------------------------------------------------------
 
195
 
 
196
/**
 
197
* This method sets the position of the pivot menu, and is registered as a 
 
198
* callback function for mouse click events.
 
199
*/
 
200
function setPosition( e )
 
201
{
 
202
  var left = e.pageX + "px";
 
203
  var top = e.pageY + "px";
 
204
  
 
205
  var pivotMenu = document.getElementById( "pivotMenu" );
 
206
  
 
207
  pivotMenu.style.left = left;
 
208
  pivotMenu.style.top = top;
 
209
}
 
210
 
 
211
/**
 
212
 * This method is responsible for generating the pivot table.
 
213
 */
 
214
function generateTable()
 
215
{
 
216
  hideDivs();
 
217
   
 
218
  var columnIndicators = pivotIndicator ? indicators : [null];
 
219
  var columnPeriods = pivotPeriod ? periods : [null];
 
220
  var columnOrgunits = pivotOrgunit ? orgunits : [null];
 
221
  
 
222
  var rowIndicators = pivotIndicator ? [null] : indicators;
 
223
  var rowPeriods = pivotPeriod ? [null] : periods;
 
224
  var rowOrgunits = pivotOrgunit ? [null] : orgunits;
 
225
 
 
226
  var table = document.getElementById( "pivotTable" );
 
227
 
 
228
  clearTable( table );
 
229
  
 
230
  var columns = getColumns( columnIndicators, columnPeriods, columnOrgunits );
 
231
  var rows = getRows( rowIndicators, rowPeriods, rowOrgunits );
 
232
  
 
233
  var columnDimensions = getColumnDimensions();
 
234
  var rowDimensions = getRowDimensions();
 
235
  
 
236
  var colSpans = getSpans( columnDimensions );
 
237
  var rowSpans = getSpans( rowDimensions );
 
238
 
 
239
  var html = "<tr>";
 
240
 
 
241
  // ---------------------------------------------------------------------------
 
242
  // Column headers
 
243
  // ---------------------------------------------------------------------------
 
244
 
 
245
  for ( d in columnDimensions )
 
246
  {
 
247
    for ( rowDimension in rowDimensions ) // Make space for row header
 
248
    {
 
249
      html += "<td class='row'></td>"; 
 
250
    }
 
251
    
 
252
    var dimension = columnDimensions[d];
 
253
    var colSpan = colSpans[dimension];
 
254
    
 
255
    for ( c in columns )
 
256
    {
 
257
      var modulus = c % colSpan;
 
258
      
 
259
      if ( modulus == 0 )
 
260
      {
 
261
        html += "<td class='column' colspan='" + colSpan + "'>" + columns[c][dimension]  + "</td>";
 
262
      }
 
263
    }
 
264
    
 
265
    html += "</tr>";
 
266
  }
 
267
  
 
268
  // ---------------------------------------------------------------------------
 
269
  // Rows
 
270
  // ---------------------------------------------------------------------------
 
271
 
 
272
  for ( r in rows )
 
273
  {
 
274
    html += "<tr>";    
 
275
    
 
276
    for ( d in rowDimensions ) // Row headers
 
277
    {
 
278
      var dimension = rowDimensions[d];
 
279
      var rowSpan = rowSpans[dimension];
 
280
      var modulus = r % rowSpan;
 
281
      
 
282
      if ( modulus == 0 )
 
283
      {
 
284
        html += "<td class='row' rowspan='" + rowSpan + "'>" + rows[r][dimension] + "</td>";
 
285
      }
 
286
    }
 
287
    
 
288
    for ( c in columns ) // Values
 
289
    {
 
290
      var value = getValue( columns[c], rows[r] );
 
291
      
 
292
      var ids = mergeArrays( columns[c], rows[r] );
 
293
      
 
294
      html += "<td class='cell' onclick='viewChartMenu( \"" + ids.indicatorId + "\", \"" + ids.periodId + "\", \"" + ids.orgunitId + "\" )'>" + value + "</td>";
 
295
    }
 
296
    
 
297
    html += "</tr>";
 
298
  }
 
299
  
 
300
  table.innerHTML = html;
 
301
  
 
302
  hidePivot();
 
303
}
 
304
 
 
305
/**
 
306
* @param dimensions array -> dimensions
 
307
*
 
308
* @return associative array ( dimension, span )
 
309
*/
 
310
function getSpans( dimensions )
 
311
{
 
312
  var spans = [];
 
313
  
 
314
  var lastIndex = ( dimensions.length - 1 );
 
315
  
 
316
  var span = 1;
 
317
  
 
318
  for ( var i=lastIndex; i>=0; i-- )
 
319
  {
 
320
    var dimension = dimensions[i];
 
321
    
 
322
    spans[dimension] = span;
 
323
    
 
324
    var dimensionSize = sizes[dimension];
 
325
    
 
326
    span = ( span * dimensionSize );
 
327
  }
 
328
  
 
329
  return spans;
 
330
}
 
331
 
 
332
/**
 
333
* @param columnIndicators array -> associative array ( indicatorId, indicatorName )
 
334
* @param columnPeriods array -> associative array ( periodId, periodName )
 
335
* @param columnOrgunits array -> associative array ( orgunitId, orgunitName )
 
336
*
 
337
* @return array -> associative array ( indicatorId, indicator, periodId, period, orgunitId, orgunit )
 
338
*/
 
339
function getColumns( columnIndicators, columnPeriods, columnOrgunits )
 
340
{
 
341
  var columns = [];
 
342
  var columnsIndex = 0;
 
343
 
 
344
  for ( var i=0; i<columnIndicators.length; i++ )
 
345
  {
 
346
    for ( var j=0; j<columnPeriods.length; j++ )
 
347
    {
 
348
      for ( var k=0; k<columnOrgunits.length; k++ )
 
349
      {
 
350
        var column = [];
 
351
        
 
352
        if ( columnIndicators[i] != null )
 
353
        {
 
354
          column["indicatorId"] = columnIndicators[i].id;
 
355
          column["indicator"] = columnIndicators[i].name;
 
356
        }
 
357
        
 
358
        if ( columnPeriods[j] != null )
 
359
        {
 
360
          column["periodId"] = columnPeriods[j].id;
 
361
          column["period"] = columnPeriods[j].name;
 
362
        }
 
363
        
 
364
        if ( columnOrgunits[k] != null )
 
365
        {
 
366
          column["orgunitId"] = columnOrgunits[k].id;
 
367
          column["orgunit"] = columnOrgunits[k].name;
 
368
        }
 
369
        
 
370
        columns[columnsIndex++] = column;     
 
371
      }
 
372
    }
 
373
  }
 
374
  
 
375
  return columns;
 
376
}
 
377
 
 
378
/**
 
379
* @param rowIndicators array -> associative array ( indicatorId, indicatorName )
 
380
* @param rowPeriods array -> associative array ( periodId, periodName )
 
381
* @param rowOrgunits array -> associative array ( orgunitId, orgunitName )
 
382
*
 
383
* @return array -> associative array ( indicatorId, indicator, periodId, period, orgunitId, orgunit )
 
384
*/
 
385
function getRows( rowIndicators, rowPeriods, rowOrgunits )
 
386
{
 
387
  var rows = [];
 
388
  var rowsIndex = 0;
 
389
 
 
390
  for ( var i=0; i<rowIndicators.length; i++ )
 
391
  {
 
392
    for ( var j=0; j<rowPeriods.length; j++ )
 
393
    {
 
394
      for ( var k=0; k<rowOrgunits.length; k++ )
 
395
      {
 
396
        var row = [];
 
397
        
 
398
        if ( rowIndicators[i] != null )
 
399
        {
 
400
          row["indicatorId"] = rowIndicators[i].id;
 
401
          row["indicator"] = rowIndicators[i].name;
 
402
        }
 
403
        
 
404
        if ( rowPeriods[j] != null )
 
405
        {
 
406
          row["periodId"] = rowPeriods[j].id;
 
407
          row["period"] = rowPeriods[j].name;
 
408
        }
 
409
        
 
410
        if ( rowOrgunits[k] != null )
 
411
        {
 
412
          row["orgunitId"] = rowOrgunits[k].id;
 
413
          row["orgunit"] = rowOrgunits[k].name;
 
414
        }
 
415
        
 
416
        rows[rowsIndex++] = row;
 
417
      }
 
418
    }
 
419
  }
 
420
  
 
421
  return rows;
 
422
}
 
423
 
 
424
/**
 
425
* @return array -> dimension
 
426
*/
 
427
function getColumnDimensions()
 
428
{
 
429
  var dimensions = [];
 
430
   
 
431
  if ( pivotIndicator )
 
432
  {
 
433
    dimensions[dimensions.length] = "indicator";
 
434
  }
 
435
  
 
436
  if ( pivotPeriod )
 
437
  {
 
438
    dimensions[dimensions.length] = "period";
 
439
  }
 
440
  
 
441
  if ( pivotOrgunit )
 
442
  {
 
443
    dimensions[dimensions.length] = "orgunit";
 
444
  }
 
445
  
 
446
  return dimensions;
 
447
}
 
448
 
 
449
/**
 
450
* @return array -> dimension
 
451
*/
 
452
function getRowDimensions()
 
453
{
 
454
  var dimensions = [];
 
455
   
 
456
  if ( !pivotIndicator )
 
457
  {
 
458
    dimensions[dimensions.length] = "indicator";
 
459
  }
 
460
  
 
461
  if ( !pivotPeriod )
 
462
  {
 
463
    dimensions[dimensions.length] = "period";
 
464
  }
 
465
  
 
466
  if ( !pivotOrgunit )
 
467
  {
 
468
    dimensions[dimensions.length] = "orgunit";
 
469
  }
 
470
  
 
471
  return dimensions;
 
472
}
 
473
 
 
474
/**
 
475
 * @param array1 the first associative array.
 
476
 * @param array2 the second associative array.
 
477
 * 
 
478
 * @return an associative array with the merged contents of the input arrays.
 
479
 */
 
480
function mergeArrays( array1, array2 )
 
481
{
 
482
  for ( a2 in array2 )
 
483
  {
 
484
    array1[a2] = array2[a2];
 
485
  }
 
486
  
 
487
  return array1;
 
488
}
 
489
 
 
490
/**
 
491
 * @param column associative array ( columnId, columnName )
 
492
 * @param row associative array ( rowId, rowName )
 
493
 * 
 
494
 * @return the value for the given combination of dimension identifiers.
 
495
 */
 
496
function getValue( column, row )
 
497
{
 
498
  var key = mergeArrays( column, row );
 
499
  
 
500
  var keyString = key.indicatorId + "-" + key.periodId + "-" + key.orgunitId;
 
501
  
 
502
  var value = data[keyString];
 
503
   
 
504
  return value != null ? value : "";
 
505
}
 
506
 
 
507
/**
 
508
 * Clears the table.
 
509
 */
 
510
function clearTable( table )
 
511
{
 
512
  while ( table.rows.length >  0 )
 
513
  {
 
514
    table.deleteRow( 0 );
 
515
  }
 
516
}
 
517
 
 
518
/**
 
519
 * Clears the global variables.
 
520
 */
 
521
function clearGlobalVariables()
 
522
{
 
523
  indicators.length = 0;
 
524
  periods.length = 0;
 
525
  orgunits.length = 0;
 
526
  data.length = 0;
 
527
  sizes.length = 0;
 
528
}