=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js 2015-04-01 15:34:05 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js 2015-04-09 06:29:13 +0000 @@ -314,7 +314,7 @@ // hideEmptyRows: boolean (false) - // : boolean (false) + // collapseDataDimensions: boolean (false) // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT' === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/styles/style.css' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/styles/style.css 2015-03-11 16:35:26 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/styles/style.css 2015-04-08 13:50:25 +0000 @@ -340,11 +340,11 @@ .ns-viewport-text * { padding: 3px 10px; - font-size: 13px; + font-size: 11px; color: #515a62; } .ns-viewport-text h3 { - font-size: 15px; + font-size: 14px; font-weight: 500; color: #333; padding: 0 0 8px 0; === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/i18n/i18n_app.properties' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/i18n/i18n_app.properties 2015-04-03 15:43:32 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/i18n/i18n_app.properties 2015-04-08 13:50:25 +0000 @@ -180,8 +180,8 @@ you_do_not_have_access_to_all_items_in_this_favorite=You do not have access to all items in this favorite example1=Creating a chart example2=Select items from any of the dimensions in the left menu -example3=Click Layout to arrange your dimensions on table rows and columns -example4=Click Update to create your table +example3=Click Layout to arrange your dimensions on chart series and categories +example4=Click Update to create your chart example5=Working with a chart example6=Click Options to show trend lines, target lines, axis titles and more example7=Click Favorites to save your chart for later use @@ -200,6 +200,7 @@ series_dimension=Series dimension category_dimension=Category dimension chart_filter=Chart filter +report_filter=Report filter value=Value average=Average count=Count @@ -214,3 +215,6 @@ user_sub_units=User sub-units user_sub_x2_units=User sub-x2-units hide_na_data=Hide n/a data +duplicate=Duplicate +remove=Remove +select=Select === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/app.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/app.js 2015-04-03 15:43:32 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/app.js 2015-04-09 07:42:56 +0000 @@ -108,12 +108,18 @@ // data items (function() { - var operatorCmpWidth = 70, - valueCmpWidth = 306, + var scrollbarWidth = /\bchrome\b/.test(navigator.userAgent.toLowerCase()) ? 8 : 17, + nameCmpWidth = 440 - scrollbarWidth, buttonCmpWidth = 20, - nameCmpWidth = 400, - namePadding = '2px 3px', - margin = '3px 0 1px'; + operatorCmpWidth = 70, + searchCmpWidth = 70, + triggerCmpWidth = 17, + valueCmpWidth = 235, + rangeSetWidth = 135, + namePadding = '3px 3px', + margin = '3px 0 1px', + removeCmpStyle = 'padding: 0; margin-left: 3px', + defaultRangeSetId = 'default'; Ext.define('Ext.ux.panel.DataElementIntegerContainer', { extend: 'Ext.container.Container', @@ -122,44 +128,96 @@ bodyStyle: 'border:0 none', style: 'margin: ' + margin, getRecord: function() { - var record = {}; + var record = {}, + isRange = this.rangeSetCmp.getValue() !== defaultRangeSetId; record.dimension = this.dataElement.id; record.name = this.dataElement.name; - if (this.valueCmp.getValue()) { - record.filter = this.operatorCmp.getValue() + ':' + this.valueCmp.getValue(); - } + if (isRange) { + record.legendSet = { + id: this.rangeSetCmp.getValue() + }; + + if (this.rangeValueCmp.getValue().length) { + record.filter = 'IN:' + this.rangeValueCmp.getValue().join(';'); + } + } + else { + if (this.valueCmp.getValue()) { + record.filter = this.operatorCmp.getValue() + ':' + this.valueCmp.getValue(); + } + } return record; }, setRecord: function(record) { - if (record.filter) { + if (Ext.isObject(record.legendSet) && record.legendSet.id) { + this.rangeSetCmp.pendingValue = record.legendSet.id; + this.onRangeSetSelect(record.legendSet.id); + + if (record.filter) { + var a = record.filter.split(':'); + + if (a.length > 1 && Ext.isString(a[1])) { + this.onRangeSearchSelect(a[1].split(';'), true); + } + } + } + else if (record.filter) { + this.rangeSetCmp.pendingValue = defaultRangeSetId; + var a = record.filter.split(':'); - this.operatorCmp.setValue(a[0]); - this.valueCmp.setValue(a[1]); + if (a.length > 1) { + this.operatorCmp.setValue(a[0]); + this.valueCmp.setValue(a[1]); + } + else {} } }, initComponent: function() { - var container = this; + var container = this, + idProperty = 'id', + nameProperty = 'name', + displayProperty = 'displayName'; this.nameCmp = Ext.create('Ext.form.Label', { text: this.dataElement.name, - width: nameCmpWidth, + flex: 1, style: 'padding:' + namePadding }); + this.addCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: 'padding: 0', + height: 18, + text: NS.i18n.duplicate, + handler: function() { + container.duplicateDataElement(); + } + }); + + this.removeCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: removeCmpStyle, + height: 18, + text: NS.i18n.remove, + handler: function() { + container.removeDataElement(); + } + }); + this.operatorCmp = Ext.create('Ext.form.field.ComboBox', { - valueField: 'id', - displayField: 'name', + valueField: idProperty, + displayField: nameProperty, queryMode: 'local', editable: false, width: operatorCmpWidth, style: 'margin-bottom:0', value: 'EQ', store: { - fields: ['id', 'name'], + fields: [idProperty, nameProperty], data: [ {id: 'EQ', name: '='}, {id: 'GT', name: '>'}, @@ -172,32 +230,231 @@ }); this.valueCmp = Ext.create('Ext.form.field.Number', { - width: valueCmpWidth, + width: nameCmpWidth - operatorCmpWidth - rangeSetWidth, style: 'margin-bottom:0' }); - this.addCmp = Ext.create('Ext.button.Button', { - text: '+', - width: buttonCmpWidth, - handler: function() { - container.duplicateDataElement(); + this.rangeSearchStore = Ext.create('Ext.data.Store', { + fields: [idProperty, nameProperty] + }); + + // function + this.filterSearchStore = function(isLayout) { + var selected = container.rangeValueCmp.getValue(); + + // hack, using internal method to activate dropdown before filtering + if (isLayout) { + container.rangeSearchCmp.onTriggerClick(); + container.rangeSearchCmp.collapse(); + } + + // filter + container.rangeSearchStore.clearFilter(); + + container.rangeSearchStore.filterBy(function(record) { + return !Ext.Array.contains(selected, record.data[idProperty]); + }); + }; + + // function + this.onRangeSearchSelect = function(ids, isLayout) { + ids = Ext.Array.from(ids); + + // store + for (var i = 0, id; i < ids.length; i++) { + id = ids[i]; + + if (container.rangeValueStore.findExact(idProperty, id) === -1) { + container.rangeValueStore.add(container.rangeSearchStore.getAt(container.rangeSearchStore.findExact(idProperty, id)).data); + } + } + + // search cmp + container.rangeSearchCmp.select([]); + + // filter + container.filterSearchStore(isLayout); + }; + + this.rangeSearchCmp = Ext.create('Ext.form.field.ComboBox', { + multiSelect: true, + width: operatorCmpWidth, + style: 'margin-bottom: 0', + emptyText: NS.i18n.select + '..', + valueField: idProperty, + displayField: displayProperty, + editable: false, + queryMode: 'local', + hidden: true, + store: this.rangeSearchStore, + listConfig: { + minWidth: operatorCmpWidth + (nameCmpWidth - operatorCmpWidth - rangeSetWidth) + }, + listeners: { + select: function() { + container.onRangeSearchSelect(Ext.Array.from(this.getValue())[0]); + }, + expand: function() { + container.filterSearchStore(); + } } }); - this.removeCmp = Ext.create('Ext.button.Button', { - text: 'x', - width: buttonCmpWidth, - handler: function() { - container.removeDataElement(); + this.rangeValueStore = Ext.create('Ext.data.Store', { + fields: [idProperty, nameProperty], + listeners: { + add: function() { + container.rangeValueCmp.select(this.getRange()); + }, + remove: function() { + container.rangeValueCmp.select(this.getRange()); + } + } + }); + + this.rangeValueCmp = Ext.create('Ext.form.field.ComboBox', { + multiSelect: true, + style: 'margin-bottom: 0', + width: nameCmpWidth - operatorCmpWidth - rangeSetWidth, + valueField: idProperty, + displayField: nameProperty, + emptyText: 'No selected items', + editable: false, + hideTrigger: true, + queryMode: 'local', + hidden: true, + store: container.rangeValueStore, + listConfig: { + minWidth: valueCmpWidth, + cls: 'ns-optionselector' + }, + setOptionValues: function(records) { + var me = this; + + container.rangeValueStore.removeAll(); + container.rangeValueStore.loadData(records); + + me.setValue(records); + }, + listeners: { + change: function(cmp, newVal, oldVal) { + newVal = Ext.Array.from(newVal); + oldVal = Ext.Array.from(oldVal); + + if (newVal.length < oldVal.length) { + var id = Ext.Array.difference(oldVal, newVal)[0]; + container.rangeValueStore.removeAt(container.rangeValueStore.findExact(idProperty, id)); + } + } + } + }); + + // function + this.onRangeSetSelect = function(id) { + if (!id || id === defaultRangeSetId) { + container.operatorCmp.show(); + container.valueCmp.show(); + container.rangeSearchCmp.hide(); + container.rangeValueCmp.hide(); + } + else { + var ranges; + + container.operatorCmp.hide(); + container.valueCmp.hide(); + container.rangeSearchCmp.show(); + container.rangeValueCmp.show(); + + ranges = Ext.clone(ns.core.init.idLegendSetMap[id].legends); + + // display name + for (var i = 0; i < ranges.length; i++) { + range = ranges[i]; + range.displayName = range.name + ' (' + range.startValue + ' - ' + range.endValue + ')'; + } + + container.rangeSearchStore.loadData(ranges); + container.rangeSearchStore.sort('startValue', 'ASC'); + } + }; + + this.rangeSetCmp = Ext.create('Ext.form.field.ComboBox', { + cls: 'ns-combo h22', + style: 'margin-bottom: 0', + width: rangeSetWidth, + height: 22, + fieldStyle: 'height: 22px', + queryMode: 'local', + valueField: idProperty, + displayField: nameProperty, + editable: false, + storage: {}, + pendingValue: null, + setPendingValue: function() { + if (this.pendingValue) { + this.setValue(this.pendingValue); + container.onRangeSetSelect(this.pendingValue); + + this.pendingValue = null; + } + + if (!this.getValue()) { + this.pendingValue = defaultRangeSetId; + this.setPendingValue(); + } + }, + store: Ext.create('Ext.data.Store', { + fields: [idProperty, nameProperty] + }), + listeners: { + added: function(cb) { + cb.store.add({ + id: defaultRangeSetId, + name: 'No range set' + }); + + //cb.setValue(defaultRangeSetId); + + Ext.Ajax.request({ + url: ns.core.init.contextPath + '/api/dataElements/' + container.dataElement.id + '.json?fields=legendSet[id,name]', + success: function(r) { + r = Ext.decode(r.responseText); + + if (Ext.isObject(r) && Ext.isObject(r.legendSet)) { + cb.store.add(r.legendSet); + + cb.setValue(r.legendSet.id); + container.onRangeSetSelect(r.legendSet.id); + } + }, + callback: function() { + cb.setPendingValue(); + } + }); + }, + select: function(cb, r) { + var id = Ext.Array.from(r)[0].data.id; + container.onRangeSetSelect(id); + } } }); this.items = [ - this.nameCmp, + { + xtype: 'container', + layout: 'hbox', + width: nameCmpWidth, + items: [ + this.nameCmp, + this.addCmp, + this.removeCmp + ] + }, + this.rangeSearchCmp, + this.rangeValueCmp, this.operatorCmp, this.valueCmp, - this.addCmp, - this.removeCmp + this.rangeSetCmp ]; this.callParent(); @@ -231,10 +488,31 @@ this.nameCmp = Ext.create('Ext.form.Label', { text: this.dataElement.name, - width: nameCmpWidth, + flex: 1, style: 'padding:' + namePadding }); + this.addCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: 'padding: 0', + height: 18, + text: 'Duplicate', + handler: function() { + container.duplicateDataElement(); + } + }); + + this.removeCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: removeCmpStyle, + height: 18, + text: 'Remove', + handler: function() { + container.removeDataElement(); + } + }); + + this.operatorCmp = Ext.create('Ext.form.field.ComboBox', { valueField: 'id', displayField: 'name', @@ -253,32 +531,23 @@ }); this.valueCmp = Ext.create('Ext.form.field.Text', { - width: valueCmpWidth, + width: nameCmpWidth - operatorCmpWidth, style: 'margin-bottom:0' }); - this.addCmp = Ext.create('Ext.button.Button', { - text: '+', - width: buttonCmpWidth, - handler: function() { - container.duplicateDataElement(); - } - }); - - this.removeCmp = Ext.create('Ext.button.Button', { - text: 'x', - width: buttonCmpWidth, - handler: function() { - container.removeDataElement(); - } - }); - this.items = [ - this.nameCmp, + { + xtype: 'container', + layout: 'hbox', + width: nameCmpWidth, + items: [ + this.nameCmp, + this.addCmp, + this.removeCmp + ] + }, this.operatorCmp, - this.valueCmp, - this.addCmp, - this.removeCmp + this.valueCmp ]; this.callParent(); @@ -316,10 +585,30 @@ this.nameCmp = Ext.create('Ext.form.Label', { text: this.dataElement.name, - width: nameCmpWidth, + flex: 1, style: 'padding:' + namePadding }); + this.addCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: 'padding: 0', + height: 18, + text: 'Duplicate', + handler: function() { + container.duplicateDataElement(); + } + }); + + this.removeCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: removeCmpStyle, + height: 18, + text: 'Remove', + handler: function() { + container.removeDataElement(); + } + }); + this.operatorCmp = Ext.create('Ext.form.field.ComboBox', { valueField: 'id', displayField: 'name', @@ -342,33 +631,24 @@ }); this.valueCmp = Ext.create('Ext.form.field.Date', { - width: valueCmpWidth, + width: nameCmpWidth - operatorCmpWidth, style: 'margin-bottom:0', format: 'Y-m-d' }); - this.addCmp = Ext.create('Ext.button.Button', { - text: '+', - width: buttonCmpWidth, - handler: function() { - container.duplicateDataElement(); - } - }); - - this.removeCmp = Ext.create('Ext.button.Button', { - text: 'x', - width: buttonCmpWidth, - handler: function() { - container.removeDataElement(); - } - }); - this.items = [ - this.nameCmp, + { + xtype: 'container', + layout: 'hbox', + width: nameCmpWidth, + items: [ + this.nameCmp, + this.addCmp, + this.removeCmp + ] + }, this.operatorCmp, - this.valueCmp, - this.addCmp, - this.removeCmp + this.valueCmp ]; this.callParent(); @@ -403,48 +683,59 @@ this.nameCmp = Ext.create('Ext.form.Label', { text: this.dataElement.name, - width: nameCmpWidth, + flex: 1, style: 'padding:' + namePadding }); + this.addCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: 'padding: 0', + height: 18, + text: 'Duplicate', + handler: function() { + container.duplicateDataElement(); + } + }); + + this.removeCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: removeCmpStyle, + height: 18, + text: 'Remove', + handler: function() { + container.removeDataElement(); + } + }); + this.valueCmp = Ext.create('Ext.form.field.ComboBox', { valueField: 'id', displayField: 'name', queryMode: 'local', editable: false, - width: operatorCmpWidth + valueCmpWidth, + width: nameCmpWidth, style: 'margin-bottom:0', value: 'true', store: { fields: ['id', 'name'], data: [ - {id: 'true', name: EV.i18n.yes}, - {id: 'false', name: EV.i18n.no} + {id: 'true', name: ER.i18n.yes}, + {id: 'false', name: ER.i18n.no} ] } }); - this.addCmp = Ext.create('Ext.button.Button', { - text: '+', - width: buttonCmpWidth, - handler: function() { - container.duplicateDataElement(); - } - }); - - this.removeCmp = Ext.create('Ext.button.Button', { - text: 'x', - width: buttonCmpWidth, - handler: function() { - container.removeDataElement(); - } - }); - this.items = [ - this.nameCmp, - this.valueCmp, - this.addCmp, - this.removeCmp + { + xtype: 'container', + layout: 'hbox', + width: nameCmpWidth, + items: [ + this.nameCmp, + this.addCmp, + this.removeCmp + ] + }, + this.valueCmp ]; this.callParent(); @@ -457,12 +748,6 @@ layout: 'column', bodyStyle: 'border:0 none', style: 'margin: ' + margin, - addCss: function() { - var css = '.optionselector .x-boundlist-selected { background-color: #fff; border-color: #fff } \n'; - css += '.optionselector .x-boundlist-selected.x-boundlist-item-over { background-color: #ddd; border-color: #ddd } \n'; - - Ext.util.CSS.createStyleSheet(css); - }, getRecord: function() { var items = this.valueCmp.getValue(), record = { @@ -507,14 +792,32 @@ idProperty = 'code', nameProperty = 'name'; - this.addCss(); - this.nameCmp = Ext.create('Ext.form.Label', { text: this.dataElement.name, - width: nameCmpWidth, + flex: 1, style: 'padding:' + namePadding }); + this.addCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: 'padding: 0', + height: 18, + text: 'Duplicate', + handler: function() { + container.duplicateDataElement(); + } + }); + + this.removeCmp = Ext.create('Ext.button.Button', { + cls: 'ns-linkbutton', + style: removeCmpStyle, + height: 18, + text: 'Remove', + handler: function() { + container.removeDataElement(); + } + }); + this.operatorCmp = Ext.create('Ext.form.field.ComboBox', { valueField: 'id', displayField: 'name', @@ -540,7 +843,7 @@ optionSetId = optionSetId || container.dataElement.optionSet.id; pageSize = pageSize || 100; - dhis2.ev.store.get('optionSets', optionSetId).done( function(obj) { + dhis2.er.store.get('optionSets', optionSetId).done( function(obj) { if (Ext.isObject(obj) && Ext.isArray(obj.options) && obj.options.length) { var data = []; @@ -592,7 +895,7 @@ this.searchCmp = Ext.create('Ext.form.field.ComboBox', { multiSelect: true, - width: 62, + width: operatorCmpWidth - triggerCmpWidth, style: 'margin-bottom:0', emptyText: 'Search..', valueField: idProperty, @@ -601,7 +904,7 @@ enableKeyEvents: true, queryMode: 'local', listConfig: { - minWidth: 346 + minWidth: nameCmpWidth - operatorCmpWidth }, store: this.searchStore, listeners: { @@ -643,7 +946,7 @@ this.triggerCmp = Ext.create('Ext.button.Button', { cls: 'ns-button-combotrigger', disabledCls: 'ns-button-combotrigger-disabled', - width: 18, + width: triggerCmpWidth, height: 22, handler: function(b) { container.searchStore.loadOptionSet(); @@ -665,7 +968,7 @@ this.valueCmp = Ext.create('Ext.form.field.ComboBox', { multiSelect: true, style: 'margin-bottom:0', - width: 226, + width: nameCmpWidth - operatorCmpWidth - operatorCmpWidth, valueField: idProperty, displayField: nameProperty, emptyText: 'No selected items', @@ -675,13 +978,13 @@ queryMode: 'local', listConfig: { minWidth: 266, - cls: 'optionselector' + cls: 'ns-optionselector' }, setOptionValues: function(codeArray) { var me = this, records = []; - dhis2.ev.store.get('optionSets', container.dataElement.optionSet.id).done( function(obj) { + dhis2.er.store.get('optionSets', container.dataElement.optionSet.id).done( function(obj) { if (Ext.isObject(obj) && Ext.isArray(obj.options) && obj.options.length) { records = container.getRecordsByCode(obj.options, codeArray); @@ -705,31 +1008,21 @@ } }); - this.addCmp = Ext.create('Ext.button.Button', { - text: '+', - width: buttonCmpWidth, - style: 'font-weight:bold', - handler: function() { - container.duplicateDataElement(); - } - }); - - this.removeCmp = Ext.create('Ext.button.Button', { - text: 'x', - width: buttonCmpWidth, - handler: function() { - container.removeDataElement(); - } - }); - this.items = [ - this.nameCmp, + { + xtype: 'container', + layout: 'hbox', + width: nameCmpWidth, + items: [ + this.nameCmp, + this.addCmp, + this.removeCmp + ] + }, this.operatorCmp, this.searchCmp, this.triggerCmp, - this.valueCmp, - this.addCmp, - this.removeCmp + this.valueCmp ]; this.callParent(); @@ -1006,6 +1299,9 @@ filterStore, onValueSelect, value, + val, + onCollapseDataDimensionsChange, + collapseDataDimensions, aggregationType, getStore, @@ -1030,14 +1326,13 @@ dataType = 'aggregated_values', defaultValueId = 'default'; - getStore = function(data) { - var config = {}; + getStore = function(applyConfig) { + var config = {}, + store; config.fields = ['id', 'name']; - if (data) { - config.data = data; - } + Ext.apply(config, applyConfig); config.getDimensionNames = function() { var dimensionNames = []; @@ -1049,7 +1344,9 @@ return Ext.clone(dimensionNames); }; - return Ext.create('Ext.data.Store', config); + store = Ext.create('Ext.data.Store', config); + + return store; }; getStoreKeys = function(store) { @@ -1065,11 +1362,11 @@ return keys; }; - colStore = getStore(); - rowStore = getStore(); - fixedFilterStore = getStore(); - filterStore = getStore(); - valueStore = getStore(); + colStore = getStore({name: 'colStore'}); + rowStore = getStore({name: 'rowStore'}); + fixedFilterStore = getStore({name: 'fixedFilterStore'}); + filterStore = getStore({name: 'filterStore'}); + valueStore = getStore({name: 'valueStore'}); // store functions valueStore.addDefaultData = function() { @@ -1204,7 +1501,7 @@ height: 25, items: { xtype: 'label', - text: NS.i18n.chart_filter, + text: NS.i18n.report_filter, cls: 'ns-toolbar-multiselect-leftright-label' } }, @@ -1230,7 +1527,6 @@ store: filterStore, listeners: { afterrender: function(ms) { - ms.store.on('add', function() { Ext.defer( function() { ms.boundList.getSelectionModel().deselectAll(); @@ -1242,7 +1538,7 @@ aggregationType = Ext.create('Ext.form.field.ComboBox', { cls: 'ns-combo h22', - width: 70, + width: 80, height: 22, style: 'margin: 0', fieldStyle: 'height: 22px', @@ -1263,15 +1559,7 @@ }, store: Ext.create('Ext.data.Store', { fields: ['id', 'text'], - data: [ - {id: 'COUNT', text: NS.i18n.count}, - {id: 'AVERAGE', text: NS.i18n.average}, - {id: 'SUM', text: NS.i18n.sum}, - {id: 'STDDEV', text: NS.i18n.stddev}, - {id: 'VARIANCE', text: NS.i18n.variance}, - {id: 'MIN', text: NS.i18n.min}, - {id: 'MAX', text: NS.i18n.max} - ] + data: ns.core.conf.aggregationType.data }), resetData: function() { this.setDisabled(); @@ -1287,7 +1575,11 @@ // remove ux and layout item if (hasDimension(id, valueStore)) { - ns.app.accordion.getUx(id).removeDataElement(); + var uxArray = ns.app.accordion.getUxArray(id); + + for (var i = 0; i < uxArray.length; i++) { + uxArray[i].removeDataElement(); + } } } }; @@ -1325,6 +1617,42 @@ } }); + val = Ext.create('Ext.panel.Panel', { + bodyStyle: 'padding: 1px', + width: defaultWidth, + height: 220, + items: value, + tbar: { + height: 25, + style: 'padding: 1px', + items: [ + { + xtype: 'label', + height: 22, + style: 'padding-left: 6px; line-height: 22px', + text: NS.i18n.value + }, + '->', + aggregationType + ] + } + }); + + onCollapseDataDimensionsChange = function(value) { + toggleDataItems(value); + toggleValueGui(value); + }; + + collapseDataDimensions = Ext.create('Ext.form.field.Checkbox', { + boxLabel: NS.i18n.collapse_data_dimensions, + style: 'margin-left: 3px', + listeners: { + change: function(chb, value) { + onCollapseDataDimensionsChange(value); + } + } + }); + selectPanel = Ext.create('Ext.panel.Panel', { bodyStyle: 'border:0 none', items: [ @@ -1350,37 +1678,25 @@ bodyStyle: 'border:0 none', items: [ row, - { - xtype: 'panel', - bodyStyle: 'padding: 1px', - width: defaultWidth, - height: 220, - items: value, - tbar: { - height: 25, - style: 'padding: 1px', - items: [ - { - xtype: 'label', - height: 22, - style: 'padding-left: 6px; line-height: 22px', - text: NS.i18n.value - }, - '->', - aggregationType - ] - } - } + val ] } ] }); - addDimension = function(record, store, excludedStores) { - var store = dimensionStoreMap[record.id] || store || filterStore; + addDimension = function(record, store, excludedStores, force) { + store = store && force ? store : dimensionStoreMap[record.id] || store || filterStore; - if (!hasDimension(record.id, excludedStores) && record.id !== value.getValue()) { - store.add(record); + if (hasDimension(record.id, excludedStores)) { + if (force) { + removeDimension(record.id); + store.add(record); + } + } + else { + if (record.id !== value.getValue()) { + store.add(record); + } } }; @@ -1432,6 +1748,10 @@ map[record.data.id] = fixedFilterStore; }); + //valueStore.each(function(record) { + //map[record.data.id] = valueStore; + //}); + return map; }; @@ -1462,6 +1782,57 @@ fixedFilterStore.setListHeight(); }; + toggleDataItems = function(param) { + var stores = [colStore, rowStore, filterStore, fixedFilterStore], + collapse = Ext.isObject(param) && param.collapseDataItems ? param.collapseDataItems : param, + keys = ['ou', 'pe', 'dates'], + dy = ['dy'], + keys; + + // clear filters + for (var i = 0, store; i < stores.length; i++) { + stores[i].clearFilter(); + } + + // add dy if it does not exist + if (!hasDimension('dy')) { + addDimension({ + id: 'dy', + name: NS.i18n.data + }, rowStore); + } + + // keys + if (collapse) { // included keys + keys = ['ou', 'pe', 'dates', 'dy']; + } + else { // excluded keys + keys = ['dy']; + } + + // data items + for (var i = 0, store, include; i < stores.length; i++) { + store = stores[i]; + + if (collapse) { + store.filterBy(function(record, id) { + return Ext.Array.contains(keys, record.data.id); + }); + } + else { + store.filterBy(function(record, id) { + return !Ext.Array.contains(keys, record.data.id); + }); + } + } + }; + + toggleValueGui = function(param) { + var collapse = Ext.isObject(param) && param.collapseDataItems ? param.collapseDataItems : param; + + val.setDisabled(collapse); + }; + window = Ext.create('Ext.window.Window', { title: NS.i18n.table_layout, bodyStyle: 'background-color:#fff; padding:' + margin + 'px', @@ -1469,6 +1840,7 @@ autoShow: true, modal: true, resizable: false, + dataType: dataType, colStore: colStore, rowStore: rowStore, fixedFilterStore: fixedFilterStore, @@ -1478,9 +1850,14 @@ addDimension: addDimension, removeDimension: removeDimension, hasDimension: hasDimension, + dimensionStoreMap: dimensionStoreMap, saveState: saveState, resetData: resetData, reset: reset, + onCollapseDataDimensionsChange: onCollapseDataDimensionsChange, + collapseDataDimensions: collapseDataDimensions, + toggleDataItems: toggleDataItems, + toggleValueGui: toggleValueGui, getValueConfig: function() { var config = {}, valueId = value.getValue(); @@ -1492,23 +1869,42 @@ return config; }, - hideOnBlur: true, + getOptions: function() { + return { + collapseDataDimensions: collapseDataDimensions.getValue() + }; + }, + hideOnBlur: true, items: selectPanel, bbar: [ '->', { text: NS.i18n.hide, - handler: function() { - window.hide(); - } + listeners: { + added: function(b) { + b.on('click', function() { + window.hide(); + }); + } + } }, { text: '' + NS.i18n.update + '', - handler: function() { - ns.app.viewport.update(); - - window.hide(); - } + listeners: { + added: function(b) { + b.on('click', function() { + var config = ns.core.web.report.getLayoutConfig(); + + if (!config) { + return; + } + + ns.core.web.report.getData(config, false); + + window.hide(); + }); + } + } } ], listeners: { @@ -3108,8 +3504,10 @@ baseWidth = 446, toolWidth = 36, + accBaseWidth = baseWidth - 2, - accBaseWidth = baseWidth - 2; + conf = ns.core.conf, + rp = conf.period.relativePeriods; // stores @@ -3227,14 +3625,13 @@ levels = [], groups = [], - optionsWindow = ns.app.aggregateOptionsWindow; + optionsWindow = ns.app.aggregateOptionsWindow; reset(); + //ns.app.typeToolbar.setType(layout.dataType); ns.app.aggregateLayoutWindow.reset(); - - // type - ns.app.viewport.chartType.setChartType(layout.type); + //ns.app.queryLayoutWindow.reset(); // data programStore.add(layout.program); @@ -3373,10 +3770,12 @@ var load; programId = layout ? layout.program.id : programId; + + // reset stage.clearValue(); - dataElementsByStageStore.removeAll(); dataElementSelected.removeAllDataElements(true); + ns.app.aggregateLayoutWindow.value.resetData(); load = function(stages) { stage.enable(); @@ -3623,16 +4022,16 @@ return hasDataElement; }, - getUxById: function(dataElementId) { - var ux; + getUxArrayById: function(dataElementId) { + var uxArray = []; this.items.each(function(item) { if (item.dataElement.id === dataElementId) { - ux = item; + uxArray.push(item); } }); - return ux; + return uxArray; }, removeAllDataElements: function(reset) { var items = this.items.items, @@ -3652,6 +4051,7 @@ index = index || dataElementSelected.items.items.length; getUxType = function(element) { + if (Ext.isObject(element.optionSet) && Ext.isString(element.optionSet.id)) { return 'Ext.ux.panel.OrganisationUnitGroupSetContainer'; } @@ -3690,6 +4090,7 @@ } ns.app.aggregateLayoutWindow.removeDimension(element.id, ns.app.aggregateLayoutWindow.valueStore); + //ns.app.queryLayoutWindow.removeDimension(element.id); } }; @@ -3706,8 +4107,8 @@ selectDataElements = function(items, layout) { var dataElements = [], allElements = [], - fixedFilterElementIds = [], aggWindow = ns.app.aggregateLayoutWindow, + //queryWindow = ns.app.queryLayoutWindow, includeKeys = ['int', 'number', 'bool', 'boolean', 'trueOnly'], ignoreKeys = ['pe', 'ou'], recordMap = { @@ -3715,14 +4116,15 @@ 'ou': {id: 'ou', name: 'Organisation units'} }, extendDim = function(dim) { + var md = ns.app.response.metaData, + dimConf = ns.core.conf.finals.dimension; + dim.id = dim.id || dim.dimension; - dim.name = dim.name || ns.app.response.metaData.names[dim.dimension]; + dim.name = dim.name || md.names[dim.dimension] || dimConf.objectNameMap[dim.dimension].name; return dim; }; - fixedFilterElementIds = []; - // data element objects for (var i = 0, item; i < items.length; i++) { item = items[i]; @@ -3771,7 +4173,7 @@ element.name = element.name || element.displayName; recordMap[element.id] = element; - // add ux if not selected as value + // dont add ux if dim is selected as value if (element.id !== aggWindow.value.getValue()) { ux = addUxFromDataElement(element); @@ -3780,49 +4182,54 @@ } } - store = Ext.Array.contains(includeKeys, element.type) || element.optionSet ? aggWindow.rowStore : aggWindow.fixedFilterStore; - - if (store === aggWindow.fixedFilterStore) { - fixedFilterElementIds.push(element.id); - } + store = Ext.Array.contains(includeKeys, element.type) || element.optionSet ? aggWindow.colStore : aggWindow.fixedFilterStore; aggWindow.addDimension(element, store, valueStore); + //queryWindow.colStore.add(element); } - if (layout) { // && layout.dataType === 'aggregated_values') { - aggWindow.reset(true); - - if (layout.startDate && layout.endDate) { - aggWindow.fixedFilterStore.add({id: dimConf.startEndDate.value, name: dimConf.startEndDate.name}); - } - - if (layout.columns) { + // favorite + if (layout && layout.dataType === 'aggregated_values') { + + // start end dates + if (layout.startDate && layout.endDate) { + aggWindow.fixedFilterStore.add({id: dimConf.startEndDate.value, name: dimConf.startEndDate.name}); + } + + // columns + if (layout.columns) { for (var i = 0, record, dim; i < layout.columns.length; i++) { dim = layout.columns[i]; record = recordMap[dim.dimension]; - aggWindow.colStore.add(record || extendDim(Ext.clone(dim))); + aggWindow.addDimension(record || extendDim(Ext.clone(dim)), aggWindow.colStore, null, true); } } - if (layout.rows) { + // rows + if (layout.rows) { for (var i = 0, record, dim; i < layout.rows.length; i++) { dim = layout.rows[i]; record = recordMap[dim.dimension]; - aggWindow.rowStore.add(record || extendDim(Ext.clone(dim))); + aggWindow.addDimension(record || extendDim(Ext.clone(dim)), aggWindow.rowStore, null, true); } } - if (layout.filters) { + // filters + if (layout.filters) { for (var i = 0, store, record, dim; i < layout.filters.length; i++) { dim = layout.filters[i]; record = recordMap[dim.dimension]; store = Ext.Array.contains(includeKeys, element.type) || element.optionSet ? aggWindow.filterStore : aggWindow.fixedFilterStore; - store.add(record || extendDim(Ext.clone(dim))); + aggWindow.addDimension(record || extendDim(Ext.clone(dim)), store, null, true); } } + + // collapse data dimensions + aggWindow.collapseDataDimensions.setValue(layout.collapseDataDimensions); + aggWindow.onCollapseDataDimensionsChange(layout.collapseDataDimensions); } }; @@ -5414,6 +5821,9 @@ return; } + // dy + map['dy'] = [{dimension: 'dy'}]; + // pe if (periodMode.getValue() === 'dates') { view.startDate = startDate.getSubmitValue(); @@ -5459,110 +5869,71 @@ //map['longitude'] = [{dimension: 'longitude'}]; //map['latitude'] = [{dimension: 'latitude'}]; - // dimensions - if (layoutWindow.colStore) { - layoutWindow.colStore.each(function(item) { - a = map[item.data.id] || []; - - if (a.length) { - if (a.length === 1) { - columns.push(a[0]); - } - else { - var dim; - - for (var i = 0; i < a.length; i++) { - if (!dim) { - dim = a[i]; - } - else { - dim.filter += ':' + a[i].filter; - } - } - - columns.push(dim); - } - } - }); - } - - if (layoutWindow.rowStore) { - layoutWindow.rowStore.each(function(item) { - a = map[item.data.id] || []; - - if (a.length) { - if (a.length === 1) { - rows.push(a[0]); - } - else { - var dim; - - for (var i = 0; i < a.length; i++) { - if (!dim) { - dim = a[i]; - } - else { - dim.filter += ':' + a[i].filter; - } - } - - rows.push(dim); - } - } - }); - } - - if (layoutWindow.filterStore) { - layoutWindow.filterStore.each(function(item) { - a = map[item.data.id] || []; - - if (a.length) { - if (a.length === 1) { - filters.push(a[0]); - } - else { - var dim; - - for (var i = 0; i < a.length; i++) { - if (!dim) { - dim = a[i]; - } - else { - dim.filter += ':' + a[i].filter; - } - } - - filters.push(dim); - } - } - }); - } - - if (layoutWindow.fixedFilterStore) { - layoutWindow.fixedFilterStore.each(function(item) { - a = map[item.data.id] || []; - - if (a.length) { - if (a.length === 1) { - filters.push(a[0]); - } - else { - var dim; - - for (var i = 0; i < a.length; i++) { - if (!dim) { - dim = a[i]; - } - else { - dim.filter += ':' + a[i].filter; - } - } - - filters.push(dim); - } - } - }); - } + addAxisDimension = function(a, axis) { + if (a.length) { + if (a.length === 1) { + axis.push(a[0]); + } + else { + var dim; + + for (var i = 0; i < a.length; i++) { + if (!dim) { //todo ?? + dim = a[i]; + } + else { + dim.filter += ':' + a[i].filter; + } + } + + axis.push(dim); + } + } + }; + + // columns + store = layoutWindow.colStore; + + if (store) { + data = store.snapshot || store.data; + + data.each(function(item) { + addAxisDimension(map[item.data.id] || [], columns); + }); + } + + // rows + store = layoutWindow.rowStore; + + if (store) { + data = store.snapshot || store.data; + + data.each(function(item) { + addAxisDimension(map[item.data.id] || [], rows); + }); + } + + // filters + store = layoutWindow.filterStore; + + if (store) { + data = store.snapshot || store.data; + + data.each(function(item) { + addAxisDimension(map[item.data.id] || [], filters); + }); + } + + // fixed filters + store = layoutWindow.fixedFilterStore; + + if (store) { + data = store.snapshot || store.data; + + data.each(function(item) { + addAxisDimension(map[item.data.id] || [], filters); + }); + } if (columns.length) { view.columns = columns; @@ -5644,6 +6015,10 @@ setGui: setGui, getView: getView, + getUxArray: function(id) { + return dataElementSelected.getUxArrayById(id); + }, + listeners: { added: function() { ns.app.accordion = this; @@ -7157,18 +7532,17 @@ } }, afterrender: function(p) { - var liStyle = 'padding:3px 10px; color:#333', - html = ''; + var html = ''; - html += '
'; - html += '
' + NS.i18n.example1 + '
'; - html += '
- ' + NS.i18n.example2 + '
'; - html += '
- ' + NS.i18n.example3 + '
'; - html += '
- ' + NS.i18n.example4 + '
'; - html += '
' + NS.i18n.example5 + '
'; - html += '
- ' + NS.i18n.example6 + '
'; - html += '
- ' + NS.i18n.example7 + '
'; - html += '
- ' + NS.i18n.example8 + '
'; + html += '
'; + html += '

' + NS.i18n.example1 + '

'; + html += '
- ' + NS.i18n.example2 + '
'; + html += '
- ' + NS.i18n.example3 + '
'; + html += '
- ' + NS.i18n.example4 + '
'; + html += '

' + NS.i18n.example5 + '

'; + html += '
- ' + NS.i18n.example6 + '
'; + html += '
- ' + NS.i18n.example7 + '
'; + html += '
- ' + NS.i18n.example8 + '
'; html += '
'; p.update(html); @@ -7470,6 +7844,15 @@ } }); + // legend sets + requests.push({ + url: contextPath + '/api/legendSets.json?fields=id,name,legends[id,name,startValue,endValue,color]&paging=false', + success: function(r) { + init.legendSets = Ext.decode(r.responseText).legendSets || []; + fn(); + } + }); + // dimensions requests.push({ url: init.contextPath + '/api/organisationUnitGroupSets.json?fields=id,' + namePropertyUrl + '&paging=false', === 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 2015-04-03 15:43:32 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js 2015-04-09 07:52:01 +0000 @@ -3,16 +3,509 @@ // ext config Ext.Ajax.method = 'GET'; + Ext.isIE = (/trident/.test(Ext.userAgent)); + + Ext.isIE11 = Ext.isIE && (/rv:11.0/.test(Ext.userAgent)); + + Ext.util.CSS.createStyleSheet = function(cssText, id) { + var ss, + head = document.getElementsByTagName("head")[0], + styleEl = document.createElement("style"); + + styleEl.setAttribute("type", "text/css"); + + if (id) { + styleEl.setAttribute("id", id); + } + + if (Ext.isIE && !Ext.isIE11) { + head.appendChild(styleEl); + ss = styleEl.styleSheet; + ss.cssText = cssText; + } + else { + try { + styleEl.appendChild(document.createTextNode(cssText)); + } + catch(e) { + styleEl.cssText = cssText; + } + head.appendChild(styleEl); + ss = styleEl.styleSheet ? styleEl.styleSheet : (styleEl.sheet || document.styleSheets[document.styleSheets.length-1]); + } + this.cacheStyleSheet(ss); + return ss; + }; + // override + Ext.override(Ext.chart.Chart, { + insetPaddingObject: {}, + + alignAxes: function() { + var me = this, + axes = me.axes, + legend = me.legend, + edges = ['top', 'right', 'bottom', 'left'], + chartBBox, + insetPadding = me.insetPadding, + insetPaddingObject = me.insetPaddingObject, + insets = { + top: insetPaddingObject.top || insetPadding, + right: insetPaddingObject.right || insetPadding, + bottom: insetPaddingObject.bottom || insetPadding, + left: insetPaddingObject.left || insetPadding + }; + + function getAxis(edge) { + var i = axes.findIndex('position', edge); + return (i < 0) ? null : axes.getAt(i); + } + + + Ext.each(edges, function(edge) { + var isVertical = (edge === 'left' || edge === 'right'), + axis = getAxis(edge), + bbox; + + + if (legend !== false) { + if (legend.position === edge) { + bbox = legend.getBBox(); + insets[edge] += (isVertical ? bbox.width : bbox.height) + insets[edge]; + } + } + + + + if (axis && axis.bbox) { + bbox = axis.bbox; + insets[edge] += (isVertical ? bbox.width : bbox.height); + } + }); + + chartBBox = { + x: insets.left, + y: insets.top, + width: me.curWidth - insets.left - insets.right, + height: me.curHeight - insets.top - insets.bottom + }; + me.chartBBox = chartBBox; + + + + axes.each(function(axis) { + var pos = axis.position, + isVertical = (pos === 'left' || pos === 'right'); + + axis.x = (pos === 'right' ? chartBBox.x + chartBBox.width : chartBBox.x); + axis.y = (pos === 'top' ? chartBBox.y : chartBBox.y + chartBBox.height); + axis.width = (isVertical ? chartBBox.width : chartBBox.height); + axis.length = (isVertical ? chartBBox.height : chartBBox.width); + }); + } + }); + Ext.override(Ext.chart.series.Line, { drawSeries: function() { var ak=this,au=ak.chart,S=au.axes,ao=au.getChartStore(),V=ao.getCount(),u=ak.chart.surface,am={},R=ak.group,K=ak.showMarkers,aA=ak.markerGroup,D=au.shadow,C=ak.shadowGroups,X=ak.shadowAttributes,O=ak.smooth,q=C.length,ar=["M"],T=["M"],d=["M"],b=["M"],J=au.markerIndex,ai=[].concat(ak.axis),ah,av=[],ag={},aa=[],v={},I=false,Q=[],az=ak.markerStyle,Z=ak.style,t=ak.colorArrayStyle,P=t&&t.length||0,L=Ext.isNumber,aw=ak.seriesIdx,g=ak.getAxesForXAndYFields(),l=g.xAxis,ay=g.yAxis,ac,h,ab,ad,A,c,ae,H,G,f,e,s,r,W,N,M,at,m,F,E,aB,n,p,B,a,Y,af,z,aq,w,ap,o,ax,an,al,U,k,aj;if(ak.fireEvent("beforedraw",ak)===false){return}if(!V||ak.seriesIsHidden){aj=this.items;if(aj){for(N=0,at=aj.length;Nam.width){a=ak.shrink(av,aa,am.width);av=a.x;aa=a.y}ak.items=[];k=0;at=av.length;for(N=0;N 1 && Ext.isString(a[1])) { - var options = a[1].split(';'), - items = []; + var options = a[1].split(';'); - for (var j = 0, dim; j < dimensions.length; j++) { + for (var j = 0, dim, items; j < dimensions.length; j++) { dim = dimensions[j]; if (dim.dimension === orgDim.dimension && dim.items && dim.items.length) { - var items = []; + items = []; for (var k = 0, option; k < options.length; k++) { option = options[k]; for (var l = 0, item; l < dim.items.length; l++) { item = dim.items[l]; - - if (item.name === option) { + if (item.id === option || item.id === (dim.dimension + option)) { items.push(item); } } @@ -1354,6 +1937,21 @@ } } } + // no specified legends -> sort by start value + else if (orgDim.legendSet && orgDim.legendSet.id) { + for (var j = 0, dim, items; j < dimensions.length; j++) { + dim = dimensions[j]; + + if (dim.dimension === orgDim.dimension && dim.items && dim.items.length) { + + // get start/end value + support.prototype.array.getObjectDataById(dim.items, init.idLegendSetMap[orgDim.legendSet.id].legends, ['startValue', 'endValue']); + + // sort by start value + support.prototype.array.sort(dim.items, 'ASC', 'startValue'); + } + } + } } // re-layout @@ -1997,7 +2595,10 @@ web.analytics.getParamString = function(layout, format) { var paramString, dimensions = Ext.Array.clean([].concat(layout.columns || [], layout.rows || [])), - ignoreKeys = ['longitude', 'latitude'], + ignoreKeys = ['dy', 'longitude', 'latitude'], + dataTypeMap = { + 'aggregated_values': 'aggregate' + }, nameItemsMap; paramString = '/api/analytics/events/aggregate/' + layout.program.id + '.' + (format || 'json') + '?'; @@ -2025,6 +2626,13 @@ paramString += encodeURIComponent(item.id) + ((j < (dim.items.length - 1)) ? ';' : ''); } } + else if (Ext.isObject(dim.legendSet) && dim.legendSet.id) { + paramString += '-' + dim.legendSet.id; + + if (dim.filter) { + paramString += ':' + encodeURIComponent(dim.filter); + } + } else { paramString += dim.filter ? ':' + encodeURIComponent(dim.filter) : ''; } @@ -2046,6 +2654,13 @@ paramString += j < dim.items.length - 1 ? ';' : ''; } } + else if (Ext.isObject(dim.legendSet) && dim.legendSet.id) { + paramString += '-' + dim.legendSet.id; + + if (dim.filter) { + paramString += ':' + encodeURIComponent(dim.filter); + } + } else { paramString += dim.filter ? ':' + encodeURIComponent(dim.filter) : ''; } @@ -2078,6 +2693,11 @@ // display property paramString += '&displayProperty=' + init.userAccount.settings.keyAnalysisDisplayProperty.toUpperCase(); + // collapse data items + if (layout.collapseDataDimensions) { + paramString += '&collapseDataDimensions=true'; + } + return paramString; }; @@ -2454,7 +3074,12 @@ fields: store.numericFields, minimum: minimum < 0 ? minimum : 0, label: { - renderer: Ext.util.Format.numberRenderer(renderer) + //renderer: Ext.util.Format.numberRenderer(renderer), + renderer: function(v) { + return support.prototype.number.prettyPrint(v); + }, + style: {}, + rotate: {} }, labelTitle: { font: 'bold 13px ' + conf.chart.style.fontFamily @@ -2462,13 +3087,13 @@ grid: { odd: { opacity: 1, - stroke: '#aaa', - 'stroke-width': 0.1 + stroke: '#000', + 'stroke-width': 0.03 }, even: { opacity: 1, - stroke: '#aaa', - 'stroke-width': 0.1 + stroke: '#000', + 'stroke-width': 0.03 } } }; @@ -2571,13 +3196,34 @@ }; if (xLayout.showValues) { + var labelFont = conf.chart.style.fontFamily, + labelColor = 'black'; + + if (Ext.isObject(xLayout.seriesStyle)) { + var style = xLayout.seriesStyle; + + // label + labelColor = style.labelColor || labelColor; + + if (style.labelFont) { + labelFont = style.labelFont; + } + else { + labelFont = style.labelFontWeight ? style.labelFontWeight + ' ' : 'normal '; + labelFont += style.labelFontSize ? parseFloat(style.labelFontSize) + 'px ' : '11px '; + labelFont += style.labelFontFamily ? style.labelFontFamily : conf.chart.style.fontFamily; + } + } + main.label = { display: 'outside', 'text-anchor': 'middle', field: store.rangeFields, - font: conf.chart.style.fontFamily, + font: labelFont, + fill: labelColor, renderer: function(n) { - return n === '0.0' ? '' : n; + n = n === '0.0' ? '' : n; + return support.prototype.number.prettyPrint(n); } }; } @@ -2655,7 +3301,7 @@ renderer: function(si, item) { if (item.value) { var value = item.value[1] === '0.0' ? '-' : item.value[1]; - this.update('
' + value + '
' + si.data[conf.finals.data.domain] + '
'); + this.update('
' + support.prototype.number.prettyPrint(value) + '
' + si.data[conf.finals.data.domain] + '
'); } } }; @@ -2802,8 +3448,10 @@ tmpText = ''; if (operator === 'IN') { - for (var ii = 0; ii < valueArray.length; ii++) { - tmpText += (tmpText.length ? ', ' : '') + valueArray[ii]; + for (var ii = 0, value; ii < valueArray.length; ii++) { + value = valueArray[ii]; + + tmpText += (tmpText.length ? ', ' : '') + (md.booleanNames[value] || md.optionNames[value] || md.names[value] || value); } text += tmpText; @@ -2841,6 +3489,14 @@ } } + // aggregation type + if (Ext.isObject(layout.value) && layout.value.id && layout.aggregationType) { + var value = layout.value.id; + + text += text.length ? ', ' : ''; + text += (md.booleanNames[value] || md.optionNames[value] || md.names[value] || value) + ' (' + conf.aggregationType.idNameMap[layout.aggregationType] + ')'; + } + fontSize = (centerRegion.getWidth() / text.length) < 11.6 ? 13 : 18; return Ext.create('Ext.draw.Sprite', { @@ -3340,12 +3996,12 @@ } // legend set map - //init.idLegendSetMap = {}; + init.idLegendSetMap = {}; - //for (var i = 0, set; i < init.legendSets.length; i++) { - //set = init.legendSets[i]; - //init.idLegendSetMap[set.id] = set; - //} + for (var i = 0, set; i < init.legendSets.length; i++) { + set = init.legendSets[i]; + init.idLegendSetMap[set.id] = set; + } }()); // instance === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/styles/style.css' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/styles/style.css 2015-02-25 14:51:26 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/styles/style.css 2015-04-08 13:50:25 +0000 @@ -312,6 +312,23 @@ /*---------------------------------------------------------------------------- + * NS viewport + *--------------------------------------------------------------------------*/ + +.ns-viewport-text * { + padding: 3px 10px; + font-size: 11px; + color: #515a62; +} +.ns-viewport-text h3 { + font-size: 14px; + font-weight: 500; + color: #333; + padding: 0 0 8px 0; +} + + +/*---------------------------------------------------------------------------- * Panel *--------------------------------------------------------------------------*/ @@ -414,13 +431,13 @@ /* Custom */ .ns-combo.h21 .x-form-trigger { - height: 21px; + height: 21px !important; } .ns-combo.h22 .x-form-trigger { - height: 22px; + height: 22px !important; } .ns-combo.h24 .x-form-trigger { - height: 24px; + height: 24px !important; } /*---------------------------------------------------------------------------- @@ -795,6 +812,19 @@ cursor: default !important; } + /* Link button */ +.ns-linkbutton.x-btn-default-small { + border: 1px solid transparent; + background: transparent; +} +.ns-linkbutton .x-btn-inner { + color: #3162c5; + padding: 0; +} +.ns-linkbutton.x-btn-over .x-btn-inner { + text-decoration: underline; +} + /*---------------------------------------------------------------------------- * Tooltip === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/app.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/app.js 2015-03-31 16:30:59 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/app.js 2015-04-08 13:50:25 +0000 @@ -6226,18 +6226,17 @@ ns.app.centerRegion = this; }, afterrender: function(p) { - var liStyle = 'padding:3px 10px; color:#333', - html = ''; + var html = ''; - html += '
'; - html += '
' + NS.i18n.example1 + '
'; - html += '
- ' + NS.i18n.example2 + '
'; - html += '
- ' + NS.i18n.example3 + '
'; - html += '
- ' + NS.i18n.example4 + '
'; - html += '
' + NS.i18n.example5 + '
'; - html += '
- ' + NS.i18n.example6 + '
'; - html += '
- ' + NS.i18n.example7 + '
'; - html += '
- ' + NS.i18n.example8 + '
'; + html += '
'; + html += '

' + NS.i18n.example1 + '

'; + html += '
- ' + NS.i18n.example2 + '
'; + html += '
- ' + NS.i18n.example3 + '
'; + html += '
- ' + NS.i18n.example4 + '
'; + html += '

' + NS.i18n.example5 + '

'; + html += '
- ' + NS.i18n.example6 + '
'; + html += '
- ' + NS.i18n.example7 + '
'; + html += '
- ' + NS.i18n.example8 + '
'; html += '
'; p.update(html); === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/styles/style.css' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/styles/style.css 2015-03-31 14:29:54 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/styles/style.css 2015-04-08 13:50:25 +0000 @@ -312,6 +312,23 @@ /*---------------------------------------------------------------------------- + * NS viewport + *--------------------------------------------------------------------------*/ + +.ns-viewport-text * { + padding: 3px 10px; + font-size: 11px; + color: #515a62; +} +.ns-viewport-text h3 { + font-size: 14px; + font-weight: 500; + color: #333; + padding: 0 0 8px 0; +} + + +/*---------------------------------------------------------------------------- * Panel *--------------------------------------------------------------------------*/ === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/app.js' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/app.js 2015-03-31 16:28:36 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/app.js 2015-04-08 13:50:25 +0000 @@ -6314,18 +6314,17 @@ } }, afterrender: function(p) { - var liStyle = 'padding:3px 10px; color:#333', - html = ''; + var html = ''; - html += '
'; - html += '
' + NS.i18n.example1 + '
'; - html += '
- ' + NS.i18n.example2 + '
'; - html += '
- ' + NS.i18n.example3 + '
'; - html += '
- ' + NS.i18n.example4 + '
'; - html += '
' + NS.i18n.example5 + '
'; - html += '
- ' + NS.i18n.example6 + '
'; - html += '
- ' + NS.i18n.example7 + '
'; - html += '
- ' + NS.i18n.example8 + '
'; + html += '
'; + html += '

' + NS.i18n.example1 + '

'; + html += '
- ' + NS.i18n.example2 + '
'; + html += '
- ' + NS.i18n.example3 + '
'; + html += '
- ' + NS.i18n.example4 + '
'; + html += '

' + NS.i18n.example5 + '

'; + html += '
- ' + NS.i18n.example6 + '
'; + html += '
- ' + NS.i18n.example7 + '
'; + html += '
- ' + NS.i18n.example8 + '
'; html += '
'; p.update(html); === modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/styles/style.css' --- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/styles/style.css 2015-03-09 13:15:43 +0000 +++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/styles/style.css 2015-04-08 13:50:25 +0000 @@ -131,6 +131,23 @@ /*---------------------------------------------------------------------------- + * NS viewport + *--------------------------------------------------------------------------*/ + +.ns-viewport-text * { + padding: 3px 10px; + font-size: 11px; + color: #515a62; +} +.ns-viewport-text h3 { + font-size: 14px; + font-weight: 500; + color: #333; + padding: 0 0 8px 0; +} + + +/*---------------------------------------------------------------------------- * Panel *--------------------------------------------------------------------------*/