=== modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/GetAggregatedValuesAction.java' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/GetAggregatedValuesAction.java 2011-12-01 20:07:31 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/GetAggregatedValuesAction.java 2011-12-07 13:47:00 +0000 @@ -121,7 +121,7 @@ if ( dataElementIds != null ) { dataValues = aggregatedDataValueService.getAggregatedDataValueTotals( dataElementIds, periodIds, - organisationUnitIds ); + organisationUnitIds ); } } === added file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/GetAggregatedValuesPluginAction.java' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/GetAggregatedValuesPluginAction.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/java/org/hisp/dhis/visualizer/action/GetAggregatedValuesPluginAction.java 2011-12-07 14:23:12 +0000 @@ -0,0 +1,267 @@ +package org.hisp.dhis.visualizer.action; + +/* + * Copyright (c) 2004-2010, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; + +import org.hisp.dhis.aggregation.AggregatedDataValue; +import org.hisp.dhis.aggregation.AggregatedDataValueService; +import org.hisp.dhis.aggregation.AggregatedIndicatorValue; +import org.hisp.dhis.dataelement.DataElementService; +import org.hisp.dhis.i18n.I18nFormat; +import org.hisp.dhis.indicator.IndicatorService; +import org.hisp.dhis.organisationunit.OrganisationUnitService; +import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodService; +import org.hisp.dhis.period.RelativePeriods; + +import com.opensymphony.xwork2.Action; + +/** + * @author Jan Henrik Overland + */ +public class GetAggregatedValuesPluginAction + implements Action +{ + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + private AggregatedDataValueService aggregatedDataValueService; + + public void setAggregatedDataValueService( AggregatedDataValueService aggregatedDataValueService ) + { + this.aggregatedDataValueService = aggregatedDataValueService; + } + + private IndicatorService indicatorService; + + public void setIndicatorService( IndicatorService indicatorService ) + { + this.indicatorService = indicatorService; + } + + private DataElementService dataElementService; + + public void setDataElementService( DataElementService dataElementService ) + { + this.dataElementService = dataElementService; + } + + private PeriodService periodService; + + public void setPeriodService( PeriodService periodService ) + { + this.periodService = periodService; + } + + private OrganisationUnitService organisationUnitService; + + public void setOrganisationUnitService( OrganisationUnitService organisationUnitService ) + { + this.organisationUnitService = organisationUnitService; + } + + private I18nFormat format; + + public void setFormat( I18nFormat format ) + { + this.format = format; + } + + // ------------------------------------------------------------------------- + // Input + // ------------------------------------------------------------------------- + + private Collection indicatorIds; + + public void setIndicatorIds( Collection indicatorIds ) + { + this.indicatorIds = indicatorIds; + } + + private Collection dataElementIds; + + public void setDataElementIds( Collection dataElementIds ) + { + this.dataElementIds = dataElementIds; + } + + private Collection organisationUnitIds; + + public void setOrganisationUnitIds( Collection organisationUnitIds ) + { + this.organisationUnitIds = organisationUnitIds; + } + + private boolean lastMonth; + + public void setLastMonth( boolean lastMonth ) + { + this.lastMonth = lastMonth; + } + + private boolean monthsThisYear; + + public void setMonthsThisYear( boolean monthsThisYear ) + { + this.monthsThisYear = monthsThisYear; + } + + private boolean monthsLastYear; + + public void setMonthsLastYear( boolean monthsLastYear ) + { + this.monthsLastYear = monthsLastYear; + } + + private boolean lastQuarter; + + public void setLastQuarter( boolean lastQuarter ) + { + this.lastQuarter = lastQuarter; + } + + private boolean quartersThisYear; + + public void setQuartersThisYear( boolean quartersThisYear ) + { + this.quartersThisYear = quartersThisYear; + } + + private boolean quartersLastYear; + + public void setQuartersLastYear( boolean quartersLastYear ) + { + this.quartersLastYear = quartersLastYear; + } + + private boolean thisYear; + + public void setThisYear( boolean thisYear ) + { + this.thisYear = thisYear; + } + + private boolean lastYear; + + public void setLastYear( boolean lastYear ) + { + this.lastYear = lastYear; + } + + private boolean lastFiveYears; + + public void setLastFiveYears( boolean lastFiveYears ) + { + this.lastFiveYears = lastFiveYears; + } + + // ------------------------------------------------------------------------- + // Output + // ------------------------------------------------------------------------- + + private Collection indicatorValues = new HashSet(); + + public Collection getIndicatorValues() + { + return indicatorValues; + } + + private Collection dataValues = new HashSet(); + + public Collection getDataValues() + { + return dataValues; + } + + // ------------------------------------------------------------------------- + // Action implementation + // ------------------------------------------------------------------------- + + public String execute() + throws Exception + { + if ( organisationUnitIds != null + && (lastMonth || monthsThisYear || monthsLastYear || lastQuarter || quartersThisYear || quartersLastYear + || thisYear || lastYear || lastFiveYears) ) + { + RelativePeriods rp = new RelativePeriods(); + rp.setReportingMonth( lastMonth ); + rp.setMonthsThisYear( monthsThisYear ); + rp.setMonthsLastYear( monthsLastYear ); + rp.setReportingQuarter( lastQuarter ); + rp.setQuartersThisYear( quartersThisYear ); + rp.setQuartersLastYear( quartersLastYear ); + rp.setThisYear( thisYear ); + rp.setLastYear( lastYear ); + rp.setLast5Years( lastFiveYears ); + + Collection periods = periodService.reloadPeriods( rp.getRelativePeriods() ); + + Collection periodIds = new ArrayList(); + + for ( Period period : periods ) + { + periodIds.add( period.getId() ); + } + + if ( indicatorIds != null ) + { + indicatorValues = aggregatedDataValueService.getAggregatedIndicatorValues( indicatorIds, periodIds, + organisationUnitIds ); + + for ( AggregatedIndicatorValue value : indicatorValues ) + { + value.setIndicatorName( indicatorService.getIndicator( value.getIndicatorId() ).getShortName() ); + value.setPeriodName( format.formatPeriod( periodService.getPeriod( value.getPeriodId() ) ) ); + value.setOrganisationUnitName( organisationUnitService.getOrganisationUnit( + value.getOrganisationUnitId() ).getName() ); + } + } + + if ( dataElementIds != null ) + { + dataValues = aggregatedDataValueService.getAggregatedDataValueTotals( dataElementIds, periodIds, + organisationUnitIds ); + + for ( AggregatedDataValue value : dataValues ) + { + value.setDataElementName( dataElementService.getDataElement( value.getDataElementId() ).getShortName() ); + value.setPeriodName( format.formatPeriod( periodService.getPeriod( value.getPeriodId() ) ) ); + value.setOrganisationUnitName( organisationUnitService.getOrganisationUnit( + value.getOrganisationUnitId() ).getName() ); + } + } + } + + return SUCCESS; + } +} === modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/META-INF/dhis/beans.xml 2011-11-25 12:25:07 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/resources/META-INF/dhis/beans.xml 2011-12-07 10:12:25 +0000 @@ -76,6 +76,18 @@ ref="org.hisp.dhis.aggregation.AggregatedDataValueService" /> + + + + + + + + + + + /dhis-web-visualizer/jsonminAggregatedValuesPlugin.vm + + /dhis-web-visualizer/void.vm + + === modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/plugin.css' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/plugin.css 2011-12-06 16:07:41 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/css/plugin.css 2011-12-07 17:05:24 +0000 @@ -8,19 +8,19 @@ } #chart1 { + width: 1000px; + height: 600px; + border: 2px solid #ddd; + margin-bottom: 100px; +} + +#chart2 { width: 600px; height: 400px; border: 2px solid #ddd; margin-bottom: 100px; } -#chart2 { - width: 1400px; - height: 400px; - border: 2px solid #ccc; - margin-bottom: 100px; -} - #chart3 { width: 1400px; height: 700px; @@ -28,3 +28,27 @@ border: 2px solid #ccc; margin-bottom: 100px; } + +/* Tooltip */ +.x-tip { + -moz-border-radius: 2px 2px 2px 2px; + -webkit-border-radius: 2px 2px 2px 2px; + -o-border-radius: 2px 2px 2px 2px; + -ms-border-radius: 2px 2px 2px 2px; + -khtml-border-radius: 2px 2px 2px 2px; + border-radius: 2px 2px 2px 2px; + padding: 2px 5px 2px 0; + border-width: 2px; + border-style: solid; + background-color: #eee; +} + +/* Chart tips (tooltip) */ +.x-tip .x-tip-header .x-box-item { + text-align: center; +} + +.dv-chart-tips { + font: normal 13px arial, ubuntu; + padding: 0 0 3px 3px; +} === modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin/plugin.html' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin/plugin.html 2011-12-06 16:07:41 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin/plugin.html 2011-12-07 17:05:24 +0000 @@ -7,15 +7,36 @@ - - +

My chart 1

- - === modified file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin/plugin.js' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin/plugin.js 2011-12-06 16:07:41 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/app/plugin/plugin.js 2011-12-07 17:05:24 +0000 @@ -5,10 +5,13 @@ url_visualizer: '../', url_commons: '../../dhis-web-commons-ajax-json/', url_portal: '../../dhis-web-portal/', - url_indicator: 'getAggregatedIndicatorValuesPlugin', - url_dataelement: 'getAggregatedDataValuesPlugin' + url_data: 'getAggregatedValuesPlugin' }, dimension: { + data: { + value: 'data', + rawvalue: 'Data' + }, indicator: { value: 'indicator', rawvalue: 'Indicator' @@ -39,6 +42,9 @@ area: 'area', pie: 'pie' } + }, + chart: { + inset: 10 } }; @@ -59,18 +65,12 @@ DHIS.util = { dimension: { - indicator: { + data: { getUrl: function(isFilter) { var a = []; Ext.Array.each(DHIS.state.state.conf.indicators, function(r) { a.push('indicatorIds=' + r); }); - return (isFilter && a.length > 1) ? a.slice(0,1) : a; - } - }, - dataelement: { - getUrl: function(isFilter) { - var a = []; Ext.Array.each(DHIS.state.state.conf.dataelements, function(r) { a.push('dataElementIds=' + r); }); @@ -97,10 +97,9 @@ } }, chart: { - getLegend: function(len) { - len = len ? len : 1; + getLegend: function(pos) { return { - position: len > 5 ? 'right' : 'top', + position: pos, labelFont: '11px arial', boxStroke: '#ffffff', boxStrokeWidth: 0, @@ -115,7 +114,7 @@ 'stroke-width': 0.2 }; }, - getTitle: function() { + getTitle: function(pos, size) { return { type: 'text', text: DHIS.state.state.filter.names[0], @@ -123,8 +122,8 @@ fill: '#222', width: 300, height: 20, - x: 28, - y: 16 + x: DHIS.util.chart.getTitlePosition(pos, size).x, + y: DHIS.util.chart.getTitlePosition(pos, size).y }; }, getTips: function() { @@ -135,6 +134,20 @@ } }; }, + getSize: function(scope, project) { + return { + width: project.state.conf.width || scope.el.getWidth(), + height: project.state.conf.height || scope.el.getHeight() + }; + }, + getTitlePosition: function(pos, size) { + if (pos === 'bottom') { + return {x:28, y:size.height-16}; + } + else { + return {x:28, y:16}; + } + }, setMask: function(str) { if (DHIS.mask) { DHIS.mask.hide(); @@ -204,13 +217,13 @@ } ]; }, - getTips: function() { + getTips: function(store) { return { trackMouse: true, height: 47, renderer: function(item) { this.setWidth((item.data.x.length * 8) + 15); - this.setTitle('' + item.data.x + '
' + item.data[DV.store.chart.left[0]] + '
'); + this.setTitle('' + item.data.x + '
' + item.data[store.left[0]] + '
'); } }; } @@ -247,6 +260,21 @@ } return url; } + }, + value: { + jsonfy: function(r) { + r = Ext.JSON.decode(r.responseText); + var values = []; + for (var i = 0; i < r.length; i++) { + var obj = {}; + obj.v = r[i][0]; + obj[DHIS.conf.finals.dimension.data.value] = r[i][1]; + obj[DHIS.conf.finals.dimension.period.value] = r[i][2]; + obj[DHIS.conf.finals.dimension.organisationunit.value] = r[i][3]; + values.push(obj); + } + return values; + } } }; @@ -304,15 +332,6 @@ filter: { dimension: null, names: [] - }, - getIndiment: function() { - var i = DHIS.conf.finals.dimension.indicator.value; - return (this.series.dimension === i || this.category.dimension === i || this.filter.dimension === i) ? - DHIS.conf.finals.dimension.indicator : DHIS.conf.finals.dimension.dataelement; - }, - isIndicator: function() { - var i = DHIS.conf.finals.dimension.indicator.value; - return (this.series.dimension === i || this.category.dimension === i || this.filter.dimension === i); } } }; @@ -323,11 +342,12 @@ indicators: [], periods: ['monthsThisYear'], organisationunits: [], - series: 'indicator', + series: 'data', category: 'period', filter: 'organisationunit', el: '', - legendPosition: false, + titlePosition: 'top', + legendPosition: 'top', url: '' }; @@ -346,20 +366,12 @@ DHIS.value = { getValues: function(project) { - var params = [], - indicator = DHIS.conf.finals.dimension.indicator.value, - dataelement = DHIS.conf.finals.dimension.dataelement.value, - series = project.state.series.dimension, - category = project.state.category.dimension, - filter = project.state.filter.dimension, - indiment = project.state.getIndiment().value, - url = project.state.isIndicator() ? DHIS.conf.finals.ajax.url_indicator : DHIS.conf.finals.ajax.url_dataelement; - - params = params.concat(DHIS.util.dimension[series].getUrl()); - params = params.concat(DHIS.util.dimension[category].getUrl()); - params = params.concat(DHIS.util.dimension[filter].getUrl(true)); + var params = []; + params = params.concat(DHIS.util.dimension[project.state.series.dimension].getUrl()); + params = params.concat(DHIS.util.dimension[project.state.category.dimension].getUrl()); + params = params.concat(DHIS.util.dimension[project.state.filter.dimension].getUrl(true)); - var baseUrl = DHIS.util.string.extendUrl(project.state.conf.url) + url + '.action'; + var baseUrl = DHIS.util.string.extendUrl(project.state.conf.url) + DHIS.conf.finals.ajax.url_data + '.action'; Ext.Array.each(params, function(item) { baseUrl = Ext.String.urlAppend(baseUrl, item); }); @@ -367,7 +379,7 @@ Ext.Ajax.request({ url: baseUrl, success: function(r) { - project.values = Ext.JSON.decode(r.responseText).values; + project.values = DHIS.util.value.jsonfy(r); if (!project.values.length) { alert('No data values'); @@ -375,19 +387,13 @@ } Ext.Array.each(project.values, function(item) { - item.indicator = item.in; - item.dataelement = item.in; - item.period = item.pn; - item.organisationunit = item.on; - Ext.Array.include(project.state.series.names, DHIS.util.string.getEncodedString(item[project.state.series.dimension])); Ext.Array.include(project.state.category.names, DHIS.util.string.getEncodedString(item[project.state.category.dimension])); Ext.Array.include(project.state.filter.names, DHIS.util.string.getEncodedString(item[project.state.filter.dimension])); item.v = parseFloat(item.v); }); - DHIS.state.state = project.state; - + DHIS.state.state = project.state; DHIS.chart.getData(project); } }); @@ -426,12 +432,13 @@ column: function(project) { project.chart = Ext.create('Ext.chart.Chart', { renderTo: project.state.conf.el, - width: project.state.conf.width || this.el.getWidth(), - height: project.state.conf.height || this.el.getHeight(), + width: DHIS.util.chart.getSize(this, project).width, + height: DHIS.util.chart.getSize(this, project).height, animate: true, store: project.store, - items: DHIS.util.chart.getTitle(), - legend: DHIS.util.chart.getLegend(project.store.left.length), + insetPadding: DHIS.conf.chart.inset, + items: DHIS.util.chart.getTitle(project.state.conf.titlePosition, DHIS.util.chart.getSize(this, project)), + legend: DHIS.util.chart.getLegend(project.state.conf.legendPosition), axes: [ { type: 'Numeric', @@ -474,7 +481,7 @@ animate: true, store: project.store, items: DHIS.util.chart.getTitle(), - legend: DHIS.util.chart.getLegend(project.store.chart.bottom.length), + legend: DHIS.util.chart.getLegend(project.state.conf.legendPosition), axes: [ { type: 'Category', @@ -517,7 +524,7 @@ animate: true, store: project.store, items: DHIS.util.chart.getTitle(), - legend: DHIS.util.chart.getLegend(project.store.chart.left.length), + legend: DHIS.util.chart.getLegend(project.state.conf.legendPosition), axes: [ { type: 'Numeric', @@ -533,7 +540,7 @@ type: 'Category', position: 'bottom', fields: project.store.bottom, - label: DV.util.chart.label.getCategoryLabel() + label: DHIS.util.chart.label.getCategoryLabel() } ], series: DHIS.util.chart.line.getSeriesArray(project) @@ -549,7 +556,7 @@ animate: true, store: project.store, items: DHIS.util.chart.getTitle(), - legend: DHIS.util.chart.getLegend(project.store.chart.left.length), + legend: DHIS.util.chart.getLegend(project.state.conf.legendPosition), axes: [ { type: 'Numeric', @@ -590,13 +597,13 @@ shadow: true, store: project.store, insetPadding: 60, - items: DHIS.util.chart.pie.getTitle(project.state.state.filter.names[0], project.store.left[0]), - legend: DHIS.util.chart.getLegend(project.state.state.category.names.length), + items: DHIS.util.chart.pie.getTitle(project.state.filter.names[0], project.store.left[0]), + legend: DHIS.util.chart.getLegend(project.state.conf.legendPosition), series: [{ type: 'pie', field: project.store.left[0], showInLegend: true, - tips: DHIS.util.chart.pie.getTips(), + tips: DHIS.util.chart.pie.getTips(project.store), label: { field: project.store.bottom[0] }, === added file 'dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonminAggregatedValuesPlugin.vm' --- dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonminAggregatedValuesPlugin.vm 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-visualizer/src/main/webapp/dhis-web-visualizer/jsonminAggregatedValuesPlugin.vm 2011-12-07 14:23:12 +0000 @@ -0,0 +1,1 @@ +#set( $indicatorSize = $indicatorValues.size() )#set( $dataSize = $dataValues.size() )[#if( $indicatorSize > 0 )#foreach( $iv in $indicatorValues )["$!{iv.value}","$!{iv.indicatorName}","$!{iv.periodName}","$!{iv.organisationUnitName}"]#if( $velocityCount < $indicatorSize ),#end#end#end#if( $dataSize > 0 )#if( $indicatorSize > 0 ),#end#foreach( $dv in $dataValues )["$!{dv.value}","$!{dv.dataElementName}","$!{dv.periodName}","$!{dv.organisationUnitName}"]#if( $velocityCount < $dataSize ),#end#end#end] \ No newline at end of file