package com.sap.opportunity.ui.client;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.extjs.gxt.charts.client.Chart;
import com.extjs.gxt.charts.client.model.ChartModel;
import com.extjs.gxt.charts.client.model.Legend;
import com.extjs.gxt.charts.client.model.Legend.Position;
import com.extjs.gxt.charts.client.model.axis.XAxis;
import com.extjs.gxt.charts.client.model.axis.YAxis;
import com.extjs.gxt.charts.client.model.charts.StackedBarChart;
import com.extjs.gxt.charts.client.model.charts.StackedBarChart.StackValue;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
public class ChartPanel extends LayoutContainer implements ISaveListener {
private ChartModel chartModel;
private final OpportunityServiceAsync oppService = GWT.create(OpportunityService.class);
private AsyncCallback<List<SalesByMonthDTO>> chartCB = new AsyncCallback<List<SalesByMonthDTO>>() {
public void onSuccess(List<SalesByMonthDTO> result) {
statusDisplay.finishRPC();
updateChart(result);
}
public void onFailure(Throwable caught) {
statusDisplay.finishRPC();
statusDisplay.error("Could not get chart data from server.");
GWT.log("Could not get chart data from server.", caught);
}
};
private StackedBarChart chart;
private Chart chartWidget;
private IStatusDisplay statusDisplay;
public ChartPanel(IStatusDisplay status) {
super();
statusDisplay = status;
((ServiceDefTarget) oppService).setServiceEntryPoint("http://localhost:8282/runlet/main/opportunity");
}
@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
ContentPanel cp = new ContentPanel();
cp.setHeading("Open Opportunity Pipeline [$] by Month of Closing Date"
+ " (for all Opps with a closing date in the last 30 or next 150 days)");
cp.setHeight(300);
cp.setFrame(true);
cp.setLayout(new FitLayout());
String url = "main/chart/open-flash-chart.swf";
chartWidget = new Chart(url);
chartModel = createBarChartData();
chartWidget.setChartModel(chartModel);
cp.add(chartWidget);
updateChart();
add(cp);
}
private ChartModel createBarChartData() {
ChartModel cm = new ChartModel();
Legend legend = new Legend(Position.RIGHT);
cm.setLegend(legend);
cm.setBackgroundColour("#eeffee");
cm.setDecimalSeparatorComma(true);
XAxis xa = new XAxis();
xa.setLabels("June 2009", "July 2009", "August 2009", "September 2009");
xa.setGridColour("#AAAAAA");
xa.setColour("#AAAAAA");
cm.setXAxis(xa);
YAxis ya = new YAxis();
ya.setRange(0, 20000);
ya.setSteps(2000);
ya.setGridColour("#AAAAAA");
ya.setColour("#AAAAAA");
cm.setYAxis(ya);
chart = new StackedBarChart();
chart.setTooltip("$#val#");
cm.addChartConfig(chart);
return cm;
}
private void updateChart(List<SalesByMonthDTO> result) {
List<String> labels = new ArrayList<String>(4);
List<StackValue> stack = new ArrayList<StackValue>(3);
chart.set("values", null);
int maxSales = 10;
for (SalesByMonthDTO sbm : result) {
labels.add(sbm.month);
stack.clear();
int thisSales = 0;
for (ExpectedSalesDTO es : sbm.sales) {
String color = "";
if (es.phase.equals("Decision Making")) {
color = "FD7400";
} else if (es.phase.equals("Final Phase")) {
color = "FFE11A";
} else {
color = "BEDB39";
}
thisSales += es.expectedVolume;
stack.add(new StackedBarChart.StackValue(es.expectedVolume, color));
}
maxSales = (thisSales > maxSales) ? thisSales : maxSales;
chart.addStack(stack);
}
// calculate y-Axis max and steps
chartModel.getXAxis().setLabels(labels);
chartModel.getYAxis().setMax(maxSales * 1.1);
float steps = maxSales / 10;
int exp = 1;
while (steps >= 100) {
exp *= 10;
steps = Math.round(steps / 10);
}
steps = steps * exp;
chartModel.getYAxis().setSteps(steps);
chartWidget.setChartModel(chartModel);
}
public void updateChart(Date transactionTime) {
statusDisplay.startRPC();
oppService.getChartData(transactionTime, chartCB);
}
public void updateChart() {
statusDisplay.startRPC();
oppService.getChartData(chartCB);
}
@Override
public void opportunitiesSaved() {
//TODO: one important assumptions here: if we get a save event
// we are sure to show the chart for the current data. changes
// on past data are not possible.
updateChart();
}
}