package er.bugtracker.components.reporting;
import java.text.Format;
import java.util.Enumeration;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import com.webobjects.appserver.WOContext;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSTimestamp;
import er.extensions.foundation.ERXDictionaryUtilities;
import er.grouping.DRCriteria;
import er.grouping.DRGroup;
import er.grouping.DRRecordGroup;
import er.grouping.DRSubMasterCriteria;
import er.grouping.DRValue;
import er.plot.ERPCategoryChart;
import er.plot.ERPPieChart;
public class ChartReport extends Report {
public String currentType;
public ChartConfiguration selectedConfiguration = (ChartConfiguration) CHART_CONFIGURATIONS.lastObject();
public ChartConfiguration currentConfiguration;
public String selectedType = selectedConfiguration.defaultType();
private static NSArray CHART_CONFIGURATIONS = new NSArray(new Object[] {
new PieChartConfiguration(),
new AreaChartConfiguration()
});
public NSArray chartConfigurations() {
return CHART_CONFIGURATIONS;
}
public static interface ChartConfiguration {
public NSArray supportedTypes();
public NSDictionary configuration();
public String componentName();
public Dataset createDataset();
public String defaultType();
}
public static class PieChartConfiguration implements ChartConfiguration {
public NSArray supportedTypes() {
return ERPPieChart.SUPPORTED_TYPES;
}
public NSDictionary configuration() {
return null;
}
public String componentName() {
return ERPPieChart.class.getName();
}
public Dataset createDataset() {
return new ERPPieChart.AccumulatingPieDataset();
}
public String defaultType() {
return "PieChart";
}
}
public static class AreaChartConfiguration implements ChartConfiguration {
public NSArray supportedTypes() {
return ERPCategoryChart.SUPPORTED_TYPES;
}
public NSDictionary configuration() {
return ERXDictionaryUtilities.dictionaryWithObjectsAndKeys(new Object[] {
CategoryLabelPositions.UP_45, "categoryPlot.domainAxis.categoryLabelPositions"
});
}
public String componentName() {
return ERPCategoryChart.class.getName();
}
public Dataset createDataset() {
return new DefaultCategoryDataset();
}
public String defaultType() {
return "StackedAreaChart";
}
}
/**
* Public constructor
* @param context the context
*/
public ChartReport(WOContext context) {
super(context);
}
@Override
public void awake() {
super.awake();
}
public boolean isCurrentTypeSelected() {
return currentType == selectedType;
}
public void selectType() {
selectedType = currentType;
selectedConfiguration = currentConfiguration;
}
public JFreeChart chart() {
// NOTE: AK this is a dummy implementation, because ERPChart.chart will setValueForBinding("chart"), which will
// try to validate the binding, which in turn calls valueForKey("chart"), which would finally choke and call
// handleQueryForUnboundKey if we didn't return null here. Duh.
return null;
}
public void setChart(JFreeChart chart) {
// chart.getCategoryPlot().getDomainAxis().setCategoryLabelPositions();
}
public Dataset dataset(Integer attribTotalKey) {
Dataset dataset = selectedConfiguration.createDataset();
NSArray dataList = model().vList();
NSArray valueList = model().hList();
if(true) {
dataList = model().hList();
valueList = model().vList();
}
DRGroup dayGroup = (DRGroup) dataList.objectAtIndex(0);
DRSubMasterCriteria daySubMasterCriteria = (DRSubMasterCriteria) dayGroup.masterCriteria().subCriteriaList().objectAtIndex(0);
String dayKey = daySubMasterCriteria.keyDesc();
NSArray dayCriterias = dayGroup.sortedCriteriaList();
Format dayFormat = DRCriteria.formatterForFormat(daySubMasterCriteria.format());
NSMutableDictionary coordinates = new NSMutableDictionary();
for(Enumeration en = valueList.objectEnumerator(); en.hasMoreElements();) {
DRGroup mainGroup = (DRGroup)en.nextElement();
DRSubMasterCriteria mainSubMasterCriteria = (DRSubMasterCriteria) mainGroup.masterCriteria().subCriteriaList().lastObject();
String mainKey = mainSubMasterCriteria.keyDesc();
NSArray mainCriterias = mainGroup.sortedCriteriaList();
for (Enumeration values = mainCriterias.objectEnumerator(); values.hasMoreElements();) {
DRCriteria mainCriteria = (DRCriteria)values.nextElement();
String label = (String) mainCriteria.valueDict().objectForKey(mainKey);
coordinates.setObjectForKey(mainCriteria, mainGroup.masterCriteria().keyDesc());
if(!mainCriteria.isTotal()) {
for (Enumeration days = dayCriterias.objectEnumerator(); days.hasMoreElements();) {
DRCriteria dayCriteria = (DRCriteria)days.nextElement();
Object o = dayCriteria.valueDict().objectForKey(dayKey);
if(!dayCriteria.isTotal()) {
// we just want the actual times, not the totals
if(o instanceof NSTimestamp) {
NSTimestamp ts = (NSTimestamp)o;
if(ts != null) {
double value = 0.0D;
String dayLabel = dayFormat.format(ts);
coordinates.setObjectForKey(dayCriteria, dayGroup.masterCriteria().keyDesc());
DRRecordGroup recordGroup = model().recordGroupForCoordinates(coordinates);
if(attribTotalKey != null) {
DRValue drValue = (DRValue) recordGroup.totals().objectForKey(attribTotalKey);
if(drValue != null) {
value = drValue.total();
}
} else {
value = ((Number) recordGroup.rawRecordList().valueForKeyPath(recordGroupTotalToShow())).doubleValue();
}
if(dataset instanceof CategoryDataset) {
((DefaultCategoryDataset)dataset).setValue(value, label, dayLabel);
} else if (dataset instanceof PieDataset) {
((DefaultPieDataset) dataset).setValue(label, value);
} else {
throw new IllegalArgumentException("Neither a Pie nor CategoryDataset");
}
}
} else {
double value = 0.0D;
coordinates.setObjectForKey(dayCriteria, dayGroup.masterCriteria().keyDesc());
DRRecordGroup recordGroup = model().recordGroupForCoordinates(coordinates);
if(attribTotalKey != null) {
DRValue drValue = (DRValue) recordGroup.totals().objectForKey(attribTotalKey);
if(drValue != null) {
value = drValue.total();
}
} else {
value = ((Number) recordGroup.rawRecordList().valueForKeyPath(recordGroupTotalToShow())).doubleValue();
}
if(dataset instanceof CategoryDataset) {
((DefaultCategoryDataset)dataset).setValue(value, label, o.toString());
} else if (dataset instanceof PieDataset) {
((DefaultPieDataset) dataset).setValue(label, value);
} else {
throw new IllegalArgumentException("Neither a Pie nor CategoryDataset");
}
}
}
}
}
}
}
return dataset;
}
public Dataset datasetForAttribute() {
Integer attribTotalKey = Integer.valueOf(model().flatAttributeList().indexOfObject(attrib));
return dataset(attribTotalKey);
}
public Dataset dataset() {
return dataset(null);
}
}