package org.activityinfo.ui.client.component.report.view; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.extjs.gxt.ui.client.Style; import com.extjs.gxt.ui.client.data.BaseListLoader; import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.Dialog; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnModel; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import org.activityinfo.i18n.shared.I18N; import org.activityinfo.legacy.client.Dispatcher; import org.activityinfo.legacy.client.type.DateUtilGWTImpl; import org.activityinfo.legacy.client.type.IndicatorNumberFormat; import org.activityinfo.legacy.shared.command.DimensionType; import org.activityinfo.legacy.shared.command.Filter; import org.activityinfo.legacy.shared.reports.content.EntityCategory; import org.activityinfo.legacy.shared.reports.content.PivotTableData; import org.activityinfo.legacy.shared.reports.model.PivotReportElement; import org.activityinfo.legacy.shared.reports.util.DateUtil; import org.activityinfo.ui.client.page.common.Shutdownable; import java.util.ArrayList; import java.util.List; import static org.activityinfo.legacy.shared.reports.model.DateRange.intersection; public class DrillDownEditor implements Shutdownable { private static final DateUtil DATES = new DateUtilGWTImpl(); public static final int WIDTH = 600; public static final int HEIGHT = 500; private Dispatcher dispatcher; private Dialog dialog; private DrillDownProxy proxy; private Grid<DrillDownRow> grid; private ListStore<DrillDownRow> store; // position private int left; private int top; public DrillDownEditor(Dispatcher dispatcher) { this.dispatcher = dispatcher; } private void show() { if (dialog == null) { createDialog(); } store.removeAll(); if (left > 0 && top > 0) { dialog.setPosition(left, top); } dialog.show(); } @Override public void shutdown() { dialog.hide(); } public void drillDown(PivotReportElement element, PivotTableData.Axis row, PivotTableData.Axis column) { // construct our filter from the intersection of rows and columns Filter filter = new Filter(filterFromAxis(row), filterFromAxis(column)); // apply the effective filter final Filter effectiveFilter = new Filter(filter, element.getContent().getEffectiveFilter()); drillDown(effectiveFilter); } public void drillDown(Filter effectiveFilter) { show(); // now query the rows: proxy.setFilter(effectiveFilter); store.getLoader().load(); } private Filter filterFromAxis(PivotTableData.Axis axis) { Filter filter = new Filter(); while (axis != null) { if (axis.getDimension() != null) { if (axis.getDimension().getType() == DimensionType.Date) { filter.setDateRange(intersection(filter.getDateRange(), DATES.rangeFromCategory(axis.getCategory()))); } else if (axis.getCategory() instanceof EntityCategory) { filter.addRestriction(axis.getDimension().getType(), ((EntityCategory) axis.getCategory()).getId()); } } axis = axis.getParent(); } return filter; } private void createDialog() { proxy = new DrillDownProxy(dispatcher); store = new ListStore<>(new BaseListLoader(proxy)); grid = new Grid<>(store, buildColumnModel()); grid.setLoadMask(true); dialog = new Dialog(); dialog.setHeadingText(I18N.CONSTANTS.sites()); dialog.setButtons(Dialog.CLOSE); dialog.setLayout(new FitLayout()); dialog.setSize(WIDTH, HEIGHT); dialog.add(grid); dialog.addListener(Events.Move, new Listener<BaseEvent>() { @Override public void handleEvent(BaseEvent baseEvent) { left = -1; top = -1; } }); } private ColumnModel buildColumnModel() { List<ColumnConfig> config = new ArrayList<>(); config.add(new ColumnConfig("partner", I18N.CONSTANTS.partner(), 100)); config.add(new ColumnConfig("location", I18N.CONSTANTS.location(), 100)); config.add(new ColumnConfig("date", I18N.CONSTANTS.date(), 100)); ColumnConfig indicatorNameColumn = new ColumnConfig("indicator", I18N.CONSTANTS.indicator(), 100); indicatorNameColumn.setHidden(true); config.add(indicatorNameColumn); ColumnConfig valueColumn = new ColumnConfig("value", I18N.CONSTANTS.value(), 100); valueColumn.setNumberFormat(IndicatorNumberFormat.INSTANCE); valueColumn.setAlignment(Style.HorizontalAlignment.RIGHT); config.add(valueColumn); return new ColumnModel(config); } public void setPosition(int left, int top) { this.left = left; this.top = top; } }