dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #33376
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17026: DV EV sorting, trend lines, style fixes.
Merge authors:
Jan Henrik Øverland (janhenrik-overland)
------------------------------------------------------------
revno: 17026 [merge]
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2014-10-09 20:15:23 +0200
message:
DV EV sorting, trend lines, style fixes.
modified:
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js 2014-10-09 07:58:13 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js 2014-10-09 18:13:21 +0000
@@ -202,7 +202,7 @@
fontFamily: 'Arial,Sans-serif,Lucida Grande,Ubuntu'
},
theme: {
- dv1: ['#94ae0a', '#0b3b68', '#a61120', '#ff8809', '#7c7474', '#a61187', '#ffd13e', '#24ad9a', '#a66111', '#414141', '#4500c4', '#1d5700']
+ dv1: ['#94ae0a', '#1d5991', '#a61120', '#ff8809', '#7c7474', '#a61187', '#ffd13e', '#24ad9a', '#a66111', '#414141', '#4500c4', '#1d5700']
}
};
@@ -1733,7 +1733,6 @@
delete layout.parentOrganisationUnit;
delete layout.regression;
delete layout.cumulative;
- delete layout.sortOrder;
delete layout.topLimit;
return layout;
@@ -2062,9 +2061,12 @@
};
web.report.aggregate.createChart = function(layout, xLayout, xResponse, centerRegion) {
- var columnIds = xLayout.columns[0] ? xLayout.columns[0].ids : [],
+ var dataTotalKey = Ext.data.IdGenerator.get('uuid').generate(),
+ //columnIds = xLayout.columns[0] ? xLayout.columns[0].ids : [],
+ columnIds = xLayout.columnDimensionNames[0] ? xLayout.dimensionNameIdsMap[xLayout.columnDimensionNames[0]] : [],
replacedColumnIds = support.prototype.str.replaceAll(Ext.clone(columnIds), '.', ''),
- rowIds = xLayout.rows[0] ? xLayout.rows[0].ids : [],
+ //rowIds = xLayout.rows[0] ? xLayout.rows[0].ids : [],
+ rowIds = xLayout.rowDimensionNames[0] ? xLayout.dimensionNameIdsMap[xLayout.rowDimensionNames[0]] : [],
replacedRowIds = support.prototype.str.replaceAll(Ext.clone(rowIds), '.', ''),
filterIds = function() {
var ids = [];
@@ -2092,28 +2094,16 @@
return map;
}(),
- sortStoreBySum = function(store, ids, sortOrder) {
- var key = Ext.data.IdGenerator.get('uuid').generate(),
- total;
-
- // add totals
- store.each( function(record) {
+ addDataTotals = function(data, ids) {
+ for (var i = 0, obj, total; i < data.length; i++) {
+ obj = data[i];
total = 0;
- for (var i = 0; i < ids.length; i++) {
- total += parseFloat(record.data[ids[i]]);
-
- record.set(key, total);
+ for (var j = 0; j < ids.length; j++) {
+ total += parseFloat(obj[ids[j]]);
+ obj[dataTotalKey] = total;
}
- });
-
- // sort
- store.sort(key, sortOrder === -1 ? 'ASC' : 'DESC');
-
- // remove totals
- store.each( function(record) {
- delete record.data[key];
- });
+ }
},
getSyncronizedXLayout,
@@ -2138,7 +2128,7 @@
generator = {};
- getDefaultStore = function() {
+ getDefaultStore = function(isStacked) {
var pe = conf.finals.dimension.period.dimensionName,
columnDimensionName = xLayout.columns[0].dimensionName,
rowDimensionName = xLayout.rows[0].dimensionName,
@@ -2156,15 +2146,15 @@
rowValues = [];
isEmpty = false;
+
obj[conf.finals.data.domain] = xResponse.metaData.names[category];
- for (var j = 0, colId, id, value; j < columnIds.length; j++) {
- id = columnIds[j] + rowIds[i];
+ for (var j = 0, id, value; j < columnIds.length; j++) {
+ id = support.prototype.str.replaceAll(columnIds[j], '#', '') + support.prototype.str.replaceAll(rowIds[i], '#', '');
value = xResponse.idValueMap[id];
rowValues.push(value);
- dataColId = replacedColumnIds[j];
- obj[dataColId] = value ? parseFloat(value) : '0.0';
+ obj[columnIds[j]] = value ? parseFloat(value) : '0.0';
}
isEmpty = !(Ext.Array.clean(rowValues).length);
@@ -2174,26 +2164,59 @@
}
}
+ // stacked
+ if (isStacked) {
+ addDataTotals(data, columnIds);
+ }
+
+ // sort order
+ if (xLayout.sortOrder) {
+ var sortingKey = isStacked ? dataTotalKey : columnIds[0];
+
+ support.prototype.array.sort(data, xLayout.sortOrder === -1 ? 'ASC' : 'DESC', sortingKey);
+ }
+
// trend lines
if (xLayout.showTrendLine) {
- for (var i = 0, regression, key; i < replacedColumnIds.length; i++) {
+ var regression,
+ regressionKey;
+
+ if (isStacked) {
regression = new SimpleRegression();
- key = conf.finals.data.trendLine + replacedColumnIds[i];
-
- for (var j = 0, value; j < data.length; j++) {
- value = data[j][replacedColumnIds[i]];
- regression.addData(j, parseFloat(value));
- }
-
- for (var j = 0; j < data.length; j++) {
- data[j][key] = parseFloat(regression.predict(j).toFixed(1));
- }
-
- trendLineFields.push(key);
- xResponse.metaData.names[key] = EV.i18n.trend + ' (' + xResponse.metaData.names[columnIds[i]] + ')';
+ regressionKey = conf.finals.data.trendLine + dataTotalKey;
+
+ for (var i = 0, value; i < data.length; i++) {
+ value = data[i][dataTotalKey];
+ regression.addData(i, parseFloat(value));
+ }
+
+ for (var i = 0; i < data.length; i++) {
+ data[i][regressionKey] = parseFloat(regression.predict(i).toFixed(1));
+ }
+
+ trendLineFields.push(regressionKey);
+ xResponse.metaData.names[regressionKey] = NS.i18n.trend + ' (Total)';
+ }
+ else {
+ for (var i = 0; i < columnIds.length; i++) {
+ regression = new SimpleRegression();
+ regressionKey = conf.finals.data.trendLine + columnIds[i];
+
+ for (var j = 0, value; j < data.length; j++) {
+ value = data[j][replacedColumnIds[i]];
+ regression.addData(j, parseFloat(value));
+ }
+
+ for (var j = 0; j < data.length; j++) {
+ data[j][regressionKey] = parseFloat(regression.predict(j).toFixed(1));
+ }
+
+ trendLineFields.push(regressionKey);
+ xResponse.metaData.names[regressionKey] = NS.i18n.trend + ' (' + xResponse.metaData.names[columnIds[i]] + ')';
+ }
}
}
-
+
// target line
if (Ext.isNumber(xLayout.targetLineValue) || Ext.isNumber(parseFloat(xLayout.targetLineValue))) {
for (var i = 0; i < data.length; i++) {
@@ -2214,7 +2237,7 @@
store = Ext.create('Ext.data.Store', {
fields: function() {
- var fields = Ext.clone(replacedColumnIds);
+ var fields = Ext.clone(columnIds);
fields.push(conf.finals.data.domain);
fields = fields.concat(trendLineFields, targetLineFields, baseLineFields);
@@ -2223,12 +2246,7 @@
data: data
});
- // sort order
- if (xLayout.sortOrder) {
- store.sort(replacedColumnIds[0], xLayout.sortOrder === -1 ? 'ASC' : 'DESC');
- }
-
- store.rangeFields = replacedColumnIds;
+ store.rangeFields = columnIds;
store.domainFields = [conf.finals.data.domain];
store.trendLineFields = trendLineFields;
store.targetLineFields = targetLineFields;
@@ -2249,7 +2267,7 @@
var minimums = [];
for (var i = 0; i < store.numericFields.length; i++) {
- minimums.push(store.max(store.numericFields[i]));
+ minimums.push(store.min(store.numericFields[i]));
}
return Ext.Array.min(minimums);
@@ -2356,6 +2374,9 @@
label: {
renderer: Ext.util.Format.numberRenderer(renderer)
},
+ labelTitle: {
+ font: 'bold 13px ' + conf.chart.style.fontFamily
+ },
grid: {
odd: {
opacity: 1,
@@ -2404,13 +2425,19 @@
fields: store.domainFields,
label: {
rotate: {
- degrees: 330
+ degrees: 320
+ },
+ style: {
+ fontSize: '11px'
}
}
};
if (xLayout.domainAxisTitle) {
axis.title = xLayout.domainAxisTitle;
+ axis.labelTitle = {
+ font: 'bold 13px ' + conf.chart.style.fontFamily
+ };
}
return axis;
@@ -2419,13 +2446,28 @@
getDefaultSeriesTitle = function(store) {
var a = [];
- for (var i = 0, id, ids; i < store.rangeFields.length; i++) {
- id = replacedIdMap[store.rangeFields[i]];
- a.push(xResponse.metaData.names[id]);
+ if (Ext.isObject(xLayout.legend) && Ext.isArray(xLayout.legend.seriesNames)) {
+ return xLayout.legend.seriesNames;
+ }
+ else {
+ for (var i = 0, id, name, mxl, ids; i < store.rangeFields.length; i++) {
+ id = store.rangeFields[i];
+ name = xResponse.metaData.names[id];
+
+ if (Ext.isObject(xLayout.legend) && xLayout.legend.maxLength) {
+ var mxl = parseInt(xLayout.legend.maxLength);
+
+ if (Ext.isNumber(mxl)) {
+ name = name.substr(0, mxl) + '..';
+ }
+ }
+
+ a.push(name);
+ }
}
return a;
- };
+ };
getDefaultSeries = function(store) {
var main = {
@@ -2460,10 +2502,12 @@
return main;
};
- getDefaultTrendLines = function(store) {
+ getDefaultTrendLines = function(store, isStacked) {
var a = [];
- for (var i = 0; i < store.trendLineFields.length; i++) {
+ for (var i = 0, strokeColor; i < store.trendLineFields.length; i++) {
+ strokeColor = isStacked ? '#000' : conf.chart.theme.dv1[i];
+
a.push({
type: 'line',
axis: 'left',
@@ -2471,12 +2515,14 @@
yField: store.trendLineFields[i],
style: {
opacity: 0.8,
- lineWidth: 3,
- 'stroke-dasharray': 8
+ lineWidth: 2,
+ 'stroke-dasharray': 14,
+ stroke: strokeColor
},
markerConfig: {
type: 'circle',
- radius: 0
+ radius: 0,
+ fill: strokeColor
},
title: xResponse.metaData.names[store.trendLineFields[i]]
});
@@ -2493,9 +2539,9 @@
yField: store.targetLineFields,
style: {
opacity: 1,
- lineWidth: 2,
+ lineWidth: 1,
'stroke-width': 1,
- stroke: '#041423'
+ stroke: '#000'
},
showMarkers: false,
title: (Ext.isString(xLayout.targetLineTitle) ? xLayout.targetLineTitle : NS.i18n.target) + ' (' + xLayout.targetLineValue + ')'
@@ -2510,9 +2556,9 @@
yField: store.baseLineFields,
style: {
opacity: 1,
- lineWidth: 2,
+ lineWidth: 1,
'stroke-width': 1,
- stroke: '#041423'
+ stroke: '#000'
},
showMarkers: false,
title: (Ext.isString(xLayout.baseLineTitle) ? xLayout.baseLineTitle : NS.i18n.base) + ' (' + xLayout.baseLineValue + ')'
@@ -2524,8 +2570,10 @@
trackMouse: true,
cls: 'dv-chart-tips',
renderer: function(si, item) {
- var value = item.value[1] === '0.0' ? '-' : item.value[1];
- 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>');
+ if (item.value) {
+ var value = item.value[1] === '0.0' ? '-' : item.value[1];
+ 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>');
+ }
}
};
};
@@ -2533,18 +2581,6 @@
setDefaultTheme = function(store) {
var colors = conf.chart.theme.dv1.slice(0, store.rangeFields.length);
- if (xLayout.targetLineValue || xLayout.baseLineValue) {
- colors.push('#051a2e');
- }
-
- if (xLayout.targetLineValue) {
- colors.push('#051a2e');
- }
-
- if (xLayout.baseLineValue) {
- colors.push('#051a2e');
- }
-
Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, {
constructor: function(config) {
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
@@ -2564,7 +2600,9 @@
width,
isVertical = false,
position = 'top',
- padding = 0;
+ fontSize = 12,
+ padding = 0,
+ positions = ['top', 'right', 'bottom', 'left'];
if (xLayout.type === conf.finals.chart.pie) {
numberOfItems = store.getCount();
@@ -2601,10 +2639,20 @@
padding = 5;
}
+ // legend
+ if (xLayout.legend) {
+ if (Ext.Array.contains(positions, xLayout.legend.position)) {
+ position = xLayout.legend.position;
+ }
+
+ fontSize = parseInt(xLayout.legend.fontSize) || fontSize;
+ fontSize = fontSize + 'px';
+ }
+
return Ext.create('Ext.chart.Legend', {
position: position,
isVertical: isVertical,
- labelFont: '13px ' + conf.chart.style.fontFamily,
+ labelFont: fontSize + ' ' + conf.chart.style.fontFamily,
boxStroke: '#ffffff',
boxStrokeWidth: 0,
padding: padding
@@ -2719,38 +2767,6 @@
height: 20,
y: 20
});
-
-
- //var ids = filterIds,
- //a = [],
- //text = '',
- //fontSize;
-
- //if (xLayout.type === conf.finals.chart.pie) {
- //ids = ids.concat(columnIds);
- //}
-
- //if (Ext.isArray(ids) && ids.length) {
- //for (var i = 0; i < ids.length; i++) {
- //text += xResponse.metaData.names[ids[i]];
- //text += i < ids.length - 1 ? ', ' : '';
- //}
- //}
-
- //if (xLayout.title) {
- //text = xLayout.title;
- //}
-
- //fontSize = (centerRegion.getWidth() / text.length) < 11.6 ? 13 : 18;
-
- //return Ext.create('Ext.draw.Sprite', {
- //type: 'text',
- //text: text,
- //font: 'bold ' + fontSize + 'px ' + conf.chart.style.fontFamily,
- //fill: '#111',
- //height: 20,
- //y: 20
- //});
};
getDefaultChartSizeHandler = function() {
@@ -2786,39 +2802,38 @@
};
};
- getDefaultChart = function(store, axes, series, theme) {
+ getDefaultChart = function(config) {
var chart,
- config = {
- //renderTo: init.el,
- store: store,
- axes: axes,
- series: series,
+ store = config.store || {},
+ defaultConfig = {
animate: true,
shadow: false,
insetPadding: 35,
width: centerRegion.getWidth() - 15,
height: centerRegion.getHeight() - 40,
- theme: theme || 'dv1'
+ theme: 'dv1'
};
- // Legend
+ // legend
if (!xLayout.hideLegend) {
- config.legend = getDefaultLegend(store);
+ defaultConfig.legend = getDefaultLegend(store);
- if (config.legend.position === 'right') {
- config.insetPadding = 40;
+ if (defaultConfig.legend.position === 'right') {
+ defaultConfig.insetPadding = 40;
}
}
- // Title
+ // title
if (!xLayout.hideTitle) {
- config.items = [getDefaultChartTitle(store)];
+ defaultConfig.items = [getDefaultChartTitle(store)];
}
else {
- config.insetPadding = 10;
+ defaultConfig.insetPadding = 10;
}
- chart = Ext.create('Ext.chart.Chart', config);
+ Ext.apply(defaultConfig, config);
+
+ chart = Ext.create('Ext.chart.Chart', defaultConfig);
chart.setChartSize = getDefaultChartSizeHandler();
chart.setTitlePosition = getDefaultChartTitlePositionHandler();
@@ -2836,16 +2851,16 @@
return chart;
};
- generator.column = function() {
- var store = getDefaultStore(),
+ generator.column = function(isStacked) {
+ var store = getDefaultStore(isStacked),
numericAxis = getDefaultNumericAxis(store),
categoryAxis = getDefaultCategoryAxis(store),
axes = [numericAxis, categoryAxis],
series = [getDefaultSeries(store)];
- // Options
+ // options
if (xLayout.showTrendLine) {
- series = getDefaultTrendLines(store).concat(series);
+ series = series.concat(getDefaultTrendLines(store, isStacked));
}
if (xLayout.targetLineValue) {
@@ -2856,19 +2871,18 @@
series.push(getDefaultBaseLine(store));
}
- // Theme
- setDefaultTheme(store);
+ // theme
+ setDefaultTheme(store, isStacked);
- return getDefaultChart(store, axes, series);
+ return getDefaultChart({
+ store: store,
+ axes: axes,
+ series: series
+ });
};
generator.stackedcolumn = function() {
- var chart = this.column();
-
- // sort order
- if (xLayout.sortOrder) {
- sortStoreBySum(chart.store, replacedColumnIds, xLayout.sortOrder);
- }
+ var chart = this.column(true);
for (var i = 0, item; i < chart.series.items.length; i++) {
item = chart.series.items[i];
@@ -2881,8 +2895,8 @@
return chart;
};
- generator.bar = function() {
- var store = getDefaultStore(),
+ generator.bar = function(isStacked) {
+ var store = getDefaultStore(isStacked),
numericAxis = getDefaultNumericAxis(store),
categoryAxis = getDefaultCategoryAxis(store),
axes,
@@ -2914,7 +2928,7 @@
series = [series];
if (xLayout.showTrendLine) {
- trendLines = getDefaultTrendLines(store);
+ trendLines = getDefaultTrendLines(store, isStacked);
for (var i = 0; i < trendLines.length; i++) {
trendLines[i].axis = 'bottom';
@@ -2922,7 +2936,7 @@
trendLines[i].yField = store.domainFields;
}
- series = trendLines.concat(series);
+ series = series.concat(trendLines);
}
if (xLayout.targetLineValue) {
@@ -2946,16 +2960,15 @@
// Theme
setDefaultTheme(store);
- return getDefaultChart(store, axes, series);
+ return getDefaultChart({
+ store: store,
+ axes: axes,
+ series: series
+ });
};
generator.stackedbar = function() {
- var chart = this.bar();
-
- // sort order
- if (xLayout.sortOrder) {
- sortStoreBySum(chart.store, replacedColumnIds, xLayout.sortOrder);
- }
+ var chart = this.bar(true);
for (var i = 0, item; i < chart.series.items.length; i++) {
item = chart.series.items[i];
@@ -3035,21 +3048,24 @@
}
});
- return getDefaultChart(store, axes, series);
+ return getDefaultChart({
+ store: store,
+ axes: axes,
+ series: series
+ });
};
generator.area = function() {
- var store = getDefaultStore(),
+
+ // NB, always true for area charts as extjs area charts cannot handle nulls
+ xLayout.hideEmptyRows = true;
+
+ var store = getDefaultStore(true),
numericAxis = getDefaultNumericAxis(store),
categoryAxis = getDefaultCategoryAxis(store),
axes = [numericAxis, categoryAxis],
series = getDefaultSeries(store);
-
- // sort order
- if (xLayout.sortOrder) {
- sortStoreBySum(store, replacedColumnIds, xLayout.sortOrder);
- }
-
+
series.type = 'area';
series.style.opacity = 0.7;
series.style.lineWidth = 0;
@@ -3059,7 +3075,7 @@
// Options
if (xLayout.showTrendLine) {
- series = getDefaultTrendLines(store).concat(series);
+ series = series.concat(getDefaultTrendLines(store, true));
}
if (xLayout.targetLineValue) {
@@ -3073,7 +3089,11 @@
// Theme
setDefaultTheme(store);
- return getDefaultChart(store, axes, series);
+ return getDefaultChart({
+ store: store,
+ axes: axes,
+ series: series
+ });
};
generator.pie = function() {
@@ -3134,7 +3154,11 @@
});
// Chart
- chart = getDefaultChart(store, null, series);
+ chart = getDefaultChart({
+ store: store,
+ series: series
+ });
+
//chart.legend.position = 'right';
//chart.legend.isVertical = true;
chart.insetPadding = 40;
@@ -3150,7 +3174,7 @@
seriesTitles = getDefaultSeriesTitle(store),
chart;
- // Axes
+ // axes
axes.push({
type: 'Radial',
position: 'radial',
@@ -3159,7 +3183,7 @@
}
});
- // Series
+ // series
for (var i = 0, obj; i < store.rangeFields.length; i++) {
obj = {
showInLegend: true,
@@ -3182,8 +3206,13 @@
series.push(obj);
}
-
- chart = getDefaultChart(store, axes, series, 'Category2');
+
+ chart = getDefaultChart({
+ store: store,
+ axes: axes,
+ series: series,
+ theme: 'Category2'
+ });
chart.insetPadding = 40;
chart.height = centerRegion.getHeight() - 80;
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js 2014-10-08 22:32:23 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js 2014-10-09 18:13:21 +0000
@@ -12,7 +12,7 @@
// namespace
DV = {};
- var NS = DV;
+ NS = DV;
NS.instances = [];
NS.i18n = {};
@@ -46,19 +46,19 @@
dimension: {
data: {
value: 'data',
- name: DV.i18n.data,
+ name: NS.i18n.data,
dimensionName: 'dx',
objectName: 'dx'
},
indicator: {
value: 'indicator',
- name: DV.i18n.indicator,
+ name: NS.i18n.indicator,
dimensionName: 'dx',
objectName: 'in'
},
dataElement: {
value: 'dataelement',
- name: DV.i18n.data_element,
+ name: NS.i18n.data_element,
dimensionName: 'dx',
objectName: 'de'
},
@@ -70,18 +70,18 @@
},
dataSet: {
value: 'dataset',
- name: DV.i18n.dataset,
+ name: NS.i18n.dataset,
dimensionName: 'dx',
objectName: 'ds'
},
category: {
- name: DV.i18n.assigned_categories,
+ name: NS.i18n.assigned_categories,
dimensionName: 'co',
objectName: 'co',
},
period: {
value: 'period',
- name: DV.i18n.period,
+ name: NS.i18n.period,
dimensionName: 'pe',
objectName: 'pe',
},
@@ -93,7 +93,7 @@
},
organisationUnit: {
value: 'organisationUnits',
- name: DV.i18n.organisation_units,
+ name: NS.i18n.organisation_units,
dimensionName: 'ou',
objectName: 'ou',
},
@@ -215,7 +215,7 @@
fontFamily: 'Arial,Sans-serif,Lucida Grande,Ubuntu'
},
theme: {
- dv1: ['#94ae0a', '#0b3b68', '#a61120', '#ff8809', '#7c7474', '#a61187', '#ffd13e', '#24ad9a', '#a66111', '#414141', '#4500c4', '#1d5700']
+ dv1: ['#94ae0a', '#1d5991', '#a61120', '#ff8809', '#7c7474', '#a61187', '#ffd13e', '#24ad9a', '#a66111', '#414141', '#4500c4', '#1d5700']
}
};
@@ -688,7 +688,7 @@
}
if (!(Ext.isArray(config.rows) && config.rows.length > 0)) {
- if (!DV.plugin) {
+ if (!NS.plugin) {
alert('No values found');
}
return;
@@ -1380,9 +1380,9 @@
delete layout.rangeAxisDecimals;
}
- if (!layout.sorting) {
- delete layout.sorting;
- }
+ if (!layout.sorting) {
+ delete layout.sorting;
+ }
if (!layout.legend) {
delete layout.legend;
@@ -1400,7 +1400,6 @@
delete layout.parentOrganisationUnit;
delete layout.regression;
delete layout.cumulative;
- delete layout.sortOrder;
delete layout.topLimit;
return layout;
@@ -1775,7 +1774,8 @@
web.chart = {};
web.chart.createChart = function(ns) {
- var xLayout = ns.app.xLayout,
+ var dataTotalKey = Ext.data.IdGenerator.get('uuid').generate(),
+ xLayout = ns.app.xLayout,
xResponse = ns.app.xResponse,
//columnIds = xLayout.columns[0] ? xLayout.columns[0].ids : [],
columnIds = xLayout.columnDimensionNames[0] ? xLayout.dimensionNameIdsMap[xLayout.columnDimensionNames[0]] : [],
@@ -1809,28 +1809,16 @@
return map;
}(),
- sortStoreBySum = function(store, ids, sortOrder) {
- var key = Ext.data.IdGenerator.get('uuid').generate(),
- total;
-
- // add totals
- store.each( function(record) {
+ addDataTotals = function(data, ids) {
+ for (var i = 0, obj, total; i < data.length; i++) {
+ obj = data[i];
total = 0;
- for (var i = 0; i < ids.length; i++) {
- total += parseFloat(record.data[ids[i]]);
-
- record.set(key, total);
+ for (var j = 0; j < ids.length; j++) {
+ total += parseFloat(obj[ids[j]]);
+ obj[dataTotalKey] = total;
}
- });
-
- // sort
- store.sort(key, sortOrder === -1 ? 'ASC' : 'DESC');
-
- // remove totals
- store.each( function(record) {
- delete record.data[key];
- });
+ }
},
getSyncronizedXLayout,
@@ -1855,14 +1843,12 @@
generator = {};
- getDefaultStore = function() {
+ getDefaultStore = function(isStacked) {
var pe = conf.finals.dimension.period.dimensionName,
columnDimensionName = xLayout.columns[0].dimensionName,
rowDimensionName = xLayout.rows[0].dimensionName,
data = [],
- //columnIds = xLayout.columnIds,
- //rowIds = xLayout.rowIds,
trendLineFields = [],
targetLineFields = [],
baseLineFields = [],
@@ -1893,26 +1879,59 @@
}
}
+ // stacked
+ if (isStacked) {
+ addDataTotals(data, columnIds);
+ }
+
+ // sort order
+ if (xLayout.sortOrder) {
+ var sortingKey = isStacked ? dataTotalKey : columnIds[0];
+
+ support.prototype.array.sort(data, xLayout.sortOrder === -1 ? 'ASC' : 'DESC', sortingKey);
+ }
+
// trend lines
if (xLayout.showTrendLine) {
- for (var i = 0, regression, key; i < columnIds.length; i++) {
+ var regression,
+ regressionKey;
+
+ if (isStacked) {
regression = new SimpleRegression();
- key = conf.finals.data.trendLine + columnIds[i];
-
- for (var j = 0, value; j < data.length; j++) {
- value = data[j][replacedColumnIds[i]];
- regression.addData(j, parseFloat(value));
- }
-
- for (var j = 0; j < data.length; j++) {
- data[j][key] = parseFloat(regression.predict(j).toFixed(1));
- }
-
- trendLineFields.push(key);
- xResponse.metaData.names[key] = DV.i18n.trend + ' (' + xResponse.metaData.names[columnIds[i]] + ')';
+ regressionKey = conf.finals.data.trendLine + dataTotalKey;
+
+ for (var i = 0, value; i < data.length; i++) {
+ value = data[i][dataTotalKey];
+ regression.addData(i, parseFloat(value));
+ }
+
+ for (var i = 0; i < data.length; i++) {
+ data[i][regressionKey] = parseFloat(regression.predict(i).toFixed(1));
+ }
+
+ trendLineFields.push(regressionKey);
+ xResponse.metaData.names[regressionKey] = NS.i18n.trend + ' (Total)';
+ }
+ else {
+ for (var i = 0; i < columnIds.length; i++) {
+ regression = new SimpleRegression();
+ regressionKey = conf.finals.data.trendLine + columnIds[i];
+
+ for (var j = 0, value; j < data.length; j++) {
+ value = data[j][replacedColumnIds[i]];
+ regression.addData(j, parseFloat(value));
+ }
+
+ for (var j = 0; j < data.length; j++) {
+ data[j][regressionKey] = parseFloat(regression.predict(j).toFixed(1));
+ }
+
+ trendLineFields.push(regressionKey);
+ xResponse.metaData.names[regressionKey] = NS.i18n.trend + ' (' + xResponse.metaData.names[columnIds[i]] + ')';
+ }
}
}
-
+
// target line
if (Ext.isNumber(xLayout.targetLineValue) || Ext.isNumber(parseFloat(xLayout.targetLineValue))) {
for (var i = 0; i < data.length; i++) {
@@ -1942,11 +1961,6 @@
data: data
});
- // sort order
- if (xLayout.sortOrder) {
- store.sort(replacedColumnIds[0], xLayout.sortOrder === -1 ? 'ASC' : 'DESC');
- }
-
store.rangeFields = columnIds;
store.domainFields = [conf.finals.data.domain];
store.trendLineFields = trendLineFields;
@@ -2026,7 +2040,7 @@
return Ext.Array.max(values);
};
- if (DV.isDebug) {
+ if (NS.isDebug) {
console.log("data", data);
console.log("rangeFields", store.rangeFields);
console.log("domainFields", store.domainFields);
@@ -2075,6 +2089,9 @@
label: {
renderer: Ext.util.Format.numberRenderer(renderer)
},
+ labelTitle: {
+ font: 'bold 13px ' + conf.chart.style.fontFamily
+ },
grid: {
odd: {
opacity: 1,
@@ -2123,13 +2140,19 @@
fields: store.domainFields,
label: {
rotate: {
- degrees: 330
+ degrees: 320
+ },
+ style: {
+ fontSize: '11px'
}
}
};
if (xLayout.domainAxisTitle) {
axis.title = xLayout.domainAxisTitle;
+ axis.labelTitle = {
+ font: 'bold 13px ' + conf.chart.style.fontFamily
+ };
}
return axis;
@@ -2194,10 +2217,12 @@
return main;
};
- getDefaultTrendLines = function(store) {
+ getDefaultTrendLines = function(store, isStacked) {
var a = [];
- for (var i = 0; i < store.trendLineFields.length; i++) {
+ for (var i = 0, strokeColor; i < store.trendLineFields.length; i++) {
+ strokeColor = isStacked ? '#000' : conf.chart.theme.dv1[i];
+
a.push({
type: 'line',
axis: 'left',
@@ -2205,12 +2230,14 @@
yField: store.trendLineFields[i],
style: {
opacity: 0.8,
- lineWidth: 3,
- 'stroke-dasharray': 8
+ lineWidth: 2,
+ 'stroke-dasharray': 14,
+ stroke: strokeColor
},
markerConfig: {
type: 'circle',
- radius: 0
+ radius: 0,
+ fill: strokeColor
},
title: xResponse.metaData.names[store.trendLineFields[i]]
});
@@ -2227,12 +2254,12 @@
yField: store.targetLineFields,
style: {
opacity: 1,
- lineWidth: 2,
+ lineWidth: 1,
'stroke-width': 1,
- stroke: '#041423'
+ stroke: '#000'
},
showMarkers: false,
- title: (Ext.isString(xLayout.targetLineTitle) ? xLayout.targetLineTitle : DV.i18n.target) + ' (' + xLayout.targetLineValue + ')'
+ title: (Ext.isString(xLayout.targetLineTitle) ? xLayout.targetLineTitle : NS.i18n.target) + ' (' + xLayout.targetLineValue + ')'
};
};
@@ -2244,12 +2271,12 @@
yField: store.baseLineFields,
style: {
opacity: 1,
- lineWidth: 2,
+ lineWidth: 1,
'stroke-width': 1,
- stroke: '#041423'
+ stroke: '#000'
},
showMarkers: false,
- title: (Ext.isString(xLayout.baseLineTitle) ? xLayout.baseLineTitle : DV.i18n.base) + ' (' + xLayout.baseLineValue + ')'
+ title: (Ext.isString(xLayout.baseLineTitle) ? xLayout.baseLineTitle : NS.i18n.base) + ' (' + xLayout.baseLineValue + ')'
};
};
@@ -2269,18 +2296,6 @@
setDefaultTheme = function(store) {
var colors = conf.chart.theme.dv1.slice(0, store.rangeFields.length);
- if (xLayout.targetLineValue || xLayout.baseLineValue) {
- colors.push('#051a2e');
- }
-
- if (xLayout.targetLineValue) {
- colors.push('#051a2e');
- }
-
- if (xLayout.baseLineValue) {
- colors.push('#051a2e');
- }
-
Ext.chart.theme.dv1 = Ext.extend(Ext.chart.theme.Base, {
constructor: function(config) {
Ext.chart.theme.Base.prototype.constructor.call(this, Ext.apply({
@@ -2480,16 +2495,16 @@
return chart;
};
- generator.column = function() {
- var store = getDefaultStore(),
+ generator.column = function(isStacked) {
+ var store = getDefaultStore(isStacked),
numericAxis = getDefaultNumericAxis(store),
categoryAxis = getDefaultCategoryAxis(store),
axes = [numericAxis, categoryAxis],
series = [getDefaultSeries(store)];
- // Options
+ // options
if (xLayout.showTrendLine) {
- series = getDefaultTrendLines(store).concat(series);
+ series = series.concat(getDefaultTrendLines(store, isStacked));
}
if (xLayout.targetLineValue) {
@@ -2500,8 +2515,8 @@
series.push(getDefaultBaseLine(store));
}
- // Theme
- setDefaultTheme(store);
+ // theme
+ setDefaultTheme(store, isStacked);
return getDefaultChart({
store: store,
@@ -2511,12 +2526,7 @@
};
generator.stackedcolumn = function() {
- var chart = this.column();
-
- // sort order
- if (xLayout.sortOrder) {
- sortStoreBySum(chart.store, replacedColumnIds, xLayout.sortOrder);
- }
+ var chart = this.column(true);
for (var i = 0, item; i < chart.series.items.length; i++) {
item = chart.series.items[i];
@@ -2529,8 +2539,8 @@
return chart;
};
- generator.bar = function() {
- var store = getDefaultStore(),
+ generator.bar = function(isStacked) {
+ var store = getDefaultStore(isStacked),
numericAxis = getDefaultNumericAxis(store),
categoryAxis = getDefaultCategoryAxis(store),
axes,
@@ -2562,7 +2572,7 @@
series = [series];
if (xLayout.showTrendLine) {
- trendLines = getDefaultTrendLines(store);
+ trendLines = getDefaultTrendLines(store, isStacked);
for (var i = 0; i < trendLines.length; i++) {
trendLines[i].axis = 'bottom';
@@ -2570,7 +2580,7 @@
trendLines[i].yField = store.domainFields;
}
- series = trendLines.concat(series);
+ series = series.concat(trendLines);
}
if (xLayout.targetLineValue) {
@@ -2602,12 +2612,7 @@
};
generator.stackedbar = function() {
- var chart = this.bar();
-
- // sort order
- if (xLayout.sortOrder) {
- sortStoreBySum(chart.store, replacedColumnIds, xLayout.sortOrder);
- }
+ var chart = this.bar(true);
for (var i = 0, item; i < chart.series.items.length; i++) {
item = chart.series.items[i];
@@ -2699,17 +2704,12 @@
// NB, always true for area charts as extjs area charts cannot handle nulls
xLayout.hideEmptyRows = true;
- var store = getDefaultStore(),
+ var store = getDefaultStore(true),
numericAxis = getDefaultNumericAxis(store),
categoryAxis = getDefaultCategoryAxis(store),
axes = [numericAxis, categoryAxis],
series = getDefaultSeries(store);
- // sort order
- if (xLayout.sortOrder) {
- sortStoreBySum(store, replacedColumnIds, xLayout.sortOrder);
- }
-
series.type = 'area';
series.style.opacity = 0.7;
series.style.lineWidth = 0;
@@ -2719,7 +2719,7 @@
// Options
if (xLayout.showTrendLine) {
- series = getDefaultTrendLines(store).concat(series);
+ series = series.concat(getDefaultTrendLines(store, true));
}
if (xLayout.targetLineValue) {
@@ -2818,7 +2818,7 @@
seriesTitles = getDefaultSeriesTitle(store),
chart;
- // Axes
+ // axes
axes.push({
type: 'Radial',
position: 'radial',
@@ -2827,7 +2827,7 @@
}
});
- // Series
+ // series
for (var i = 0, obj; i < store.rangeFields.length; i++) {
obj = {
showInLegend: true,
@@ -2850,7 +2850,7 @@
series.push(obj);
}
-
+
chart = getDefaultChart({
store: store,
axes: axes,