Skip to content

Instantly share code, notes, and snippets.

@dardison
Created February 24, 2015 16:59
Show Gist options
  • Select an option

  • Save dardison/66417ec9ff59ecdf1675 to your computer and use it in GitHub Desktop.

Select an option

Save dardison/66417ec9ff59ecdf1675 to your computer and use it in GitHub Desktop.
EvolutionChartPanel
package com.asbitec.vbi.framework.client.chart;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.asbitec.vbi.framework.client.dashboard.DimensionModel;
import com.asbitec.vbi.framework.client.dimesions.CategoryConfig;
import com.asbitec.vbi.framework.client.dimesions.DimensionConfig;
import com.asbitec.vbi.framework.client.dimesions.PropertyEditorValueProvider;
import com.asbitec.vbi.framework.client.dimesions.TimeDimension;
import com.asbitec.vbi.framework.client.event.category.MagnitudeSelectionChangedEvent.MagnitudeSelectionChangedHandler;
import com.asbitec.vbi.framework.client.event.panel.ChartTypeChangeEvent.ChartTypeChangeHandler;
import com.asbitec.vbi.framework.client.magnitudes.DoubleMagnitudeConfig;
import com.asbitec.vbi.framework.client.ui.widgets.field.CategorySelectionField;
import com.asbitec.vbi.framework.client.ui.widgets.field.ChartTypeSelectionField;
import com.asbitec.vbi.framework.client.ui.widgets.field.MagnitudeField;
import com.asbitec.vbi.framework.shared.constants.Constant;
import com.asbitec.vbi.framework.shared.model.category.Category;
import com.asbitec.vbi.framework.shared.model.category.CategoryValue;
import com.asbitec.vbi.framework.shared.model.crosstab.CrossTabDTO;
import com.asbitec.vbi.framework.shared.model.crosstab.CrossTabValueDTOProvider;
import com.asbitec.vbi.framework.shared.services.category.EvolutionProcess;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.chart.client.chart.Chart;
import com.sencha.gxt.chart.client.chart.Chart.Position;
import com.sencha.gxt.chart.client.chart.Legend;
import com.sencha.gxt.chart.client.chart.axis.NumericAxis;
import com.sencha.gxt.chart.client.chart.series.AreaSeries;
import com.sencha.gxt.chart.client.chart.series.BarSeries;
import com.sencha.gxt.chart.client.chart.series.LineSeries;
import com.sencha.gxt.chart.client.chart.series.Primitives;
import com.sencha.gxt.chart.client.chart.series.Series;
import com.sencha.gxt.chart.client.chart.series.SeriesToolTipConfig;
import com.sencha.gxt.chart.client.draw.Color;
import com.sencha.gxt.chart.client.draw.Gradient;
import com.sencha.gxt.chart.client.draw.sprite.Sprite;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.grid.SummaryType.MaxSummaryType;
import com.sencha.gxt.widget.core.client.grid.SummaryType.MinSummaryType;
import com.sencha.gxt.widget.core.client.tips.ToolTip;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;
public class EvolutionChartPanel<M extends CrossTabDTO>
extends OneSerieBaseChartPanel<M>{
/**
* Categoria no temporal seleccionada
*/
private CategoryConfig<M, ?> currentCategoryConfig;
/**
* Categoria temporal seleccionada
*/
private CategoryConfig<M, ?> currentTimeCategoryConfig;
/**
* Selector de granularidad (opcional)
*/
private CategorySelectionField<M> timeCategoryField;
private boolean withTimeCategorySelector = false;
/**
* Selector de categoria no temporal (opcional)
*/
private CategorySelectionField<M> categoryField;
private boolean withCategorySelector = false;
/**
* Selector de tipo de grafico
*/
private ChartTypeSelectionField chartTypeField;
private boolean chartTypeChanged = false;
/**
* Define las categorias disponibles
*/
private DimensionConfig<M> dimensionConfig;
/**
* Selector de magnitud (opcional)
*/
private MagnitudeField<M> magnitudeField;
private boolean withMagnitudeSelector = true;
/**
* Define las magnitudes disponibles y la magnitud por defecto
*/
private DimensionModel<M> model;
private String currentMagnitude;
/**
* Tipo de grafico
*/
private ChartType chartType = ChartType.LINE;
private List<CategoryValue<?>> series;
// private CategorySeriesProvider<M, ?> serieProvider;
private AreaSeries<M> area = null;
private BarSeries<M> bar = null;
@SuppressWarnings("rawtypes")
public EvolutionChartPanel(String title,
EvolutionProcess process,
DimensionConfig<M> dimensionConfig,
ListStore<M> store,
ChartType chartType,
DimensionModel<M> model,
Boolean withTimeCategorySelector,
Boolean withMagnitudeSelector,
Boolean withCategorySelector){
super();
// Seteo categoria temporal por defecto
TimeDimension<M> timeDimensionConfig = new TimeDimension<M>();
this.currentTimeCategoryConfig = timeDimensionConfig.findCategoryConfigFor((CategoryValue<?>)process.getSecondCategory());
// Seteo categoria no temporal por defecto
this.currentCategoryConfig = dimensionConfig.findCategoryConfigFor((CategoryValue<?>)process.getCategory());
this.setTitle(title);
this.store = store;
this.model = model;
this.dimensionConfig = dimensionConfig;
this.withToolBar = true;
this.currentMagnitude = this.model.getDefaultMagnitude().getProperty();
if (chartType != null)
this.chartType = chartType;
if (withTimeCategorySelector != null)
this.withTimeCategorySelector = withTimeCategorySelector;
if (withMagnitudeSelector != null)
this.withMagnitudeSelector = withMagnitudeSelector;
if (withCategorySelector != null)
this.withCategorySelector = withCategorySelector;
this.labelProvider = buildLabelProvider(this.currentTimeCategoryConfig);
// this.serieProvider = new CategorySeriesProvider<M, String>(store);
this.series = getSeries();//this.serieProvider.getSeries();
this.buildUI();
}
protected List<CategoryValue<?>> getSeries(){
CrossTabDTO dto=store.get(0);
ArrayList<CategoryValue<?>> list=new ArrayList<CategoryValue<?>>();
if(dto!=null){
for(Category c : dto.getColumns()){
CategoryValue<?> category=(CategoryValue<?>)c;
list.add(category);
}
Collections.sort(list);
}
return list;
}
protected <N extends Comparable<N>> PropertyEditorValueProvider<M, N> buildLabelProvider(CategoryConfig<M, N> config){
PropertyEditorValueProvider<M, N> result=new PropertyEditorValueProvider<M, N>(config.getEditor(), config.getValueProvider());
result.setProperty(config.getCategory().getProperty());
return result;
}
@Override
protected void magnitudeChanged(DoubleMagnitudeConfig<M> magnitude) {
// TODO Auto-generated method stub
}
protected void addAreaYField(AreaSeries<M> area, ValueProvider<M, Double> magnitudeProvider, Color color){
valueAxis.addField(magnitudeProvider);
area.addYField(magnitudeProvider);
area.addColor(color);
}
protected AreaSeries<M> addAreaSerie(Chart<M> chart,
DefaultSerieLabelProvider<M> labelProvider,
boolean highlight){
AreaSeries<M> area=new AreaSeries<M>();
area.setHighlighting(true);
SeriesToolTipConfig<M> toolTip=new SeriesToolTipConfig<M>();
toolTip.setLabelProvider(labelProvider);
area.setToolTipConfig(toolTip);
area.setYAxisPosition(Position.LEFT);
area.setHighlighting(false);
chart.addSeries(area);
return area;
}
@Override
protected void setAxisScale(NumericAxis<M> axis) {
MaxSummaryType<Double> maxSummary=new MaxSummaryType<Double>();
MinSummaryType<Double> minSummary=new MinSummaryType<Double>();
Double rMin=0d;
Double rMax=0d;
boolean first=true;
for(CategoryValue<?> data : this.series){
CrossTabValueDTOProvider<M> provider=new CrossTabValueDTOProvider<M>(data, currentMagnitude);
Double max=maxSummary.calculate(store.getAll(), provider);
Double min=minSummary.calculate(store.getAll(), provider);
if(first){
rMin=min;
rMax=max;
first=false;
}else{
if(min.compareTo(rMin)<0){
rMin=min;
}
if(max.compareTo(rMax)>0){
rMax=max;
}
}
}
NumberLabelProvider provider=new NumberLabelProvider();
provider.setMin(rMin);
provider.setMax(rMax);
axis.setLabelProvider(provider);
/* NiceScale scale=new NiceScale(rMin, rMax);
axis.setMinimum(scale.getNiceMin());
axis.setMaximum(scale.getNiceMax());
axis.setInterval(scale.getTickSpacing());
*/
}
@Override
protected ToolBar buildToolBar(ToolBar toolBar) {
if (withTimeCategorySelector)
toolBar.add(timeCategoryField);
if (withMagnitudeSelector)
toolBar.add(magnitudeField);
if (withCategorySelector)
toolBar.add(categoryField);
return toolBar;
}
@Override
protected void addToolBarButtonsOnRight(ToolBar toolbar) {
toolbar.add(chartTypeField);
}
@Override
protected void reconfigure() {
this.valueAxis.getFields().clear();
this.xAxis.setField(labelProvider);
if (!chartTypeChanged)
removeSeries(chartType);
else
chartTypeChanged = false;
// this.serieProvider = new CategorySeriesProvider<M, String>(store);
this.series=getSeries();//this.serieProvider.getSeries();
this.defineSeries();
this.setAxisScale(valueAxis);
}
private void removeSeries(ChartType type){
if (type == ChartType.LINE){
int size = series.size();
for (int i = size-1; i >= 0; i--) {
this.chart.removeSeries(i);
}
}
if (type == ChartType.AREA && area!=null)
this.chart.removeSeries(area);
if (type == ChartType.BAR && bar!=null)
this.chart.removeSeries(bar);
}
@Override
protected void defineSerie(Chart<M> chart) {
super.defineSerie(chart);
Legend<M> legend=new Legend<M>();
legend.setPosition(Position.BOTTOM);
legend.setItemHighlighting(true);
legend.setItemHiding(true);
legend.getBorderConfig().setStrokeWidth(0);
chart.setLegend(legend);
defineSeries();
}
protected void defineSeries(){
List<Color> colors=this.getRandomColor(this.series.size());
NumberFormat format=NumberFormat.getFormat(Constant.DECIMAL_FORMAT);
final ToolTip newToolTip = new ToolTip((Widget)null);
if (chartType == ChartType.AREA)
area=this.addAreaSerie(chart, new DefaultSerieLabelProvider<M>(format, this.labelProvider), false);
if (chartType == ChartType.BAR)
bar = this.addBarSerie(chart, new DefaultSerieLabelProvider<M>(format, this.labelProvider));
List<String> serieTitles=new ArrayList<String>();
int i = 0;
boolean hasLegends=true;
if(this.series.size()>15)
hasLegends=false;
for(CategoryValue<?> data : this.series){
CrossTabValueDTOProvider<M> provider=new CrossTabValueDTOProvider<M>(data, currentMagnitude);
String legendTitle = data.getValue().toString();//currentCategoryConfig.getEditor().render(data.getValue());
DefaultSerieLabelProvider<M> labelProvider=new DefaultSerieLabelProvider<M>(format, this.labelProvider, legendTitle);
Sprite marker = Primitives.circle(0, 0, 4);
Series<M> serie = null;
if (colors.get(i) instanceof Gradient)
chart.addGradient((Gradient)colors.get(i));
switch (chartType) {
case LINE:
LineSeries<M> line = this.addLineSerie(chart, provider, labelProvider, colors.get(i), marker, newToolTip);
if(hasLegends)
line.setLegendTitle(legendTitle);
serie = line;
break;
case AREA:
addAreaYField(area, provider, colors.get(i));
serieTitles.add(legendTitle);
serie = area;
break;
case BAR:
addBarYField(bar, provider, colors.get(i));
bar.setLegendTitle(legendTitle);
serieTitles.add(legendTitle);
serie = bar;
break;
}
this.setHighlightSerie(serie, colors.get(i));
i++;
}
if (chartType == ChartType.AREA)
area.setLegendTitles(serieTitles);
if (chartType == ChartType.BAR)
bar.setLegendTitles(serieTitles);
}
protected LineSeries<M> addLineSerie(Chart<M> chart,
ValueProvider<M, ? extends Number> magnitudeProvider,
DefaultSerieLabelProvider<M> labelProvider,
Color color,
final ToolTip tooltip){
Sprite marker = Primitives.square(0, 0, 4);
return addLineSerie(chart, magnitudeProvider, labelProvider, color, marker, tooltip);
}
protected LineSeries<M> addLineSerie(Chart<M> chart,
ValueProvider<M, ? extends Number> magnitudeProvider,
DefaultSerieLabelProvider<M> labelProvider,
Color color,
Sprite marker,
final ToolTip tooltip){
valueAxis.addField(magnitudeProvider);
LineSeries<M> serie=new LineSeries<M>(){
{
toolTip = tooltip;
}
};
SeriesToolTipConfig<M> toolTip=new SeriesToolTipConfig<M>();
toolTip.setLabelProvider(labelProvider);
serie.setToolTipConfig(toolTip);
serie.setYAxisPosition(Position.LEFT);
// serie.setXAxisPosition(Position.BOTTOM);
serie.setYField(magnitudeProvider);
serie.setStroke(color);
serie.setShowMarkers(true);
// serie.setFill(color);
marker.setFill(color);
marker.setStroke(color);
serie.setMarkerConfig(marker);
serie.setHighlighting(true);
chart.addSeries(serie);
return serie;
}
protected BarSeries<M> addBarSerie(Chart<M> chart,
DefaultSerieLabelProvider<M> labelProvider){
BarSeries<M> bar=new BarSeries<M>();
bar.setColumn(true);
bar.setHighlighting(true);
SeriesToolTipConfig<M> toolTip=new SeriesToolTipConfig<M>();
toolTip.setLabelProvider(labelProvider);
bar.setToolTipConfig(toolTip);
bar.setYAxisPosition(Position.LEFT);
bar.setHighlighting(false);
chart.addSeries(bar);
return bar;
}
protected void addBarYField(BarSeries<M> bar, ValueProvider<M, ? extends Number> magnitudeProvider, Color color){
valueAxis.addField(magnitudeProvider);
bar.addYField(magnitudeProvider);
bar.addColor(color);
}
@Override
public void highlight(M model) {
// TODO Auto-generated method stub
}
public void setChartType(ChartType chartType) {
this.chartType = chartType;
this.reconfigure();
}
@Override
protected void buildUI() {
final TimeDimension<M> config = new TimeDimension<M>();
this.timeCategoryField=new CategorySelectionField<M>(config);
this.timeCategoryField.setValue(currentTimeCategoryConfig.getValue());
this.categoryField=new CategorySelectionField<M>(this.dimensionConfig);
this.categoryField.setValue(currentCategoryConfig.getValue());
this.magnitudeField = new MagnitudeField<M>(model.getMagnitudes(), model.findMagnitudeConfig(currentMagnitude));
this.chartTypeField = new ChartTypeSelectionField(chartType);
super.buildUI();
}
public void addTimeCategorySelectionHandler(SelectionHandler<CategoryValue<?>> handler){
this.timeCategoryField.addSelectionHandler(handler);
}
public void addCategorySelectionHandler(SelectionHandler<CategoryValue<?>> handler){
this.categoryField.addSelectionHandler(handler);
}
public void addMagnitudeSelectionHandler(MagnitudeSelectionChangedHandler<M> handler){
this.magnitudeField.addMagnitudeSelectionChangedHandler(handler);
}
public void addChartTypeSelectionHandler(ChartTypeChangeHandler handler){
this.chartTypeField.addChartTypeSelectionChangedHandler(handler);
}
@Override
public HandlerRegistration addResizeHandler(ResizeHandler handler) {
return null;
}
public void changeMagnitude(String magnitude){
this.currentMagnitude = magnitude;
repaint();
}
public void changeTimeCategory(CategoryConfig<M, ?> category){
this.labelProvider = buildLabelProvider(category);
repaint();
}
public void changeChartType(ChartType chartType){
removeSeries(this.chartType);
chartTypeChanged = true;
this.chartType = chartType;
repaint();
}
public void repaint(){
this.reconfigure();
this.chart.redrawChart();
this.chart.redrawSurface();
}
public void changeCategory(CategoryConfig<M, ?> category){
repaint();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment