1
Ext.onReady(function() {
4
function SimpleRegression()
6
var sumX = 0; // Sum of x values
7
var sumY = 0; // Sum of y values
8
var sumXX = 0; // Total variation in x
9
var sumXY = 0; // Sum of products
10
var n = 0; // Number of observations
11
var xbar = 0; // Mean of accumulated x values, used in updating formulas
12
var ybar = 0; // Mean of accumulated y values, used in updating formulas
14
this.addData = function( x, y )
25
sumXX += dx * dx * n / ( n + 1 );
26
sumXY += dx * dy * n / ( n + 1 );
27
xbar += dx / ( n + 1 );
28
ybar += dy / ( n + 1 );
36
this.predict = function( x )
38
var b1 = this.getSlope();
40
return this.getIntercept( b1 ) + b1 * x;
43
this.getSlope = function()
53
this.getIntercept = function( slope )
55
return ( sumY - slope * sumX ) / n;
62
Ext.Ajax.method = 'GET';
64
Ext.isIE = function() {
65
return /trident/.test(Ext.userAgent);
74
DV.isSessionStorage = ('sessionStorage' in window && window['sessionStorage'] !== null);
76
DV.getCore = function(init) {
88
path_module: '/dhis-web-visualizer/',
90
path_commons: '/dhis-web-commons-ajax-json/',
91
data_get: 'chartValues.json',
92
indicator_get: 'indicatorGroups/',
93
indicator_getall: 'indicators.json?paging=false&links=false',
94
indicatorgroup_get: 'indicatorGroups.json?paging=false&links=false',
95
dataelement_get: 'dataElementGroups/',
96
dataelement_getall: 'dataElements.json?domainType=aggregate&paging=false&links=false',
97
dataelementgroup_get: 'dataElementGroups.json?paging=false&links=false',
98
dataset_get: 'dataSets.json?paging=false&links=false'
109
name: DV.i18n.indicator,
114
value: 'dataelement',
115
name: DV.i18n.data_element,
127
name: DV.i18n.dataset,
132
name: DV.i18n.assigned_categories,
138
name: DV.i18n.period,
146
value: 'relativePeriods'
149
value: 'organisationUnits',
150
name: DV.i18n.organisation_units,
164
category: 'category',
167
stackedcolumn: 'stackedcolumn',
169
stackedbar: 'stackedbar',
178
targetLine: 'targetline_',
179
baseLine: 'baseline_',
180
trendLine: 'trendline_'
196
dimConf = conf.finals.dimension;
198
dimConf.objectNameMap = {};
199
dimConf.objectNameMap[dimConf.data.objectName] = dimConf.data;
200
dimConf.objectNameMap[dimConf.indicator.objectName] = dimConf.indicator;
201
dimConf.objectNameMap[dimConf.dataElement.objectName] = dimConf.dataElement;
202
dimConf.objectNameMap[dimConf.operand.objectName] = dimConf.operand;
203
dimConf.objectNameMap[dimConf.dataSet.objectName] = dimConf.dataSet;
204
dimConf.objectNameMap[dimConf.category.objectName] = dimConf.category;
205
dimConf.objectNameMap[dimConf.period.objectName] = dimConf.period;
206
dimConf.objectNameMap[dimConf.organisationUnit.objectName] = dimConf.organisationUnit;
207
dimConf.objectNameMap[dimConf.dimension.objectName] = dimConf.dimension;
211
{id: 'Daily', name: DV.i18n.daily},
212
{id: 'Weekly', name: DV.i18n.weekly},
213
{id: 'Monthly', name: DV.i18n.monthly},
214
{id: 'BiMonthly', name: DV.i18n.bimonthly},
215
{id: 'Quarterly', name: DV.i18n.quarterly},
216
{id: 'SixMonthly', name: DV.i18n.sixmonthly},
217
{id: 'SixMonthlyApril', name: DV.i18n.sixmonthly_april},
218
{id: 'Yearly', name: DV.i18n.yearly},
219
{id: 'FinancialOct', name: DV.i18n.financial_oct},
220
{id: 'FinancialJuly', name: DV.i18n.financial_july},
221
{id: 'FinancialApril', name: DV.i18n.financial_april}
227
west_fieldset_width: 418,
228
west_width_padding: 2,
230
west_fill_accordion_indicator: 56,
231
west_fill_accordion_dataelement: 59,
232
west_fill_accordion_dataset: 31,
233
west_fill_accordion_period: 284,
234
west_fill_accordion_organisationunit: 58,
235
west_maxheight_accordion_indicator: 350,
236
west_maxheight_accordion_dataelement: 350,
237
west_maxheight_accordion_dataset: 350,
238
west_maxheight_accordion_period: 513,
239
west_maxheight_accordion_organisationunit: 500,
240
west_maxheight_accordion_group: 350,
241
west_scrollbarheight_accordion_indicator: 300,
242
west_scrollbarheight_accordion_dataelement: 300,
243
west_scrollbarheight_accordion_dataset: 300,
244
west_scrollbarheight_accordion_period: 450,
245
west_scrollbarheight_accordion_organisationunit: 450,
246
west_scrollbarheight_accordion_group: 300,
247
east_tbar_height: 31,
248
east_gridcolumn_height: 30,
249
form_label_width: 55,
250
window_favorite_ypos: 100,
251
window_confirm_width: 250,
252
window_share_width: 500,
253
grid_favorite_width: 420,
255
treepanel_minheight: 135,
256
treepanel_maxheight: 400,
257
treepanel_fill_default: 310,
258
treepanel_toolbar_menu_width_group: 140,
259
treepanel_toolbar_menu_width_level: 120,
260
multiselect_minheight: 100,
261
multiselect_maxheight: 250,
262
multiselect_fill_default: 345,
263
multiselect_fill_reportingrates: 315
269
fontFamily: 'Arial,Sans-serif,Roboto,Helvetica,Consolas'
272
dv1: ['#94ae0a', '#1d5991', '#a61120', '#ff8809', '#7c7474', '#a61187', '#ffd13e', '#24ad9a', '#a66111', '#414141', '#4500c4', '#1d5700']
278
error: 'error_s.png',
279
warning: 'warning.png',
288
'programStage[id,name]',
289
'columns[dimension,filter,items[id,' + init.namePropertyUrl + ']]',
290
'rows[dimension,filter,items[id,' + init.namePropertyUrl + ']]',
291
'filters[dimension,filter,items[id,' + init.namePropertyUrl + ']]',
296
'!rewindRelativePeriods',
297
'!userOrganisationUnit',
298
'!userOrganisationUnitChildren',
299
'!userOrganisationUnitGrandChildren',
307
'!organisationUnitGroups',
308
'!itemOrganisationUnitGroups',
309
'!userGroupAccesses',
312
'!dataElementOperands',
313
'!dataElementGroups',
316
'!organisationUnitLevels',
326
api.layout.Record = function(config) {
327
var config = Ext.clone(config);
332
if (!Ext.isObject(config)) {
333
console.log('Record: config is not an object: ' + config);
337
if (!Ext.isString(config.id)) {
338
alert('Record: id is not text: ' + config);
342
config.id = config.id.replace('.', '#');
348
api.layout.Dimension = function(config) {
349
var config = Ext.clone(config);
356
if (!Ext.isObject(config)) {
357
console.log('Dimension: config is not an object: ' + config);
361
if (!Ext.isString(config.dimension)) {
362
console.log('Dimension: name is not a string: ' + config);
366
if (config.dimension !== conf.finals.dimension.category.objectName) {
369
if (!Ext.isArray(config.items)) {
370
console.log('Dimension: items is not an array: ' + config);
374
for (var i = 0; i < config.items.length; i++) {
375
records.push(api.layout.Record(config.items[i]));
378
config.items = Ext.Array.clean(records);
380
if (!config.items.length) {
381
console.log('Dimension: has no valid items: ' + config);
390
api.layout.Layout = function(config, applyConfig) {
391
var config = Ext.clone(config),
393
getValidatedDimensionArray,
394
validateSpecialCases;
396
// type: string ('column') - 'column', 'stackedcolumn', 'bar', 'stackedbar', 'line', 'area', 'pie'
398
// columns: [Dimension]
402
// filters: [Dimension]
404
// showTrendLine: boolean (false)
406
// targetLineValue: number
408
// targetLineTitle: string
410
// baseLineValue: number
412
// baseLineTitle: string
416
// rangeAxisMaxValue: number
418
// rangeAxisMinValue: number
420
// rangeAxisSteps: number
422
// rangeAxisDecimals: number
424
// showValues: boolean (true)
426
// hideEmptyRows: boolean (false)
428
// hideLegend: boolean (false)
430
// hideTitle: boolean (false)
432
// domainAxisTitle: string
434
// rangeAxisTitle: string
436
// userOrganisationUnit: boolean (false)
438
// userOrganisationUnitChildren: boolean (false)
440
// parentGraphMap: object
442
getValidatedDimensionArray = function(dimensionArray) {
443
var dimensionArray = Ext.clone(dimensionArray);
445
if (!(dimensionArray && Ext.isArray(dimensionArray) && dimensionArray.length)) {
449
for (var i = 0; i < dimensionArray.length; i++) {
450
dimensionArray[i] = api.layout.Dimension(dimensionArray[i]);
453
dimensionArray = Ext.Array.clean(dimensionArray);
455
return dimensionArray.length ? dimensionArray : null;
458
analytical2layout = function(analytical) {
459
var layoutConfig = Ext.clone(analytical),
460
co = dimConf.category.objectName;
462
analytical = Ext.clone(analytical);
464
layoutConfig.columns = [];
465
layoutConfig.rows = [];
466
layoutConfig.filters = layoutConfig.filters || [];
469
if (Ext.isArray(analytical.columns) && analytical.columns.length) {
470
analytical.columns.reverse();
472
for (var i = 0, dim; i < analytical.columns.length; i++) {
473
dim = analytical.columns[i];
475
if (dim.dimension === co) {
479
if (!layoutConfig.columns.length) {
480
layoutConfig.columns.push(dim);
484
// indicators cannot be set as filter
485
if (dim.dimension === dimConf.indicator.objectName) {
486
layoutConfig.filters.push(layoutConfig.columns.pop());
487
layoutConfig.columns = [dim];
490
layoutConfig.filters.push(dim);
497
if (Ext.isArray(analytical.rows) && analytical.rows.length) {
498
analytical.rows.reverse();
500
for (var i = 0, dim; i < analytical.rows.length; i++) {
501
dim = analytical.rows[i];
503
if (dim.dimension === co) {
507
if (!layoutConfig.rows.length) {
508
layoutConfig.rows.push(dim);
512
// indicators cannot be set as filter
513
if (dim.dimension === dimConf.indicator.objectName) {
514
layoutConfig.filters.push(layoutConfig.rows.pop());
515
layoutConfig.rows = [dim];
518
layoutConfig.filters.push(dim);
527
validateSpecialCases = function() {
528
var dimConf = conf.finals.dimension,
530
objectNameDimensionMap = {};
536
dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || []));
538
for (var i = 0; i < dimensions.length; i++) {
539
objectNameDimensionMap[dimensions[i].dimension] = dimensions[i];
542
if (layout.filters && layout.filters.length) {
543
for (var i = 0; i < layout.filters.length; i++) {
545
// Indicators as filter
546
if (layout.filters[i].dimension === dimConf.indicator.objectName) {
547
web.message.alert(DV.i18n.indicators_cannot_be_specified_as_filter || 'Indicators cannot be specified as filter');
551
// Categories as filter
552
if (layout.filters[i].dimension === dimConf.category.objectName) {
553
web.message.alert(DV.i18n.categories_cannot_be_specified_as_filter || 'Categories cannot be specified as filter');
557
// Data sets as filter
558
if (layout.filters[i].dimension === dimConf.dataSet.objectName) {
559
web.message.alert(DV.i18n.data_sets_cannot_be_specified_as_filter || 'Data sets cannot be specified as filter');
566
if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.indicator.objectName]) {
567
web.message.alert('Indicators and detailed data elements cannot be specified together');
572
if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.dataElement.objectName]) {
573
web.message.alert('Detailed data elements and totals cannot be specified together');
578
if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.dataSet.objectName]) {
579
web.message.alert('Data sets and detailed data elements cannot be specified together');
584
if (objectNameDimensionMap[dimConf.operand.objectName] && objectNameDimensionMap[dimConf.category.objectName]) {
585
web.message.alert('Categories and detailed data elements cannot be specified together');
593
var objectNames =Â [],
594
dimConf = conf.finals.dimension;
596
// config must be an object
597
if (!(config && Ext.isObject(config))) {
598
alert('Layout: config is not an object (' + init.el + ')');
602
config.columns = getValidatedDimensionArray(config.columns);
603
config.rows = getValidatedDimensionArray(config.rows);
604
config.filters = getValidatedDimensionArray(config.filters);
606
// at least one dimension specified as column and row
607
if (!config.columns) {
608
alert('No series items selected');
613
alert('No category items selected');
618
for (var i = 0, dims = Ext.Array.clean([].concat(config.columns || [], config.rows || [], config.filters || [])); i < dims.length; i++) {
621
if (api.layout.Dimension(dims[i])) {
622
objectNames.push(dims[i].dimension);
626
// at least one period
627
if (!Ext.Array.contains(objectNames, dimConf.period.objectName)) {
628
alert('At least one period must be specified as series, category or filter');
634
layout.id = config.id;
638
layout.name = config.name;
642
//config = analytical2layout(config);
645
layout.type = Ext.isString(config.type) ? config.type.toLowerCase() : conf.finals.chart.column;
647
layout.columns = config.columns;
648
layout.rows = config.rows;
649
layout.filters = config.filters;
652
layout.showValues = Ext.isBoolean(config.showData) ? config.showData : (Ext.isBoolean(config.showValues) ? config.showValues : true);
653
layout.hideEmptyRows = Ext.isBoolean(config.hideEmptyRows) ? config.hideEmptyRows : (Ext.isBoolean(config.hideEmptyRows) ? config.hideEmptyRows : true);
654
layout.showTrendLine = Ext.isBoolean(config.regression) ? config.regression : (Ext.isBoolean(config.showTrendLine) ? config.showTrendLine : false);
655
layout.targetLineValue = Ext.isNumber(config.targetLineValue) ? config.targetLineValue : null;
656
layout.targetLineTitle = Ext.isString(config.targetLineLabel) && !Ext.isEmpty(config.targetLineLabel) ? config.targetLineLabel :
657
(Ext.isString(config.targetLineTitle) && !Ext.isEmpty(config.targetLineTitle) ? config.targetLineTitle : null);
658
layout.baseLineValue = Ext.isNumber(config.baseLineValue) ? config.baseLineValue : null;
659
layout.baseLineTitle = Ext.isString(config.baseLineLabel) && !Ext.isEmpty(config.baseLineLabel) ? config.baseLineLabel :
660
(Ext.isString(config.baseLineTitle) && !Ext.isEmpty(config.baseLineTitle) ? config.baseLineTitle : null);
661
layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
663
layout.rangeAxisMaxValue = Ext.isNumber(config.rangeAxisMaxValue) ? config.rangeAxisMaxValue : null;
664
layout.rangeAxisMinValue = Ext.isNumber(config.rangeAxisMinValue) ? config.rangeAxisMinValue : null;
665
layout.rangeAxisSteps = Ext.isNumber(config.rangeAxisSteps) ? config.rangeAxisSteps : null;
666
layout.rangeAxisDecimals = Ext.isNumber(config.rangeAxisDecimals) ? config.rangeAxisDecimals : null;
667
layout.rangeAxisTitle = Ext.isString(config.rangeAxisLabel) && !Ext.isEmpty(config.rangeAxisLabel) ? config.rangeAxisLabel :
668
(Ext.isString(config.rangeAxisTitle) && !Ext.isEmpty(config.rangeAxisTitle) ? config.rangeAxisTitle : null);
669
layout.domainAxisTitle = Ext.isString(config.domainAxisLabel) && !Ext.isEmpty(config.domainAxisLabel) ? config.domainAxisLabel :
670
(Ext.isString(config.domainAxisTitle) && !Ext.isEmpty(config.domainAxisTitle) ? config.domainAxisTitle : null);
672
layout.hideLegend = Ext.isBoolean(config.hideLegend) ? config.hideLegend : false;
673
layout.hideTitle = Ext.isBoolean(config.hideTitle) ? config.hideTitle : false;
674
layout.title = Ext.isString(config.title) && !Ext.isEmpty(config.title) ? config.title : null;
676
layout.parentGraphMap = Ext.isObject(config.parentGraphMap) ? config.parentGraphMap : null;
679
if (Ext.isObject(config.domainAxisStyle)) {
680
layout.domainAxisStyle = config.domainAxisStyle;
683
if (Ext.isObject(config.rangeAxisStyle)) {
684
layout.rangeAxisStyle = config.rangeAxisStyle;
687
if (Ext.isObject(config.legendStyle)) {
688
layout.legendStyle = config.legendStyle;
691
if (Ext.isObject(config.seriesStyle)) {
692
layout.seriesStyle = config.seriesStyle;
695
if (!validateSpecialCases()) {
699
return Ext.apply(layout, applyConfig);
705
api.response.Header = function(config) {
706
var config = Ext.clone(config);
713
if (!Ext.isObject(config)) {
714
console.log('Header: config is not an object: ' + config);
718
if (!Ext.isString(config.name)) {
719
console.log('Header: name is not a string: ' + config);
723
if (!Ext.isBoolean(config.meta)) {
724
console.log('Header: meta is not boolean: ' + config);
732
api.response.Response = function(config) {
733
var config = Ext.clone(config);
738
if (!(config && Ext.isObject(config))) {
739
console.log('Response: config is not an object');
743
if (!(config.headers && Ext.isArray(config.headers))) {
744
console.log('Response: headers is not an array');
748
for (var i = 0, header; i < config.headers.length; i++) {
749
config.headers[i] = api.response.Header(config.headers[i]);
752
config.headers = Ext.Array.clean(config.headers);
754
if (!config.headers.length) {
755
console.log('Response: no valid headers');
759
if (!(Ext.isArray(config.rows) && config.rows.length > 0)) {
761
alert('No values found');
766
if (config.headers.length !== config.rows[0].length) {
767
console.log('Response: headers.length !== rows[0].length');
779
support.prototype = {};
782
support.prototype.array = {};
784
support.prototype.array.getLength = function(array, suppressWarning) {
785
if (!Ext.isArray(array)) {
786
if (!suppressWarning) {
787
console.log('support.prototype.array.getLength: not an array');
796
support.prototype.array.sort = function(array, direction, key) {
797
// accepts [number], [string], [{prop: number}], [{prop: string}]
799
if (!support.prototype.array.getLength(array)) {
805
array.sort( function(a, b) {
807
// if object, get the property values
808
if (Ext.isObject(a) && Ext.isObject(b) && key) {
814
if (Ext.isString(a) && Ext.isString(b)) {
818
if (direction === 'DESC') {
819
return a < b ? 1 : (a > b ? -1 : 0);
822
return a < b ? -1 : (a > b ? 1 : 0);
827
else if (Ext.isNumber(a) && Ext.isNumber(b)) {
828
return direction === 'DESC' ? b - a : a - b;
838
support.prototype.object = {};
840
support.prototype.object.getLength = function(object, suppressWarning)Â {
841
if (!Ext.isObject(object)) {
842
if (!suppressWarning) {
843
console.log('support.prototype.object.getLength: not an object');
851
for (var key in object) {
852
if (object.hasOwnProperty(key)) {
860
support.prototype.object.hasObject = function(object, property, value) {
861
if (!support.prototype.object.getLength(object)) {
865
for (var key in object) {
866
var record = object[key];
868
if (object.hasOwnProperty(key) && record[property] === value) {
877
support.prototype.str = {};
879
support.prototype.str.replaceAll = function(variable, find, replace) {
880
if (Ext.isString(variable)) {
881
variable = variable.split(find).join(replace);
883
else if (Ext.isArray(variable)) {
884
for (var i = 0; i < variable.length; i++) {
885
variable[i] = variable[i].split(find).join(replace);
899
service.layout.cleanDimensionArray = function(dimensionArray) {
900
if (!support.prototype.array.getLength(dimensionArray)) {
906
for (var i = 0; i < dimensionArray.length; i++) {
907
array.push(api.layout.Dimension(dimensionArray[i]));
910
array = Ext.Array.clean(array);
912
return array.length ? array : null;
915
service.layout.sortDimensionArray = function(dimensionArray, key) {
916
if (!support.prototype.array.getLength(dimensionArray, true)) {
920
// Clean dimension array
921
dimensionArray = service.layout.cleanDimensionArray(dimensionArray);
923
if (!dimensionArray) {
924
console.log('service.layout.sortDimensionArray: no valid dimensions');
928
key = key || 'dimensionName';
931
Ext.Array.sort(dimensionArray, function(a,b) {
932
if (a[key] < b[key]) {
935
if (a[key] > b[key]) {
941
// Sort object items, ids
942
for (var i = 0, items; i < dimensionArray.length; i++) {
943
support.prototype.array.sort(dimensionArray[i].items, 'ASC', 'id');
945
if (support.prototype.array.getLength(dimensionArray[i].ids)) {
946
support.prototype.array.sort(dimensionArray[i].ids);
950
return dimensionArray;
953
service.layout.getObjectNameDimensionMapFromDimensionArray = function(dimensionArray) {
956
if (!support.prototype.array.getLength(dimensionArray)) {
960
for (var i = 0, dimension; i < dimensionArray.length; i++) {
961
dimension = api.layout.Dimension(dimensionArray[i]);
964
map[dimension.dimension] = dimension;
968
return support.prototype.object.getLength(map) ? map : null;
971
service.layout.getObjectNameDimensionItemsMapFromDimensionArray = function(dimensionArray) {
974
if (!support.prototype.array.getLength(dimensionArray)) {
978
for (var i = 0, dimension; i < dimensionArray.length; i++) {
979
dimension = api.layout.Dimension(dimensionArray[i]);
982
map[dimension.dimension] = dimension.items;
986
return support.prototype.object.getLength(map) ? map : null;
989
service.layout.getExtendedLayout = function(layout) {
990
var layout = Ext.clone(layout),
998
columnObjectNames: [],
999
columnDimensionNames: [],
1001
rowDimensionNames: [],
1005
axisObjectNames: [],
1006
axisDimensionNames: [],
1009
sortedAxisDimensionNames: [],
1012
filterDimensions: [],
1013
filterObjectNames: [],
1014
filterDimensionNames: [],
1017
sortedFilterDimensions: [],
1025
objectNameDimensionsMap: {},
1026
objectNameItemsMap: {},
1027
objectNameIdsMap: {},
1029
// dimension name maps
1030
dimensionNameDimensionsMap: {},
1031
dimensionNameItemsMap: {},
1032
dimensionNameIdsMap: {},
1035
dimensionNameSortedIdsMap: {}
1037
// sort table by column
1038
//sortableIdObjects: []
1041
Ext.applyIf(xLayout, layout);
1043
// columns, rows, filters
1044
if (layout.columns) {
1045
//layout.columns = support.prototype.array.uniqueByProperty(layout.columns, 'dimension');
1047
for (var i = 0, dim, items, xDim; i < layout.columns.length; i++) {
1048
dim = layout.columns[i];
1052
xDim.dimension = dim.dimension;
1053
xDim.objectName = dim.dimension;
1054
xDim.dimensionName = dimConf.objectNameMap.hasOwnProperty(dim.dimension) ? dimConf.objectNameMap[dim.dimension].dimensionName || dim.dimension : dim.dimension;
1062
for (var j = 0; j < items.length; j++) {
1063
xDim.ids.push(items[j].id);
1067
xLayout.columns.push(xDim);
1069
xLayout.columnObjectNames.push(xDim.objectName);
1070
xLayout.columnDimensionNames.push(xDim.dimensionName);
1072
xLayout.axisDimensions.push(xDim);
1073
xLayout.axisObjectNames.push(xDim.objectName);
1074
xLayout.axisDimensionNames.push(dimConf.objectNameMap.hasOwnProperty(xDim.objectName) ? dimConf.objectNameMap[xDim.objectName].dimensionName || xDim.objectName : xDim.objectName);
1076
xLayout.objectNameDimensionsMap[xDim.objectName] = xDim;
1077
xLayout.objectNameItemsMap[xDim.objectName] = xDim.items;
1078
xLayout.objectNameIdsMap[xDim.objectName] = xDim.ids;
1083
//layout.rows = support.prototype.array.uniqueByProperty(layout.rows, 'dimension');
1085
for (var i = 0, dim, items, xDim; i < layout.rows.length; i++) {
1086
dim = Ext.clone(layout.rows[i]);
1090
xDim.dimension = dim.dimension;
1091
xDim.objectName = dim.dimension;
1092
xDim.dimensionName = dimConf.objectNameMap.hasOwnProperty(dim.dimension) ? dimConf.objectNameMap[dim.dimension].dimensionName || dim.dimension : dim.dimension;
1100
for (var j = 0; j < items.length; j++) {
1101
xDim.ids.push(items[j].id);
1105
xLayout.rows.push(xDim);
1107
xLayout.rowObjectNames.push(xDim.objectName);
1108
xLayout.rowDimensionNames.push(xDim.dimensionName);
1110
xLayout.axisDimensions.push(xDim);
1111
xLayout.axisObjectNames.push(xDim.objectName);
1112
xLayout.axisDimensionNames.push(dimConf.objectNameMap.hasOwnProperty(xDim.objectName) ? dimConf.objectNameMap[xDim.objectName].dimensionName || xDim.objectName : xDim.objectName);
1114
xLayout.objectNameDimensionsMap[xDim.objectName] = xDim;
1115
xLayout.objectNameItemsMap[xDim.objectName] = xDim.items;
1116
xLayout.objectNameIdsMap[xDim.objectName] = xDim.ids;
1120
if (layout.filters) {
1121
//layout.filters = support.prototype.array.uniqueByProperty(layout.filters, 'dimension');
1123
for (var i = 0, dim, items, xDim; i < layout.filters.length; i++) {
1124
dim = layout.filters[i];
1128
xDim.dimension = dim.dimension;
1129
xDim.objectName = dim.dimension;
1130
xDim.dimensionName = dimConf.objectNameMap.hasOwnProperty(dim.dimension) ? dimConf.objectNameMap[dim.dimension].dimensionName || dim.dimension : dim.dimension;
1138
for (var j = 0; j < items.length; j++) {
1139
xDim.ids.push(items[j].id);
1143
xLayout.filters.push(xDim);
1145
xLayout.filterDimensions.push(xDim);
1146
xLayout.filterObjectNames.push(xDim.objectName);
1147
xLayout.filterDimensionNames.push(dimConf.objectNameMap.hasOwnProperty(xDim.objectName) ? dimConf.objectNameMap[xDim.objectName].dimensionName || xDim.objectName : xDim.objectName);
1149
xLayout.objectNameDimensionsMap[xDim.objectName] = xDim;
1150
xLayout.objectNameItemsMap[xDim.objectName] = xDim.items;
1151
xLayout.objectNameIdsMap[xDim.objectName] = xDim.ids;
1156
xLayout.legendSet = layout.legendSet ? init.idLegendSetMap[layout.legendSet.id] : null;
1158
if (layout.legendSet && layout.legendSet.mapLegends) {
1159
xLayout.legendSet = init.idLegendSetMap[layout.legendSet.id];
1160
support.prototype.array.sort(xLayout.legendSet.mapLegends, 'ASC', 'startValue');
1163
// unique dimension names
1164
xLayout.axisDimensionNames = Ext.Array.unique(xLayout.axisDimensionNames);
1165
xLayout.filterDimensionNames = Ext.Array.unique(xLayout.filterDimensionNames);
1167
xLayout.columnDimensionNames = Ext.Array.unique(xLayout.columnDimensionNames);
1168
xLayout.rowDimensionNames = Ext.Array.unique(xLayout.rowDimensionNames);
1169
xLayout.filterDimensionNames = Ext.Array.unique(xLayout.filterDimensionNames);
1172
xLayout.sortedAxisDimensionNames = Ext.clone(xLayout.axisDimensionNames).sort();
1173
xLayout.sortedFilterDimensions = service.layout.sortDimensionArray(Ext.clone(xLayout.filterDimensions));
1176
xLayout.dimensions = [].concat(xLayout.axisDimensions, xLayout.filterDimensions);
1177
xLayout.objectNames = [].concat(xLayout.axisObjectNames, xLayout.filterObjectNames);
1178
xLayout.dimensionNames = [].concat(xLayout.axisDimensionNames, xLayout.filterDimensionNames);
1180
// dimension name maps
1181
for (var i = 0, dimName; i < xLayout.dimensionNames.length; i++) {
1182
dimName = xLayout.dimensionNames[i];
1184
xLayout.dimensionNameDimensionsMap[dimName] = [];
1185
xLayout.dimensionNameItemsMap[dimName] = [];
1186
xLayout.dimensionNameIdsMap[dimName] = [];
1189
for (var i = 0, xDim; i < xLayout.dimensions.length; i++) {
1190
xDim = xLayout.dimensions[i];
1192
xLayout.dimensionNameDimensionsMap[xDim.dimensionName].push(xDim);
1193
xLayout.dimensionNameItemsMap[xDim.dimensionName] = xLayout.dimensionNameItemsMap[xDim.dimensionName].concat(xDim.items);
1194
xLayout.dimensionNameIdsMap[xDim.dimensionName] = xLayout.dimensionNameIdsMap[xDim.dimensionName].concat(xDim.ids);
1198
for (var key in xLayout.dimensionNameIdsMap) {
1199
if (xLayout.dimensionNameIdsMap.hasOwnProperty(key)) {
1200
xLayout.dimensionNameSortedIdsMap[key] = Ext.clone(xLayout.dimensionNameIdsMap[key]).sort();
1205
xLayout.tableUuid = init.el + '_' + Ext.data.IdGenerator.get('uuid').generate();
1210
service.layout.getSyncronizedXLayout = function(xLayout, response) {
1211
var dimensions = Ext.Array.clean([].concat(xLayout.columns || [], xLayout.rows || [], xLayout.filters || [])),
1212
xOuDimension = xLayout.objectNameDimensionsMap[dimConf.organisationUnit.objectName],
1213
isUserOrgunit = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT'),
1214
isUserOrgunitChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_CHILDREN'),
1215
isUserOrgunitGrandChildren = xOuDimension && Ext.Array.contains(xOuDimension.ids, 'USER_ORGUNIT_GRANDCHILDREN'),
1216
isLevel = function() {
1217
if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
1218
for (var i = 0; i < xOuDimension.ids.length; i++) {
1219
if (xOuDimension.ids[i].substr(0,5) === 'LEVEL') {
1227
isGroup = function() {
1228
if (xOuDimension && Ext.isArray(xOuDimension.ids)) {
1229
for (var i = 0; i < xOuDimension.ids.length; i++) {
1230
if (xOuDimension.ids[i].substr(0,8) === 'OU_GROUP') {
1238
ou = dimConf.organisationUnit.objectName,
1241
// Set items from init/metaData/xLayout
1242
for (var i = 0, dim, metaDataDim, items; i < dimensions.length; i++) {
1243
dim = dimensions[i];
1245
metaDataDim = response.metaData[dim.objectName];
1247
// If ou and children
1248
if (dim.dimensionName === ou) {
1249
if (isUserOrgunit || isUserOrgunitChildren || isUserOrgunitGrandChildren) {
1254
if (init.user && isUserOrgunit) {
1257
for (var j = 0; j < init.user.ou.length; j++) {
1259
id: init.user.ou[j],
1260
name: response.metaData.names[init.user.ou[j]]
1264
if (init.user && init.user.ouc && isUserOrgunitChildren) {
1267
for (var j = 0; j < init.user.ouc.length; j++) {
1269
id: init.user.ouc[j],
1270
name: response.metaData.names[init.user.ouc[j]]
1274
support.prototype.array.sort(userOuc);
1276
if (init.user && init.user.ouc && isUserOrgunitGrandChildren) {
1277
var userOuOuc = [].concat(init.user.ou, init.user.ouc),
1278
responseOu = response.metaData[ou];
1282
for (var j = 0, id; j < responseOu.length; j++) {
1285
if (!Ext.Array.contains(userOuOuc, id)) {
1288
name: response.metaData.names[id]
1293
support.prototype.array.sort(userOugc);
1296
dim.items = [].concat(userOu || [], userOuc || [], userOugc || []);
1298
else if (isLevel || isGroup) {
1299
for (var j = 0, responseOu = response.metaData[ou], id; j < responseOu.length; j++) {
1304
name: response.metaData.names[id]
1308
support.prototype.array.sort(dim.items);
1311
dim.items = Ext.clone(xLayout.dimensionNameItemsMap[dim.dimensionName]);
1315
// Items: get ids from metadata -> items
1316
if (Ext.isArray(metaDataDim) && metaDataDim.length) {
1317
var ids = Ext.clone(response.metaData[dim.dimensionName]);
1318
for (var j = 0; j < ids.length; j++) {
1321
name: response.metaData.names[ids[j]]
1325
// Items: get items from xLayout
1327
dim.items = Ext.clone(xLayout.objectNameItemsMap[dim.objectName]);
1333
layout = api.layout.Layout(xLayout);
1336
dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || []));
1338
for (var i = 0, idNameMap = response.metaData.names, dimItems; i < dimensions.length; i++) {
1339
dimItems = dimensions[i].items;
1341
if (Ext.isArray(dimItems) && dimItems.length) {
1342
for (var j = 0, item; j < dimItems.length; j++) {
1345
if (Ext.isObject(item) && Ext.isString(idNameMap[item.id]) && !Ext.isString(item.name)) {
1346
item.name = idNameMap[item.id] || '';
1352
return service.layout.getExtendedLayout(layout);
1358
service.layout.layout2plugin = function(layout, el) {
1359
var layout = Ext.clone(layout),
1360
dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [], layout.filters || []));
1362
layout.url = init.contextPath;
1368
if (Ext.isString(layout.id)) {
1369
return {id: layout.id};
1372
for (var i = 0, dimension, item; i < dimensions.length; i++) {
1373
dimension = dimensions[i];
1375
delete dimension.id;
1376
delete dimension.ids;
1377
delete dimension.type;
1378
delete dimension.dimensionName;
1379
delete dimension.objectName;
1381
for (var j = 0, item; j < dimension.items.length; j++) {
1382
item = dimension.items[j];
1386
delete item.created;
1387
delete item.lastUpdated;
1392
if (!layout.hideEmptyRows) {
1393
delete layout.hideEmptyRows;
1396
if (!layout.showTrendLine) {
1397
delete layout.showTrendLine;
1400
if (!layout.targetLineValue) {
1401
delete layout.targetLineValue;
1404
if (!layout.targetLineTitle) {
1405
delete layout.targetLineTitle;
1408
if (!layout.baseLineValue) {
1409
delete layout.baseLineValue;
1412
if (!layout.baseLineTitle) {
1413
delete layout.baseLineTitle;
1416
if (!layout.hideLegend) {
1417
delete layout.hideLegend;
1420
if (!layout.hideTitle) {
1421
delete layout.hideTitle;
1424
if (!layout.title) {
1425
delete layout.title;
1428
if (!layout.domainAxisTitle) {
1429
delete layout.domainAxisTitle;
1432
if (!layout.rangeAxisTitle) {
1433
delete layout.rangeAxisTitle;
1436
if (!layout.rangeAxisMaxValue) {
1437
delete layout.rangeAxisMaxValue;
1440
if (!layout.rangeAxisMinValue) {
1441
delete layout.rangeAxisMinValue;
1444
if (!layout.rangeAxisSteps) {
1445
delete layout.rangeAxisSteps;
1448
if (!layout.rangeAxisDecimals) {
1449
delete layout.rangeAxisDecimals;
1452
if (!layout.sorting) {
1453
delete layout.sorting;
1456
if (!layout.legend) {
1457
delete layout.legend;
1462
if (layout.showValues) {
1463
delete layout.showValues;
1466
delete layout.parentGraphMap;
1467
delete layout.reportingPeriod;
1468
delete layout.organisationUnit;
1469
delete layout.parentOrganisationUnit;
1470
delete layout.regression;
1471
delete layout.cumulative;
1472
delete layout.topLimit;
1477
service.layout.analytical2layout = function(analytical) {
1478
var layoutConfig = Ext.clone(analytical),
1479
co = dimConf.category.objectName;
1481
analytical = Ext.clone(analytical);
1483
layoutConfig.columns = [];
1484
layoutConfig.rows = [];
1485
layoutConfig.filters = layoutConfig.filters || [];
1488
if (Ext.isArray(analytical.columns) && analytical.columns.length) {
1489
analytical.columns.reverse();
1491
for (var i = 0, dim; i < analytical.columns.length; i++) {
1492
dim = analytical.columns[i];
1494
if (dim.dimension === co) {
1498
if (!layoutConfig.columns.length) {
1499
layoutConfig.columns.push(dim);
1503
// indicators cannot be set as filter
1504
if (dim.dimension === dimConf.indicator.objectName) {
1505
layoutConfig.filters.push(layoutConfig.columns.pop());
1506
layoutConfig.columns = [dim];
1509
layoutConfig.filters.push(dim);
1516
if (Ext.isArray(analytical.rows) && analytical.rows.length) {
1517
analytical.rows.reverse();
1519
for (var i = 0, dim; i < analytical.rows.length; i++) {
1520
dim = analytical.rows[i];
1522
if (dim.dimension === co) {
1526
if (!layoutConfig.rows.length) {
1527
layoutConfig.rows.push(dim);
1531
// indicators cannot be set as filter
1532
if (dim.dimension === dimConf.indicator.objectName) {
1533
layoutConfig.filters.push(layoutConfig.rows.pop());
1534
layoutConfig.rows = [dim];
1537
layoutConfig.filters.push(dim);
1543
return layoutConfig;
1547
service.response = {};
1549
service.response.getExtendedResponse = function(xLayout, response) {
1552
response.nameHeaderMap = {};
1553
response.idValueMap = {};
1558
// extend headers: index, ids, size
1559
for (var i = 0, header; i < response.headers.length; i++) {
1560
header = response.headers[i];
1568
header.ids = Ext.clone(xLayout.dimensionNameIdsMap[header.name]) || [];
1571
header.size = header.ids.length;
1573
// collect ids, used by extendMetaData
1574
ids = ids.concat(header.ids);
1578
// nameHeaderMap (headerName: header)
1579
for (var i = 0, header; i < response.headers.length; i++) {
1580
header = response.headers[i];
1582
response.nameHeaderMap[header.name] = header;
1588
for (var i = 0, id, splitId ; i < ids.length; i++) {
1591
if (id.indexOf('#') !== -1) {
1592
splitId = id.split('#');
1593
response.metaData.names[id] = response.metaData.names[splitId[0]] + ' ' + response.metaData.names[splitId[1]];
1598
// create value id map
1600
var valueHeaderIndex = response.nameHeaderMap[conf.finals.dimension.value.value].index,
1601
coHeader = response.nameHeaderMap[conf.finals.dimension.category.dimensionName],
1602
dx = dimConf.data.dimensionName,
1603
co = dimConf.category.dimensionName,
1604
axisDimensionNames = xLayout.axisDimensionNames,
1608
for (var i = 0; i < axisDimensionNames.length; i++) {
1609
idIndexOrder.push(response.nameHeaderMap[axisDimensionNames[i]].index);
1611
// If co exists in response and is not added in layout, add co after dx
1612
if (coHeader && !Ext.Array.contains(axisDimensionNames, co) && axisDimensionNames[i] === dx) {
1613
idIndexOrder.push(coHeader.index);
1618
for (var i = 0, row, id; i < response.rows.length; i++) {
1619
row = response.rows[i];
1622
for (var j = 0; j < idIndexOrder.length; j++) {
1623
id += row[idIndexOrder[j]];
1626
response.idValueMap[id] = row[valueHeaderIndex];
1634
service.mapLegend = {};
1636
service.mapLegend.getColorByValue = function(legendSet, value) {
1639
if (!(legendSet && value)) {
1643
for (var i = 0, legend; i < legendSet.mapLegends.length; i++) {
1644
legend = legendSet.mapLegends[i];
1646
if (value >= parseFloat(legend.startValue) && value < parseFloat(legend.endValue)) {
1647
return legend.color;
1661
web.mask.show = function(component, message) {
1662
if (init.skipMask) {
1666
if (!Ext.isObject(component)) {
1667
console.log('support.gui.mask.show: component not an object');
1671
message = message || 'Loading..';
1673
if (component.mask) {
1674
component.mask.destroy();
1675
component.mask = null;
1678
component.mask = new Ext.create('Ext.LoadMask', component, {
1681
style: 'box-shadow:0',
1682
bodyStyle: 'box-shadow:0'
1685
component.mask.show();
1688
web.mask.hide = function(component) {
1689
if (init.skipMask) {
1693
if (!Ext.isObject(component)) {
1694
console.log('support.gui.mask.hide: component not an object');
1698
if (component.mask) {
1699
component.mask.destroy();
1700
component.mask = null;
1707
web.message.alert = function(message)Â {
1708
console.log(message);
1714
web.analytics.getParamString = function(xLayout, isSorted) {
1715
var axisDimensionNames = isSorted ? xLayout.sortedAxisDimensionNames : xLayout.axisDimensionNames,
1716
filterDimensions = isSorted ? xLayout.sortedFilterDimensions : xLayout.filterDimensions,
1717
dimensionNameIdsMap = isSorted ? xLayout.dimensionNameSortedIdsMap : xLayout.dimensionNameIdsMap,
1719
addCategoryDimension = false,
1720
map = xLayout.dimensionNameItemsMap,
1721
dx = dimConf.indicator.dimensionName;
1723
for (var i = 0, dimName, items; i < axisDimensionNames.length; i++) {
1724
dimName = axisDimensionNames[i];
1726
paramString += 'dimension=' + dimName;
1728
items = Ext.clone(dimensionNameIdsMap[dimName]);
1730
if (dimName === dx) {
1731
for (var j = 0, index; j < items.length; j++) {
1732
index = items[j].indexOf('#');
1735
addCategoryDimension = true;
1736
items[j] = items[j].substr(0, index);
1740
items = Ext.Array.unique(items);
1743
if (dimName !== dimConf.category.dimensionName) {
1744
paramString += ':' + items.join(';');
1747
if (i < (axisDimensionNames.length - 1)) {
1752
if (addCategoryDimension) {
1753
paramString += '&dimension=' + conf.finals.dimension.category.dimensionName;
1756
if (Ext.isArray(filterDimensions) && filterDimensions.length) {
1757
for (var i = 0, dim; i < filterDimensions.length; i++) {
1758
dim = filterDimensions[i];
1760
paramString += '&filter=' + dim.dimensionName + ':' + dim.ids.join(';');
1765
paramString += '&displayProperty=' + init.userAccount.settings.keyAnalysisDisplayProperty.toUpperCase();
1770
web.analytics.validateUrl = function(url) {
1774
msg = 'Too many items selected (url has ' + url.length + ' characters). Internet Explorer accepts maximum 2048 characters.';
1777
var len = url.length > 8000 ? '8000' : (url.length > 4000 ? '4000' : '2000');
1778
msg = 'Too many items selected (url has ' + url.length + ' characters). Please reduce to less than ' + len + ' characters.';
1781
msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
1789
web.chart.createChart = function(ns, legendSet) {
1790
var xLayout = ns.app.xLayout,
1791
xResponse = ns.app.xResponse,
1792
columnIds = xLayout.columnDimensionNames[0] ? xLayout.dimensionNameIdsMap[xLayout.columnDimensionNames[0]] : [],
1793
failSafeColumnIds = [],
1794
failSafeColumnIdMap = {},
1795
createFailSafeIds = function() {
1796
for (var i = 0, uuid; i < columnIds.length; i++) {
1797
uuid = Ext.data.IdGenerator.get('uuid').generate();
1799
failSafeColumnIds.push(uuid);
1800
failSafeColumnIdMap[uuid] = columnIds[i];
1802
xResponse.metaData.names[uuid] = xResponse.metaData.names[columnIds[i]];
1807
rowIds = xLayout.rowDimensionNames[0] ? xLayout.dimensionNameIdsMap[xLayout.rowDimensionNames[0]] : [],
1810
filterIds = function() {
1813
if (xLayout.filters) {
1814
for (var i = 0; i < xLayout.filters.length; i++) {
1815
ids = ids.concat(xLayout.filters[i].ids || []);
1823
dataTotalKey = Ext.data.IdGenerator.get('uuid').generate(),
1824
addDataTotals = function(data, ids) {
1825
for (var i = 0, obj, total; i < data.length; i++) {
1829
for (var j = 0; j < ids.length; j++) {
1830
total += parseFloat(obj[ids[j]]);
1831
obj[dataTotalKey] = total;
1836
getSyncronizedXLayout,
1837
getExtendedResponse,
1841
getDefaultNumericAxis,
1842
getDefaultCategoryAxis,
1843
getDefaultSeriesTitle,
1845
getDefaultTrendLines,
1846
getDefaultTargetLine,
1851
getDefaultChartTitle,
1852
getDefaultChartSizeHandler,
1853
getDefaultChartTitlePositionHandler,
1858
getDefaultStore = function(isStacked) {
1860
trendLineFields = [],
1861
targetLineFields = [],
1862
baseLineFields = [],
1866
for (var i = 0, obj, category, rowValues, isEmpty; i < rowIds.length; i++) {
1868
category = rowIds[i];
1872
obj[conf.finals.data.domain] = xResponse.metaData.names[category];
1874
for (var j = 0, id, value; j < columnIds.length; j++) {
1875
id = support.prototype.str.replaceAll(columnIds[j], '#', '') + support.prototype.str.replaceAll(rowIds[i], '#', '');
1876
value = xResponse.idValueMap[id];
1877
rowValues.push(value);
1879
obj[failSafeColumnIds[j]] = value ? parseFloat(value) : '0.0';
1882
isEmpty = !(Ext.Array.clean(rowValues).length);
1884
if (!(isEmpty && xLayout.hideEmptyRows)) {
1891
addDataTotals(data, failSafeColumnIds);
1895
if (xLayout.sortOrder) {
1896
var sortingKey = isStacked ? dataTotalKey : failSafeColumnIds[0];
1898
support.prototype.array.sort(data, xLayout.sortOrder === -1 ? 'ASC' : 'DESC', sortingKey);
1902
if (xLayout.showTrendLine) {
1907
regression = new SimpleRegression();
1908
regressionKey = conf.finals.data.trendLine + dataTotalKey;
1910
for (var i = 0, value; i < data.length; i++) {
1911
value = data[i][dataTotalKey];
1912
regression.addData(i, parseFloat(value));
1915
for (var i = 0; i < data.length; i++) {
1916
data[i][regressionKey] = parseFloat(regression.predict(i).toFixed(1));
1919
trendLineFields.push(regressionKey);
1920
xResponse.metaData.names[regressionKey] = DV.i18n.trend + ' (Total)';
1923
for (var i = 0; i < failSafeColumnIds.length; i++) {
1924
regression = new SimpleRegression();
1925
regressionKey = conf.finals.data.trendLine + failSafeColumnIds[i];
1927
for (var j = 0, value; j < data.length; j++) {
1928
value = data[j][failSafeColumnIds[i]];
1929
regression.addData(j, parseFloat(value));
1932
for (var j = 0; j < data.length; j++) {
1933
data[j][regressionKey] = parseFloat(regression.predict(j).toFixed(1));
1936
trendLineFields.push(regressionKey);
1937
xResponse.metaData.names[regressionKey] = DV.i18n.trend + ' (' + xResponse.metaData.names[failSafeColumnIds[i]] + ')';
1943
if (Ext.isNumber(xLayout.targetLineValue) || Ext.isNumber(parseFloat(xLayout.targetLineValue))) {
1944
for (var i = 0; i < data.length; i++) {
1945
data[i][conf.finals.data.targetLine] = parseFloat(xLayout.targetLineValue);
1948
targetLineFields.push(conf.finals.data.targetLine);
1952
if (Ext.isNumber(xLayout.baseLineValue) || Ext.isNumber(parseFloat(xLayout.baseLineValue))) {
1953
for (var i = 0; i < data.length; i++) {
1954
data[i][conf.finals.data.baseLine] = parseFloat(xLayout.baseLineValue);
1957
baseLineFields.push(conf.finals.data.baseLine);
1960
store = Ext.create('Ext.data.Store', {
1961
fields: function() {
1962
var fields = Ext.clone(failSafeColumnIds);
1963
fields.push(conf.finals.data.domain);
1964
fields = fields.concat(trendLineFields, targetLineFields, baseLineFields);
1971
store.rangeFields = failSafeColumnIds;
1972
store.domainFields = [conf.finals.data.domain];
1973
store.trendLineFields = trendLineFields;
1974
store.targetLineFields = targetLineFields;
1975
store.baseLineFields = baseLineFields;
1976
store.numericFields = [].concat(store.rangeFields, store.trendLineFields, store.targetLineFields, store.baseLineFields);
1978
store.getMaximum = function() {
1981
for (var i = 0; i < store.numericFields.length; i++) {
1982
maximums.push(store.max(store.numericFields[i]));
1985
return Ext.Array.max(maximums);
1988
store.getMinimum = function() {
1991
for (var i = 0; i < store.numericFields.length; i++) {
1992
minimums.push(store.min(store.numericFields[i]));
1995
return Ext.Array.min(minimums);
1998
store.getMaximumSum = function() {
2002
store.each(function(record) {
2005
for (var i = 0; i < store.rangeFields.length; i++) {
2006
recordSum += record.data[store.rangeFields[i]];
2009
sums.push(recordSum);
2012
return Ext.Array.max(sums);
2015
store.hasDecimals = function() {
2016
var records = store.getRange();
2018
for (var i = 0; i < records.length; i++) {
2019
for (var j = 0, value; j < store.rangeFields.length; j++) {
2020
value = records[i].data[store.rangeFields[j]];
2022
if (Ext.isNumber(value) && (value % 1)) {
2031
store.getNumberOfDecimals = function() {
2032
var records = store.getRange(),
2035
for (var i = 0; i < records.length; i++) {
2036
for (var j = 0, value; j < store.rangeFields.length; j++) {
2037
value = records[i].data[store.rangeFields[j]];
2039
if (Ext.isNumber(value) && (value % 1)) {
2040
value = value.toString();
2042
values.push(value.length - value.indexOf('.') - 1);
2047
return Ext.Array.max(values);
2051
console.log("data", data);
2052
console.log("rangeFields", store.rangeFields);
2053
console.log("domainFields", store.domainFields);
2054
console.log("trendLineFields", store.trendLineFields);
2055
console.log("targetLineFields", store.targetLineFields);
2056
console.log("baseLineFields", store.baseLineFields);
2062
getDefaultNumericAxis = function(store) {
2063
var labelFont = 'normal 11px ' + conf.chart.style.fontFamily,
2064
labelColor = 'black',
2066
titleFont = 'bold 12px ' + conf.chart.style.fontFamily,
2067
titleColor = 'black',
2069
typeConf = conf.finals.chart,
2070
minimum = store.getMinimum(),
2075
getRenderer = function(numberOfDecimals) {
2076
var renderer = '0.';
2078
for (var i = 0; i < numberOfDecimals; i++) {
2085
// set maximum if stacked + extra line
2086
if ((xLayout.type === typeConf.stackedcolumn || xLayout.type === typeConf.stackedbar) &&
2087
(xLayout.showTrendLine || xLayout.targetLineValue || xLayout.baseLineValue)) {
2088
var a = [store.getMaximum(), store.getMaximumSum()];
2089
maximum = Math.ceil(Ext.Array.max(a) * 1.1);
2090
maximum = Math.floor(maximum / 10) * 10;
2094
numberOfDecimals = store.getNumberOfDecimals();
2095
renderer = !!numberOfDecimals && (store.getMaximum() < 20) ? getRenderer(numberOfDecimals) : '0,0';
2100
fields: store.numericFields,
2101
minimum: minimum < 0 ? minimum : 0,
2103
renderer: Ext.util.Format.numberRenderer(renderer),
2112
'stroke-width': 0.03
2117
'stroke-width': 0.03
2123
axis.maximum = maximum;
2126
if (xLayout.rangeAxisMaxValue) {
2127
axis.maximum = xLayout.rangeAxisMaxValue;
2130
if (xLayout.rangeAxisMinValue) {
2131
axis.minimum = xLayout.rangeAxisMinValue;
2134
if (xLayout.rangeAxisSteps) {
2135
axis.majorTickSteps = xLayout.rangeAxisSteps - 1;
2138
if (xLayout.rangeAxisDecimals) {
2139
axis.label.renderer = Ext.util.Format.numberRenderer(getRenderer(xLayout.rangeAxisDecimals));
2142
if (xLayout.rangeAxisTitle) {
2143
axis.title = xLayout.rangeAxisTitle;
2147
if (Ext.isObject(xLayout.rangeAxisStyle)) {
2148
var style = xLayout.rangeAxisStyle;
2151
labelColor = style.labelColor || labelColor;
2153
if (style.labelFont) {
2154
labelFont = style.labelFont;
2157
labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal ';
2158
labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px ';
2159
labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily;
2163
if (Ext.isNumber(parseFloat(style.labelRotation))) {
2164
labelRotation = 360 - parseFloat(style.labelRotation);
2168
titleColor = style.titleColor || titleColor;
2170
if (style.titleFont) {
2171
titleFont = style.titleFont;
2174
titleFont = style.titleFontWeight ? style.titleFontWeight + ' ' : 'bold ';
2175
titleFont += style.titleFontSize ? parseFloat(style.titleFontSize) + 'px ' : '12px ';
2176
titleFont += style.titleFontFamily ? style.titleFontFamily : conf.chart.style.fontFamily;
2180
axis.label.style.fill = labelColor;
2181
axis.label.style.font = labelFont;
2182
axis.label.rotate.degrees = labelRotation;
2184
axis.labelTitle.fill = titleColor;
2185
axis.labelTitle.font = titleFont;
2190
getDefaultCategoryAxis = function(store) {
2191
var labelFont = 'normal 11px ' + conf.chart.style.fontFamily,
2192
labelColor = 'black',
2193
labelRotation = 315,
2194
titleFont = 'bold 12px ' + conf.chart.style.fontFamily,
2195
titleColor = 'black',
2200
fields: store.domainFields,
2208
if (xLayout.domainAxisTitle) {
2209
axis.title = xLayout.domainAxisTitle;
2213
if (Ext.isObject(xLayout.domainAxisStyle)) {
2214
var style = xLayout.domainAxisStyle;
2217
labelColor = style.labelColor || labelColor;
2219
if (style.labelFont) {
2220
labelFont = style.labelFont;
2223
labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal ';
2224
labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px ';
2225
labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily;
2229
if (Ext.isNumber(parseFloat(style.labelRotation))) {
2230
labelRotation = 360 - parseFloat(style.labelRotation);
2234
titleColor = style.titleColor || titleColor;
2236
if (style.titleFont) {
2237
titleFont = style.titleFont;
2240
titleFont = style.titleFontWeight ? style.titleFontWeight + ' ' : 'bold ';
2241
titleFont += style.titleFontSize ? parseFloat(style.titleFontSize) + 'px ' : '12px ';
2242
titleFont += style.titleFontFamily ? style.titleFontFamily : conf.chart.style.fontFamily;
2246
axis.label.style.fill = labelColor;
2247
axis.label.style.font = labelFont;
2248
axis.label.rotate.degrees = labelRotation;
2250
axis.labelTitle.fill = titleColor;
2251
axis.labelTitle.font = titleFont;
2256
getDefaultSeriesTitle = function(store) {
2259
if (Ext.isObject(xLayout.legendStyle) && Ext.isArray(xLayout.legendStyle.labelNames)) {
2260
return xLayout.legendStyle.labelNames;
2263
for (var i = 0, id, name, mxl, ids; i < store.rangeFields.length; i++) {
2264
id = failSafeColumnIdMap[store.rangeFields[i]];
2265
name = xResponse.metaData.names[id];
2267
if (Ext.isString(name) && Ext.isObject(xLayout.legendStyle) && Ext.isNumber(xLayout.legendStyle.labelMaxLength)) {
2268
var mxl = parseInt(xLayout.legendStyle.labelMaxLength);
2270
name = name.length > mxl ? name.substr(0, mxl) + '..' : name;
2280
getDefaultSeries = function(store) {
2284
xField: store.domainFields,
2285
yField: store.rangeFields,
2294
tips: getDefaultTips(),
2295
title: getDefaultSeriesTitle(store)
2298
if (xLayout.showValues) {
2299
var labelFont = conf.chart.style.fontFamily,
2300
labelColor = 'black';
2302
if (Ext.isObject(xLayout.seriesStyle)) {
2303
var style = xLayout.seriesStyle;
2306
labelColor = style.labelColor || labelColor;
2308
if (style.labelFont) {
2309
labelFont = style.labelFont;
2312
labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal ';
2313
labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px ';
2314
labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily;
2320
'text-anchor': 'middle',
2321
field: store.rangeFields,
2324
renderer: function(n) {
2325
return n === '0.0' ? '' : n;
2333
getDefaultTrendLines = function(store, isStacked) {
2336
for (var i = 0, strokeColor; i < store.trendLineFields.length; i++) {
2337
strokeColor = isStacked ? '#000' : conf.chart.theme.dv1[i];
2342
xField: store.domainFields,
2343
yField: store.trendLineFields[i],
2347
'stroke-dasharray': 14,
2356
var title = xResponse.metaData.names[store.trendLineFields[i]],
2357
ls = xLayout.legendStyle;
2358
return ls && Ext.isNumber(ls.labelMaxLength) ? title.substr(0, ls.labelMaxLength) + '..' : title;
2366
getDefaultTargetLine = function(store) {
2370
xField: store.domainFields,
2371
yField: store.targetLineFields,
2380
var title = (Ext.isString(xLayout.targetLineTitle) ? xLayout.targetLineTitle : DV.i18n.target) + ' (' + xLayout.targetLineValue + ')',
2381
ls = xLayout.legendStyle;
2382
return ls && Ext.isNumber(ls.labelMaxLength) ? title.substr(0, ls.labelMaxLength) + '..' : title;
2387
getDefaultBaseLine = function(store) {
2391
xField: store.domainFields,
2392
yField: store.baseLineFields,
2401
var title = (Ext.isString(xLayout.baseLineTitle) ? xLayout.baseLineTitle : DV.i18n.base) + ' (' + xLayout.baseLineValue + ')',
2402
ls = xLayout.legendStyle;
2403
return ls && Ext.isNumber(ls.labelMaxLength) ? title.substr(0, ls.labelMaxLength) + '..' : title;
2408
getDefaultTips = function() {
2411
cls: 'dv-chart-tips',
2412
renderer: function(si, item) {
2414
var value = item.value[1] === '0.0' ? '-' : item.value[1];
2415
this.update('<div style="text-align:center"><div style="font-size:17px; font-weight:bold">' + value + '</div><div style="font-size:10px">' + si.data[conf.finals.data.domain] + '</div></div>');
2421
setDefaultTheme = function(store) {
2422
var colors = conf.chart.theme.dv1.slice(0, store.rangeFields.length);
2424
Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, {
2425
constructor: function(config) {
2426
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
2427
seriesThemes: colors,
2434
getDefaultLegend = function(store, chartConfig) {
2435
var itemLength = 30,
2442
labelFont = '11px ' + conf.chart.style.fontFamily,
2445
positions = ['top', 'right', 'bottom', 'left'],
2446
series = chartConfig.series;
2448
if (xLayout.type === conf.finals.chart.pie) {
2449
numberOfItems = store.getCount();
2450
store.each(function(r) {
2451
str += r.data[store.domainFields[0]];
2455
for (var i = 0, title; i < series.length; i++) {
2456
title = series[i].title;
2458
if (Ext.isString(title)) {
2460
numberOfChars += title.length;
2462
else if (Ext.isArray(title)) {
2463
numberOfItems += title.length;
2464
numberOfChars += title.toString().split(',').join('').length;
2469
width = (numberOfItems * itemLength) + (numberOfChars * charLength);
2471
if (width > ns.app.centerRegion.getWidth() - 10) {
2477
if (Ext.isObject(xLayout.legendStyle)) {
2478
var style = xLayout.legendStyle;
2480
if (Ext.Array.contains(positions, style.position)) {
2481
position = style.position;
2484
if (style.labelFont) {
2485
labelFont = style.labelFont;
2488
labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal ';
2489
labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px ';
2490
labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily;
2495
if (position === 'right') {
2499
return Ext.create('Ext.chart.Legend', {
2501
isVertical: isVertical,
2502
labelFont: labelFont,
2503
boxStroke: '#ffffff',
2509
getDefaultChartTitle = function(store) {
2514
isPie = xLayout.type === conf.finals.chart.pie,
2515
isGauge = xLayout.type === conf.finals.chart.gauge;
2518
ids.push(columnIds[0]);
2521
ids.push(columnIds[0], rowIds[0]);
2524
ids = Ext.Array.clean(ids.concat(filterIds || []));
2526
if (Ext.isArray(ids) && ids.length) {
2527
for (var i = 0; i < ids.length; i++) {
2528
text += xResponse.metaData.names[ids[i]];
2529
text += i < ids.length - 1 ? ', ' : '';
2533
if (xLayout.title) {
2534
text = xLayout.title;
2537
fontSize = (ns.app.centerRegion.getWidth() / text.length) < 11.6 ? 12 : 17;
2538
titleFont = 'normal ' + fontSize + 'px ' + conf.chart.style.fontFamily;
2539
titleColor = 'black';
2542
if (Ext.isObject(xLayout.legendStyle)) {
2543
var style = xLayout.legendStyle;
2545
titleColor = style.titleColor || titleColor;
2547
if (style.titleFont) {
2548
titleFont = style.titleFont;
2551
titleFont = style.titleFontWeight ? style.titleFontWeight + ' ' : 'normal ';
2552
titleFont += style.titleFontSize ? parseFloat(style.titleFontSize) + 'px ' : (fontSize + 'px ');
2553
titleFont += style.titleFontFamily ? style.titleFontFamily : conf.chart.style.fontFamily;
2557
return Ext.create('Ext.draw.Sprite', {
2563
y: ns.dashboard ? 11 : 20
2567
getDefaultChartSizeHandler = function() {
2569
//this.animate = false;
2570
this.setWidth(ns.app.centerRegion.getWidth() - 15);
2571
this.setHeight(ns.app.centerRegion.getHeight() - 40);
2572
//this.animate = true;
2576
getDefaultChartTitlePositionHandler = function() {
2579
var title = this.items[0],
2580
titleWidth = Ext.isIE ? title.el.dom.scrollWidth : title.el.getWidth(),
2581
titleXFallback = 10,
2582
legend = this.legend,
2586
if (this.legend.position === 'top') {
2587
legendCenterX = legend.x + (legend.width / 2);
2588
titleX = titleWidth ? legendCenterX - (titleWidth / 2) : titleXFallback;
2591
var legendWidth = legend ? legend.width : 0;
2592
titleX = titleWidth ? (this.width / 2) - (titleWidth / 2) : titleXFallback;
2595
title.setAttributes({
2602
getDefaultChart = function(config) {
2604
store = config.store || {},
2609
insetPadding: ns.dashboard ? 23 : 35,
2610
width: ns.app.centerRegion.getWidth() - 15,
2611
height: ns.app.centerRegion.getHeight() - 40,
2616
if (!xLayout.hideLegend) {
2617
defaultConfig.legend = getDefaultLegend(store, config);
2619
if (defaultConfig.legend.position === 'right') {
2620
defaultConfig.insetPadding = ns.dashboard ? 32 : 40;
2625
if (!xLayout.hideTitle) {
2626
defaultConfig.items = [getDefaultChartTitle(store)];
2629
defaultConfig.insetPadding = 10;
2632
Ext.apply(defaultConfig, config);
2634
chart = Ext.create('Ext.chart.Chart', defaultConfig);
2636
chart.setChartSize = getDefaultChartSizeHandler();
2637
chart.setTitlePosition = getDefaultChartTitlePositionHandler();
2639
chart.onViewportResize = function() {
2640
chart.setChartSize();
2642
chart.setTitlePosition();
2645
chart.on('afterrender', function() {
2646
chart.setTitlePosition();
2652
generator.column = function(isStacked) {
2653
var store = getDefaultStore(isStacked),
2654
numericAxis = getDefaultNumericAxis(store),
2655
categoryAxis = getDefaultCategoryAxis(store),
2656
axes = [numericAxis, categoryAxis],
2657
series = [getDefaultSeries(store)];
2660
if (xLayout.showTrendLine) {
2661
series = series.concat(getDefaultTrendLines(store, isStacked));
2664
if (xLayout.targetLineValue) {
2665
series.push(getDefaultTargetLine(store));
2668
if (xLayout.baseLineValue) {
2669
series.push(getDefaultBaseLine(store));
2673
setDefaultTheme(store, isStacked);
2675
return getDefaultChart({
2682
generator.stackedcolumn = function() {
2683
var chart = this.column(true);
2685
for (var i = 0, item; i < chart.series.items.length; i++) {
2686
item = chart.series.items[i];
2688
if (item.type === conf.finals.chart.column) {
2689
item.stacked = true;
2696
generator.bar = function(isStacked) {
2697
var store = getDefaultStore(isStacked),
2698
numericAxis = getDefaultNumericAxis(store),
2699
categoryAxis = getDefaultCategoryAxis(store),
2701
series = getDefaultSeries(store),
2708
numericAxis.position = 'bottom';
2709
categoryAxis.position = 'left';
2710
categoryAxis.label.rotate.degrees = 360;
2711
axes = [numericAxis, categoryAxis];
2714
series.type = 'bar';
2715
series.axis = 'bottom';
2718
if (xLayout.showValues) {
2721
'text-anchor': 'middle',
2722
field: store.rangeFields
2728
if (xLayout.showTrendLine) {
2729
trendLines = getDefaultTrendLines(store, isStacked);
2731
for (var i = 0; i < trendLines.length; i++) {
2732
trendLines[i].axis = 'bottom';
2733
trendLines[i].xField = store.trendLineFields[i];
2734
trendLines[i].yField = store.domainFields;
2737
series = series.concat(trendLines);
2740
if (xLayout.targetLineValue) {
2741
targetLine = getDefaultTargetLine(store);
2742
targetLine.axis = 'bottom';
2743
targetLine.xField = store.targetLineFields;
2744
targetLine.yField = store.domainFields;
2746
series.push(targetLine);
2749
if (xLayout.baseLineValue) {
2750
baseLine = getDefaultBaseLine(store);
2751
baseLine.axis = 'bottom';
2752
baseLine.xField = store.baseLineFields;
2753
baseLine.yField = store.domainFields;
2755
series.push(baseLine);
2759
setDefaultTheme(store);
2761
return getDefaultChart({
2768
generator.stackedbar = function() {
2769
var chart = this.bar(true);
2771
for (var i = 0, item; i < chart.series.items.length; i++) {
2772
item = chart.series.items[i];
2774
if (item.type === conf.finals.chart.bar) {
2775
item.stacked = true;
2782
generator.line = function() {
2783
var store = getDefaultStore(),
2784
numericAxis = getDefaultNumericAxis(store),
2785
categoryAxis = getDefaultCategoryAxis(store),
2786
axes = [numericAxis, categoryAxis],
2788
colors = conf.chart.theme.dv1.slice(0, store.rangeFields.length),
2789
seriesTitles = getDefaultSeriesTitle(store);
2792
for (var i = 0, line; i < store.rangeFields.length; i++) {
2796
xField: store.domainFields,
2797
yField: store.rangeFields[i],
2804
radius: ns.dashboard ? 3 : 4
2806
tips: getDefaultTips(),
2807
title: seriesTitles[i]
2810
//if (xLayout.showValues) {
2813
//field: store.rangeFields[i]
2820
// Options, theme colors
2821
if (xLayout.showTrendLine) {
2822
series = getDefaultTrendLines(store).concat(series);
2824
colors = colors.concat(colors);
2827
if (xLayout.targetLineValue) {
2828
series.push(getDefaultTargetLine(store));
2830
colors.push('#051a2e');
2833
if (xLayout.baseLineValue) {
2834
series.push(getDefaultBaseLine(store));
2836
colors.push('#051a2e');
2840
Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, {
2841
constructor: function(config) {
2842
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
2843
seriesThemes: colors,
2849
return getDefaultChart({
2856
generator.area = function() {
2858
// NB, always true for area charts as extjs area charts cannot handle nulls
2859
xLayout.hideEmptyRows = true;
2861
var store = getDefaultStore(true),
2862
numericAxis = getDefaultNumericAxis(store),
2863
categoryAxis = getDefaultCategoryAxis(store),
2864
axes = [numericAxis, categoryAxis],
2865
series = getDefaultSeries(store);
2867
series.type = 'area';
2868
series.style.opacity = 0.7;
2869
series.style.lineWidth = 0;
2870
delete series.label;
2875
if (xLayout.showTrendLine) {
2876
series = series.concat(getDefaultTrendLines(store, true));
2879
if (xLayout.targetLineValue) {
2880
series.push(getDefaultTargetLine(store));
2883
if (xLayout.baseLineValue) {
2884
series.push(getDefaultBaseLine(store));
2888
setDefaultTheme(store);
2890
return getDefaultChart({
2897
generator.pie = function() {
2898
var store = getDefaultStore(),
2903
field: conf.finals.data.domain
2907
if (xLayout.showValues) {
2908
var labelFont = conf.chart.style.fontFamily,
2911
if (Ext.isObject(xLayout.seriesStyle)) {
2912
var style = xLayout.seriesStyle;
2915
labelColor = style.labelColor || labelColor;
2917
if (style.labelFont) {
2918
labelFont = style.labelFont;
2921
labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal ';
2922
labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px ';
2923
labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily;
2927
label.display = 'middle';
2928
label.contrast = !labelColor;
2929
label.font = labelFont;
2930
label.fill = labelColor;
2931
label.renderer = function(value) {
2932
var record = store.getAt(store.findExact(conf.finals.data.domain, value));
2933
return record.data[store.rangeFields[0]];
2940
field: store.rangeFields[0],
2955
cls: 'dv-chart-tips',
2956
renderer: function(item) {
2957
this.update('<div style="text-align:center"><div style="font-size:17px; font-weight:bold">' + item.data[store.rangeFields[0]] + '</div><div style="font-size:10px">' + item.data[conf.finals.data.domain] + '</div></div>');
2960
shadowAttributes: false
2964
colors = conf.chart.theme.dv1.slice(0, xResponse.nameHeaderMap[xLayout.rowDimensionNames[0]].ids.length);
2966
Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, {
2967
constructor: function(config) {
2968
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
2969
seriesThemes: colors,
2976
chart = getDefaultChart({
2981
//chart.legend.position = 'right';
2982
//chart.legend.isVertical = true;
2983
chart.insetPadding = ns.dashboard ? 25 : 40;
2988
generator.radar = function() {
2989
var store = getDefaultStore(),
2992
seriesTitles = getDefaultSeriesTitle(store),
3005
for (var i = 0, obj; i < store.rangeFields.length; i++) {
3009
xField: store.domainFields,
3010
yField: store.rangeFields[i],
3014
tips: getDefaultTips(),
3015
title: seriesTitles[i]
3018
if (xLayout.showValues) {
3021
field: store.rangeFields[i]
3028
chart = getDefaultChart({
3035
chart.insetPadding = ns.dashboard ? 32 : 40;
3037
chart.height = ns.app.centerRegion.getHeight() - 80;
3039
chart.setChartSize = function() {
3040
//this.animate = false;
3041
this.setWidth(ns.app.centerRegion.getWidth());
3042
this.setHeight(ns.app.centerRegion.getHeight() - 80);
3043
//this.animate = true;
3049
generator.gauge = function() {
3050
var valueColor = '#aaa',
3059
columnIds = [columnIds[0]];
3060
failSafeColumnIds = [failSafeColumnIds[0]];
3061
rowIds = [rowIds[0]];
3064
store = getDefaultStore();
3076
// series, legendset
3078
valueColor = service.mapLegend.getColorByValue(legendSet, store.getRange()[0].data[failSafeColumnIds[0]]) || valueColor;
3083
field: store.rangeFields[0],
3085
colorSet: [valueColor, '#ddd']
3088
chart = getDefaultChart({
3091
width: ns.app.centerRegion.getWidth(),
3092
height: ns.app.centerRegion.getHeight() * 0.6,
3094
insetPadding: ns.dashboard ? 50 : 100,
3097
//easing: 'elasticIn',
3103
if (xLayout.showValues) {
3104
chart.items.push(Ext.create('Ext.draw.Sprite', {
3106
text: store.getRange()[0].data[failSafeColumnIds[0]],
3107
font: 'normal 26px ' + conf.chart.style.fontFamily,
3114
chart.setChartSize = function() {
3115
//this.animate = false;
3116
this.setWidth(ns.app.centerRegion.getWidth());
3117
this.setHeight(ns.app.centerRegion.getHeight() * 0.6);
3118
//this.animate = true;
3121
chart.setTitlePosition = function() {
3123
var title = this.items[0],
3124
subTitle = this.items[1],
3125
titleXFallback = 10;
3128
var titleWidth = Ext.isIE ? title.el.dom.scrollWidth : title.el.getWidth(),
3129
titleX = titleWidth ? (ns.app.centerRegion.getWidth() / 2) - (titleWidth / 2) : titleXFallback;
3130
title.setAttributes({
3136
var subTitleWidth = Ext.isIE ? subTitle.el.dom.scrollWidth : subTitle.el.getWidth(),
3137
subTitleX = subTitleWidth ? (ns.app.centerRegion.getWidth() / 2) - (subTitleWidth / 2) : titleXFallback;
3138
subTitle.setAttributes({
3149
return generator[xLayout.type]();
3157
// sort and extend dynamic dimensions
3158
if (Ext.isArray(init.dimensions)) {
3159
support.prototype.array.sort(init.dimensions);
3161
for (var i = 0, dim; i < init.dimensions.length; i++) {
3162
dim = init.dimensions[i];
3163
dim.dimensionName = dim.id;
3164
dim.objectName = conf.finals.dimension.dimension.objectName;
3165
conf.finals.dimension.objectNameMap[dim.id] = dim;
3170
if (init.user && init.user.ouc) {
3171
support.prototype.array.sort(init.user.ouc);
3201
isInitStarted = false,
3202
isInitComplete = false,
3207
getInit = function(config) {
3211
type = config.plugin && config.crossDomain ? 'jsonp' : 'json',
3214
init.contextPath = config.url;
3217
if (++callbacks === requests.length) {
3218
isInitComplete = true;
3220
for (var i = 0; i < configs.length; i++) {
3221
execute(configs[i]);
3230
url: init.contextPath + '/api/me/user-account.' + type,
3231
disableCaching: false,
3232
success: function(r) {
3233
init.userAccount = r.responseText ? Ext.decode(r.responseText) : r;
3236
var defaultKeyUiLocale = 'en',
3237
defaultKeyAnalysisDisplayProperty = 'name',
3242
init.userAccount.settings.keyUiLocale = init.userAccount.settings.keyUiLocale || defaultKeyUiLocale;
3243
init.userAccount.settings.keyAnalysisDisplayProperty = init.userAccount.settings.keyAnalysisDisplayProperty || defaultKeyAnalysisDisplayProperty;
3246
contextPath = init.contextPath;
3247
keyUiLocale = init.userAccount.settings.keyUiLocale;
3248
keyAnalysisDisplayProperty = init.userAccount.settings.keyAnalysisDisplayProperty;
3249
namePropertyUrl = keyAnalysisDisplayProperty === defaultKeyAnalysisDisplayProperty ? keyAnalysisDisplayProperty : keyAnalysisDisplayProperty + '|rename(' + defaultKeyAnalysisDisplayProperty + ')';
3251
init.namePropertyUrl = namePropertyUrl;
3259
url: init.contextPath + '/api/organisationUnits.' + type + '?userOnly=true&fields=id,name,children[id,name]&paging=false',
3260
disableCaching: false,
3261
success: function(r) {
3262
var organisationUnits = (r.responseText ? Ext.decode(r.responseText).organisationUnits : r) || [],
3266
if (organisationUnits.length) {
3267
for (var i = 0, org; i < organisationUnits.length; i++) {
3268
org = organisationUnits[i];
3273
ouc = Ext.Array.clean(ouc.concat(Ext.Array.pluck(org.children, 'id') || []));
3283
alert('User is not assigned to any organisation units');
3291
url: init.contextPath + '/api/dimensions.' + type + '?fields=id,name&paging=false',
3292
disableCaching: false,
3293
success: function(r) {
3294
init.dimensions = r.responseText ? Ext.decode(r.responseText).dimensions : r.dimensions;
3299
for (var i = 0; i < requests.length; i++) {
3300
if (type === 'jsonp') {
3301
Ext.data.JsonP.request(requests[i]);
3304
Ext.Ajax.request(requests[i]);
3309
applyCss = function() {
3312
var css = '.dv-chart-tips { border-radius: 2px; padding: 0px 3px 1px; border: 2px solid #000; background-color: #000; } \n';
3313
css += '.dv-chart-tips .x-tip-body { background-color: #000; font-size: 13px; font-weight: normal; color: #fff; -webkit-text-stroke: 0; } \n';
3314
css += '.dv-chart-tips .x-tip-body div { font-family: arial,sans-serif,ubuntu,consolas !important; } \n';
3317
css += '.x-mask-msg { padding: 0; border: 0 none; background-image: none; background-color: transparent; } \n';
3318
css += '.x-mask-msg div { background-position: 11px center; } \n';
3319
css += '.x-mask-msg .x-mask-loading { border: 0 none; \n background-color: #000; color: #fff; border-radius: 2px; padding: 12px 14px 12px 30px; opacity: 0.65; } \n';
3320
css += '.x-mask { opacity: 0; } \n';
3322
Ext.util.CSS.createStyleSheet(css);
3325
execute = function(config) {
3335
validateConfig = function(config) {
3336
if (!Ext.isObject(config)) {
3337
console.log('Chart configuration is not an object');
3341
if (!Ext.isString(config.el)) {
3342
console.log('No element id provided');
3346
config.id = config.id || config.uid;
3351
extendInstance = function(ns) {
3352
var init = ns.core.init,
3354
conf = ns.core.conf,
3355
support = ns.core.support,
3356
service = ns.core.service,
3358
type = ns.plugin && ns.crossDomain ? 'jsonp' : 'json',
3360
json: 'application/json',
3361
jsonp: 'application/javascript'
3364
'Content-Type': headerMap[type],
3365
'Accepts': headerMap[type]
3368
ns.plugin = init.plugin;
3369
ns.dashboard = init.dashboard;
3370
ns.crossDomain = init.crossDomain;
3371
ns.skipMask = init.skipMask;
3372
ns.skipFade = init.skipFade;
3374
init.el = config.el;
3376
if (!ns.skipFade && init.el && Ext.get(init.el)) {
3377
Ext.get(init.el).setStyle('opacity', 0);
3380
web.chart = web.chart || {};
3382
web.chart.loadChart = function(obj) {
3387
if (!(obj && obj.id)) {
3388
console.log('Error, no chart id');
3392
success = function(r) {
3393
var layout = api.layout.Layout((r.responseText ? Ext.decode(r.responseText) : r), obj);
3396
web.chart.getData(layout, true);
3400
failure = function(r) {
3401
console.log(obj.id, (r.responseText ? Ext.decode(r.responseText) : r));
3404
config.url = init.contextPath + '/api/charts/' + obj.id + '.' + type + '?fields=' + conf.url.analysisFields.join(',');
3405
config.disableCaching = false;
3406
config.headers = headers;
3407
config.success = success;
3408
config.failure = failure;
3410
if (type === 'jsonp') {
3411
Ext.data.JsonP.request(config);
3414
Ext.Ajax.request(config);
3418
web.chart.getData = function(layout, isUpdateGui) {
3429
xLayout = service.layout.getExtendedLayout(layout);
3430
paramString = web.analytics.getParamString(xLayout, true);
3434
web.mask.show(ns.app.centerRegion);
3437
success = function(r) {
3438
var response = api.response.Response((r.responseText ? Ext.decode(r.responseText) : r));
3441
web.mask.hide(ns.app.centerRegion);
3445
// sync xLayout with response
3446
xLayout = service.layout.getSyncronizedXLayout(xLayout, response);
3449
web.mask.hide(ns.app.centerRegion);
3453
ns.app.paramString = paramString;
3455
web.chart.getChart(layout, xLayout, response, isUpdateGui);
3458
failure = function(r) {
3460
web.mask.hide(ns.app.centerRegion);
3464
config.url = init.contextPath + '/api/analytics.' + type + paramString;
3465
config.disableCaching = false;
3466
config.timeout = 60000;
3467
config.headers = headers;
3468
config.success = success;
3469
config.failure = failure;
3471
if (type === 'jsonp') {
3472
Ext.data.JsonP.request(config);
3475
Ext.Ajax.request(config);
3479
web.chart.getChart = function(layout, xLayout, response, isUpdateGui) {
3486
xLayout = service.layout.getExtendedLayout(layout);
3490
xResponse = service.response.getExtendedResponse(xLayout, response);
3493
ns.app.layout = layout;
3494
ns.app.xLayout = xLayout;
3495
ns.app.response = response;
3496
ns.app.xResponse = xResponse;
3499
console.log('layout', ns.app.layout);
3500
console.log('xLayout', ns.app.xLayout);
3501
console.log('response', ns.app.response);
3502
console.log('xResponse', ns.app.xResponse);
3506
ns.app.chart = ns.core.web.chart.createChart(ns);
3509
if (!ns.skipFade && ns.core.init.el && Ext.get(ns.core.init.el)) {
3510
ns.app.chart.on('afterrender', function() {
3511
Ext.defer( function() {
3512
Ext.get(ns.core.init.el).fadeIn({
3520
ns.app.centerRegion.removeAll();
3521
ns.app.centerRegion.add(ns.app.chart);
3524
web.mask.hide(ns.app.centerRegion);
3529
createViewport = function() {
3530
var el = Ext.get(ns.core.init.el),
3536
if (!ns.skipFade && el && Ext.get(el)) {
3537
var elBorderW = parseInt(el.getStyle('border-left-width')) + parseInt(el.getStyle('border-right-width')),
3538
elBorderH = parseInt(el.getStyle('border-top-width')) + parseInt(el.getStyle('border-bottom-width')),
3539
elPaddingW = parseInt(el.getStyle('padding-left')) + parseInt(el.getStyle('padding-right')),
3540
elPaddingH = parseInt(el.getStyle('padding-top')) + parseInt(el.getStyle('padding-bottom'));
3542
width = el.getWidth() - elBorderW - elPaddingW,
3543
height = el.getHeight() - elBorderH - elPaddingH;
3546
centerRegion = Ext.create('Ext.panel.Panel', {
3548
bodyStyle: 'border: 0 none',
3549
width: config.width || width || '100%',
3550
height: config.height || height || '50%',
3555
centerRegion: centerRegion
3559
initialize = function() {
3560
if (!validateConfig(config)) {
3567
init.dashboard = Ext.isBoolean(config.dashboard) ? config.dashboard : false;
3568
init.crossDomain = Ext.isBoolean(config.crossDomain) ? config.crossDomain : true;
3569
init.skipMask = Ext.isBoolean(config.skipMask) ? config.skipMask : false;
3570
init.skipFade = Ext.isBoolean(config.skipFade) ? config.skipFade : false;
3572
ns.core = DV.getCore(Ext.clone(init));
3575
ns.app.viewport = createViewport();
3576
ns.app.centerRegion = ns.app.viewport.centerRegion;
3578
if (config && config.id) {
3579
ns.core.web.chart.loadChart(config);
3582
layout = ns.core.api.layout.Layout(config);
3588
ns.core.web.chart.getData(layout);
3593
DV.plugin.getChart = function(config) {
3594
if (Ext.isString(config.url) && config.url.split('').pop() === '/') {
3595
config.url = config.url.substr(0, config.url.length - 1);
3598
if (isInitComplete) {
3602
configs.push(config);
3604
if (!isInitStarted) {
3605
isInitStarted = true;
3611
DHIS = Ext.isObject(window['DHIS']) ? DHIS : {};
3612
DHIS.getChart = DV.plugin.getChart;