/** * Sencha GXT 3.0.0b - Sencha for GWT * Copyright(c) 2007-2012, Sencha, Inc. * licensing@sencha.com * * http://www.sencha.com/products/gxt/license/ */ package com.sencha.gxt.explorer.client.chart; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.editor.client.Editor.Path; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.sencha.gxt.cell.core.client.NumberCell; import com.sencha.gxt.chart.client.chart.Chart; import com.sencha.gxt.chart.client.chart.Chart.Position; import com.sencha.gxt.chart.client.chart.axis.CategoryAxis; import com.sencha.gxt.chart.client.chart.axis.RadialAxis; import com.sencha.gxt.chart.client.chart.series.BarSeries; import com.sencha.gxt.chart.client.chart.series.Primitives; import com.sencha.gxt.chart.client.chart.series.RadarSeries; import com.sencha.gxt.chart.client.chart.series.SeriesHighlighter; import com.sencha.gxt.chart.client.chart.series.SeriesLabelConfig; import com.sencha.gxt.chart.client.chart.series.SeriesRenderer; import com.sencha.gxt.chart.client.draw.Color; import com.sencha.gxt.chart.client.draw.RGB; import com.sencha.gxt.chart.client.draw.sprite.RectangleSprite; import com.sencha.gxt.chart.client.draw.sprite.Sprite; import com.sencha.gxt.chart.client.draw.sprite.TextSprite; import com.sencha.gxt.chart.client.draw.sprite.TextSprite.TextAnchor; import com.sencha.gxt.chart.client.draw.sprite.TextSprite.TextBaseline; import com.sencha.gxt.core.client.ValueProvider; import com.sencha.gxt.core.client.util.Margins; import com.sencha.gxt.data.shared.LabelProvider; import com.sencha.gxt.data.shared.ListStore; import com.sencha.gxt.data.shared.ModelKeyProvider; import com.sencha.gxt.data.shared.PropertyAccess; import com.sencha.gxt.examples.resources.client.model.Data; import com.sencha.gxt.explorer.client.model.Example.Detail; import com.sencha.gxt.widget.core.client.ContentPanel; import com.sencha.gxt.widget.core.client.FramedPanel; import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer; import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData; import com.sencha.gxt.widget.core.client.container.SimpleContainer; import com.sencha.gxt.widget.core.client.container.VBoxLayoutContainer; import com.sencha.gxt.widget.core.client.container.VBoxLayoutContainer.VBoxLayoutAlign; import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData; import com.sencha.gxt.widget.core.client.event.SortChangeEvent; import com.sencha.gxt.widget.core.client.event.SortChangeEvent.SortChangeHandler; import com.sencha.gxt.widget.core.client.form.FieldLabel; import com.sencha.gxt.widget.core.client.form.NumberPropertyEditor.DoublePropertyEditor; import com.sencha.gxt.widget.core.client.form.SpinnerField; import com.sencha.gxt.widget.core.client.form.TextField; import com.sencha.gxt.widget.core.client.grid.ColumnConfig; import com.sencha.gxt.widget.core.client.grid.ColumnModel; import com.sencha.gxt.widget.core.client.grid.Grid; import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent; import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent.SelectionChangedHandler; @Detail(name = "Dashboard", icon = "dashboard", category = "Charts", classes = Data.class) public class DashboardExample implements IsWidget, EntryPoint { public interface DataPropertyAccess extends PropertyAccess<Data> { ValueProvider<Data, Double> data1(); ValueProvider<Data, Double> data2(); ValueProvider<Data, Double> data3(); ValueProvider<Data, Double> data4(); ValueProvider<Data, Double> data5(); ValueProvider<Data, String> name(); @Path("name") ModelKeyProvider<Data> nameKey(); } private static final DataPropertyAccess dataAccess = GWT.create(DataPropertyAccess.class); private final ListStore<Data> store = new ListStore<Data>(dataAccess.nameKey()); private final ListStore<Data> radarStore = new ListStore<Data>(dataAccess.nameKey()); private final TextField name = new TextField(); private final SpinnerField<Double> price = new SpinnerField<Double>(new DoublePropertyEditor()); private final SpinnerField<Double> revenue = new SpinnerField<Double>(new DoublePropertyEditor()); private final SpinnerField<Double> growth = new SpinnerField<Double>(new DoublePropertyEditor()); private final SpinnerField<Double> product = new SpinnerField<Double>(new DoublePropertyEditor()); private final SpinnerField<Double> market = new SpinnerField<Double>(new DoublePropertyEditor()); private Data currentData; private Chart<Data> radarChart; private final static String[] radarLabels = {"Price", "Revenue %", "Growth %", "Product %", "Market %"}; private final static String[] companies = { "3m Co", "Alcoa Inc", "Altria Group Inc", "American Express Company", "American International Group, Inc.", "AT&T Inc", "Boeing Co.", "Caterpillar Inc.", "Citigroup, Inc.", "E.I. du Pont de Nemours and Company", "Exxon Mobil Corp", "General Electric Company", "General Motors Corporation", "Hewlett-Packard Co", "Honeywell Intl Inc", "Intel Corporation", "International Business Machines", "Johnson & Johnson", "JP Morgan & Chase & Co", "McDonald\"s Corporation", "Merck & Co., Inc.", "Microsoft Corporation", "Pfizer Inc", "The Coca-Cola Company", "The Home Depot, Inc.", "The Procter & Gamble Company", "United Technologies Corporation", "Verizon Communications", "Wal-Mart Stores, Inc."}; @Override public Widget asWidget() { for (int i = 0; i < companies.length; i++) { store.add(new Data(companies[i], Math.random() * 100, Math.random() * 100, Math.random() * 100, Math.random() * 100, Math.random() * 100, 0, 0, 0, 0)); } final Chart<Data> barChart = new Chart<Data>(); barChart.setStore(store); barChart.setShadowChart(true); barChart.setAnimated(true); CategoryAxis<Data, String> catAxis = new CategoryAxis<Data, String>(); catAxis.setPosition(Position.BOTTOM); catAxis.setField(dataAccess.name()); TextSprite rotation = new TextSprite(); rotation.setRotation(270); catAxis.setLabelConfig(rotation); catAxis.setLabelProvider(new LabelProvider<String>() { @Override public String getLabel(String item) { if (item.length() > 8) { return item.substring(0, 8) + "..."; } else { return item; } } }); barChart.addAxis(catAxis); final BarSeries<Data> bar = new BarSeries<Data>(); bar.setYAxisPosition(Position.LEFT); bar.addYField(dataAccess.data1()); SeriesLabelConfig<Data> barLabelConfig = new SeriesLabelConfig<Data>(); rotation = rotation.copy(); rotation.setTextAnchor(TextAnchor.END); rotation.setTextBaseline(TextBaseline.MIDDLE); barLabelConfig.setSpriteConfig(rotation); bar.setLabelConfig(barLabelConfig); bar.addColor(new RGB(148, 174, 10)); bar.setColumn(true); bar.setHighlighter(new SeriesHighlighter() { @Override public void highlight(Sprite sprite) { if (sprite instanceof RectangleSprite) { RectangleSprite bar = (RectangleSprite) sprite; bar.setStroke(new RGB(85, 85, 204)); bar.setStrokeWidth(3); bar.setFill(new RGB("#a2b5ca")); bar.redraw(); } } @Override public void unHighlight(Sprite sprite) { if (sprite instanceof RectangleSprite) { RectangleSprite bar = (RectangleSprite) sprite; bar.setStroke(Color.NONE); bar.setStrokeWidth(0); bar.setFill(new RGB(148, 174, 10)); bar.redraw(); } } }); barChart.addSeries(bar); ContentPanel eastPanel = new ContentPanel(); eastPanel.setHeadingText("Company Details"); eastPanel.addStyleName("white-bg"); VBoxLayoutContainer vbox = new VBoxLayoutContainer(); name.setReadOnly(true); FieldLabel nameLabel = new FieldLabel(name, "Name"); price.setIncrement(1d); price.setMinValue(0d); price.setMaxValue(100d); price.setAllowBlank(false); price.getPropertyEditor().setFormat(NumberFormat.getFormat("0.00")); price.addValueChangeHandler(new ValueChangeHandler<Double>() { @Override public void onValueChange(ValueChangeEvent<Double> event) { if (currentData != null) { Double value = event.getValue(); if (value != null) { int storeIndex = store.indexOf(currentData); currentData.setData1(value); store.update(currentData); bar.drawSeries(); bar.highlight(storeIndex); updateRadarStore(storeIndex); radarChart.redrawChart(); } } } }); FieldLabel priceLabel = new FieldLabel(price, "Price $"); revenue.setIncrement(1d); revenue.setMinValue(0d); revenue.setMaxValue(100d); revenue.setAllowBlank(false); revenue.getPropertyEditor().setFormat(NumberFormat.getFormat("0.00")); revenue.addValueChangeHandler(new ValueChangeHandler<Double>() { @Override public void onValueChange(ValueChangeEvent<Double> event) { if (currentData != null) { Double value = event.getValue(); if (value != null) { int storeIndex = store.indexOf(currentData); currentData.setData2(value); store.update(currentData); updateRadarStore(storeIndex); radarChart.redrawChart(); } } } }); FieldLabel revenueLabel = new FieldLabel(revenue, "Revenue %"); growth.setIncrement(1d); growth.setMinValue(0d); growth.setMaxValue(100d); growth.setAllowBlank(false); growth.getPropertyEditor().setFormat(NumberFormat.getFormat("0.00")); growth.addValueChangeHandler(new ValueChangeHandler<Double>() { @Override public void onValueChange(ValueChangeEvent<Double> event) { if (currentData != null) { Double value = event.getValue(); if (value != null) { int storeIndex = store.indexOf(currentData); currentData.setData3(value); store.update(currentData); updateRadarStore(storeIndex); radarChart.redrawChart(); } } } }); FieldLabel growthLabel = new FieldLabel(growth, "Growth %"); product.setIncrement(1d); product.setMinValue(0d); product.setMaxValue(100d); product.setAllowBlank(false); product.getPropertyEditor().setFormat(NumberFormat.getFormat("0.00")); product.addValueChangeHandler(new ValueChangeHandler<Double>() { @Override public void onValueChange(ValueChangeEvent<Double> event) { if (currentData != null) { Double value = event.getValue(); if (value != null) { int storeIndex = store.indexOf(currentData); currentData.setData4(value); store.update(currentData); updateRadarStore(storeIndex); radarChart.redrawChart(); } } } }); FieldLabel productLabel = new FieldLabel(product, "Product %"); market.setIncrement(1d); market.setMinValue(0d); market.setMaxValue(100d); market.setAllowBlank(false); market.getPropertyEditor().setFormat(NumberFormat.getFormat("0.00")); market.addValueChangeHandler(new ValueChangeHandler<Double>() { @Override public void onValueChange(ValueChangeEvent<Double> event) { if (currentData != null) { Double value = event.getValue(); if (value != null) { int storeIndex = store.indexOf(currentData); currentData.setData5(event.getValue()); store.update(currentData); updateRadarStore(storeIndex); radarChart.redrawChart(); } } } }); FieldLabel marketLabel = new FieldLabel(market, "Market %"); radarChart = createRadar(); vbox.setVBoxLayoutAlign(VBoxLayoutAlign.CENTER); vbox.add(nameLabel); vbox.add(priceLabel); vbox.add(revenueLabel); vbox.add(growthLabel); vbox.add(productLabel); vbox.add(marketLabel); vbox.add(radarChart); eastPanel.add(vbox, new VerticalLayoutData(1, 1, new Margins(20, 0, 0, 0))); ContentPanel centerPanel = new ContentPanel(); centerPanel.setHeadingText("Company Data"); List<ColumnConfig<Data, ?>> columns = new ArrayList<ColumnConfig<Data, ?>>(); columns.add(new ColumnConfig<Data, String>(dataAccess.name(), 120, "Name")); ColumnConfig<Data, Double> priceColumnConfig = new ColumnConfig<Data, Double>(dataAccess.data1(), 75, "Price $"); priceColumnConfig.setCell(new NumberCell<Double>(NumberFormat.getFormat("0.00"))); columns.add(priceColumnConfig); ColumnConfig<Data, Double> revenueColumnConfig = new ColumnConfig<Data, Double>(dataAccess.data2(), 75, "Revenue %"); revenueColumnConfig.setCell(new NumberCell<Double>(NumberFormat.getFormat("0.00"))); columns.add(revenueColumnConfig); ColumnConfig<Data, Double> growthColumnConfig = new ColumnConfig<Data, Double>(dataAccess.data3(), 75, "Growth %"); growthColumnConfig.setCell(new NumberCell<Double>(NumberFormat.getFormat("0.00"))); columns.add(growthColumnConfig); ColumnConfig<Data, Double> productColumnConfig = new ColumnConfig<Data, Double>(dataAccess.data4(), 75, "Product %"); productColumnConfig.setCell(new NumberCell<Double>(NumberFormat.getFormat("0.00"))); columns.add(productColumnConfig); ColumnConfig<Data, Double> marketColumnConfig = new ColumnConfig<Data, Double>(dataAccess.data5(), 75, "Market %"); marketColumnConfig.setCell(new NumberCell<Double>(NumberFormat.getFormat("0.00"))); columns.add(marketColumnConfig); Grid<Data> grid = new Grid<Data>(store, new ColumnModel<Data>(columns)); grid.getSelectionModel().addSelectionChangedHandler(new SelectionChangedHandler<Data>() { @Override public void onSelectionChanged(SelectionChangedEvent<Data> event) { if (event.getSelection().size() > 0) { int index = store.indexOf(event.getSelection().get(0)); if (currentData != null) { bar.unHighlight(store.indexOf(currentData)); currentData = null; } if (index >= 0) { bar.highlight(index); currentData = event.getSelection().get(0); price.setValue(currentData.getData1()); // update radar chart updateRadarStore(index); radarChart.redrawChart(); } } } }); grid.addSortChangeHandler(new SortChangeHandler() { @Override public void onSortChange(SortChangeEvent event) { barChart.redrawChart(); } }); centerPanel.add(grid); BorderLayoutContainer container = new BorderLayoutContainer(); BorderLayoutData centerLayoutData = new BorderLayoutData(); centerLayoutData.setMargins(new Margins(5, 5, 0, 0)); container.setCenterWidget(centerPanel, centerLayoutData); SimpleContainer barChartContainer = new SimpleContainer(); barChartContainer.add(barChart); barChartContainer.setBorders(true); container.setNorthWidget(barChartContainer, new BorderLayoutData(200)); BorderLayoutData eastLayoutData = new BorderLayoutData(330); eastLayoutData.setMargins(new Margins(5, 0, 0, 0)); container.setEastWidget(eastPanel, eastLayoutData); FramedPanel panel = new FramedPanel(); panel.getElement().getStyle().setMargin(10, Unit.PX); panel.setHeadingText("Company Data"); panel.setPixelSize(870, 720); panel.add(container); return panel; } public void onModuleLoad() { RootPanel.get().add(asWidget()); } private Chart<Data> createRadar() { currentData = store.get(0); updateRadarStore(0); final Chart<Data> chart = new Chart<Data>(320, 320); chart.setStore(radarStore); chart.setAnimated(true); chart.setDefaultInsets(50); RadialAxis<Data, String> axis = new RadialAxis<Data, String>(); axis.setCategoryField(dataAccess.name()); axis.setSteps(5); chart.addAxis(axis); RadarSeries<Data> radar = new RadarSeries<Data>(); radar.setYField(dataAccess.data1()); radar.setFill(new RGB(194, 214, 240)); radar.setStrokeWidth(0.5); radar.setLineRenderer(new SeriesRenderer<Data>() { @Override public void spriteRenderer(Sprite sprite, int index, ListStore<Data> store) { sprite.setOpacity(0.5); } }); radar.setShowMarkers(true); Sprite marker = Primitives.circle(0, 0, 4); marker.setFill(new RGB(69, 109, 159)); radar.setMarkerConfig(marker); chart.addSeries(radar); return chart; } private void updateRadarStore(int index) { radarStore.clear(); Data data = store.get(index); name.setValue(data.getName()); radarStore.add(new Data(radarLabels[0], data.getData1(), 0, 0, 0, 0, 0, 0, 0, 0)); price.setValue(data.getData1()); radarStore.add(new Data(radarLabels[1], data.getData2(), 0, 0, 0, 0, 0, 0, 0, 0)); revenue.setValue(data.getData2()); radarStore.add(new Data(radarLabels[2], data.getData3(), 0, 0, 0, 0, 0, 0, 0, 0)); growth.setValue(data.getData3()); radarStore.add(new Data(radarLabels[3], data.getData4(), 0, 0, 0, 0, 0, 0, 0, 0)); product.setValue(data.getData4()); radarStore.add(new Data(radarLabels[4], data.getData5(), 0, 0, 0, 0, 0, 0, 0, 0)); market.setValue(data.getData5()); } }