package org.yaac.client.ui;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import org.yaac.client.util.ListBoxUtil;
import org.yaac.client.widget.SortHandler;
import org.yaac.client.widget.SortableColumn;
import org.yaac.client.widget.stat.CountSizeFilterChoice;
import org.yaac.client.widget.stat.CountSizeMultiFilterPanel;
import org.yaac.client.widget.stat.CountSizeSingleFilterPanel;
import org.yaac.client.widget.stat.KindFilterChoice;
import org.yaac.client.widget.stat.KindMultiFilterPanel;
import org.yaac.client.widget.stat.KindSingleFilterPanel;
import com.google.common.collect.ComparisonChain;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DeckPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.DefaultSelectionEventManager;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionModel;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.LegendPosition;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.BarChart;
import com.google.gwt.visualization.client.visualizations.ColumnChart;
import com.google.gwt.visualization.client.visualizations.PieChart;
/**
* @author Max Zhu (thebbsky@gmail.com)
*
*/
// TODO : make chart resizable
// TODO : logScale support?
// TODO : breakdown by property name
public class StatisticsViewImpl extends Composite implements StatisticsView {
private static StatisticsViewImplUiBinder uiBinder = GWT.create(StatisticsViewImplUiBinder.class);
@UiTemplate("StatisticsView.ui.xml")
interface StatisticsViewImplUiBinder extends UiBinder<Widget, StatisticsViewImpl> {
}
private static final String CHART_TYPE_BAR = "bar";
private static final String CHART_TYPE_PIE = "pie";
private static final String CHART_TYPE_COLUMN = "column";
/**
* config panel index for pie chart
*/
private static final Integer CONFIG_IDX_PIE = 0;
/**
* config panel index for bar and column chart
*/
private static final Integer CONFIG_IDX_BAR_COLUMN = 1;
// TODO : i18n
private static final String SELECT_ALL = "[ALL]";
// =============radio button groups used for corresponding filter panels================
private final String NAMESPACE_RADIO_GROUP = "nsg";
private final String PROPERTY_TYPE_RADIO_GROUP = "ptg";
private final String KIND_RADIO_GROUP = "kg";
@UiField
ListBox chartTypeChoice;
@UiField
Element descElem;
/**
* filter by namespace
*/
@UiField
ListBox namespaceChoice;
/**
* filter by kind name
*/
@UiField
ListBox kindChoice;
@UiField
SimplePanel namespaceChart;
@UiField
DeckPanel namespaceChartConfig;
private CountSizeSingleFilterPanel namespaceSingleConfig;
private CountSizeMultiFilterPanel namespaceMultiConfig;
/**
* won't be changed once initialized
*/
@UiField(provided=true)
CellTable<NamespaceBreakdown> namespaceTable;
/**
* selection model, used to render chart
*/
private SelectionModel<NamespaceBreakdown> namespaceSelectionModel;
/**
* sort handler, will not be changed once initialized
*/
private SortHandler<NamespaceBreakdown> namespaceSortHandler;
/**
* display data, keep changing
*/
private List<NamespaceBreakdown> namespaceBreakdownList;
@UiField
SimplePanel propertyTypeChart;
@UiField
DeckPanel propertyTypeChartConfig;
private CountSizeSingleFilterPanel propertyTypeSingleConfig;
private CountSizeMultiFilterPanel propertyTypeMultiConfig;
/**
* won't be changed once initialized
*/
@UiField(provided=true)
CellTable<PropertyTypeBreakdown> propertyTypeTable;
/**
* selection model, used to render chart
*/
private SelectionModel<PropertyTypeBreakdown> propertySelectionModel;
/**
* sort handler, will not be changed once initialized
*/
private SortHandler<PropertyTypeBreakdown> propertySortHandler;
/**
* display data, keep changing
*/
private List<PropertyTypeBreakdown> propertyBreakdownList;
@UiField
SimplePanel kindChart;
@UiField
DeckPanel kindChartConfig;
private KindSingleFilterPanel kindSingleConfig;
private KindMultiFilterPanel kindMultiConfig;
/**
* won't be changed once initialized
*/
@UiField(provided=true)
CellTable<KindBreakdown> kindTable;
/**
* selection model, used to render chart
*/
private SelectionModel<KindBreakdown> kindSelectionModel;
/**
* sort handler, will not be changed once initialized
*/
private SortHandler<KindBreakdown> kindSortHandler;
/**
* display data, keep changing
*/
private List<KindBreakdown> kindBreakdownList;
// activity
private Presenter listener;
@Inject
StatisticsViewImpl() {
// ======init provided UI widgets========
// init namespace table
{
namespaceSortHandler = new SortHandler<NamespaceBreakdown>();
namespaceTable = new CellTable<NamespaceBreakdown>();
namespaceTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
namespaceTable.addColumnSortHandler(namespaceSortHandler);
namespaceTable.setVisibleRange(0, Integer.MAX_VALUE);
namespaceSelectionModel =
new MultiSelectionModel<NamespaceBreakdown>(NamespaceBreakdown.KEY_PROVIDER);
namespaceTable.setSelectionModel(namespaceSelectionModel,
DefaultSelectionEventManager.<NamespaceBreakdown>createCheckboxManager());
namespaceSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
refreshNamespaceChart();
}
});
// checkbox for chart rendering, unsortable
{
Column<NamespaceBreakdown, Boolean> checkColumn = new Column<NamespaceBreakdown, Boolean>(
new CheckboxCell(true, false)) {
@Override
public Boolean getValue(NamespaceBreakdown object) {
return namespaceSelectionModel.isSelected(object);
}
};
//empty nothing
namespaceTable.addColumn(checkColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));
}
// namespace column
{
SortableColumn<NamespaceBreakdown, String> column =
new SortableColumn<NamespaceBreakdown, String>(new TextCell()) {
@Override
public String getValue(NamespaceBreakdown breakdown) {
return breakdown.getNamespace();
}
};
namespaceTable.addColumn(column, "Namespace");
namespaceSortHandler.setComparator(column, new Comparator<NamespaceBreakdown>() {
@Override
public int compare(NamespaceBreakdown o1, NamespaceBreakdown o2) {
return o1.getNamespace().compareTo(o2.getNamespace());
}
});
}
// entity count
{
SortableColumn<NamespaceBreakdown, String> column =
new SortableColumn<NamespaceBreakdown, String>(new TextCell()) {
@Override
public String getValue(NamespaceBreakdown breakdown) {
return breakdown.getCount().toString();
}
};
namespaceTable.addColumn(column, "Count");
namespaceSortHandler.setComparator(column, new Comparator<NamespaceBreakdown>() {
@Override
public int compare(NamespaceBreakdown o1, NamespaceBreakdown o2) {
return o1.getCount().compareTo(o2.getCount());
}
});
}
// entity size
{
SortableColumn<NamespaceBreakdown, String> column =
new SortableColumn<NamespaceBreakdown, String>(new TextCell()) {
@Override
public String getValue(NamespaceBreakdown breakdown) {
return breakdown.getBytes().toString();
}
};
namespaceTable.addColumn(column, "Size(Bytes)");
namespaceSortHandler.setComparator(column, new Comparator<NamespaceBreakdown>() {
@Override
public int compare(NamespaceBreakdown o1, NamespaceBreakdown o2) {
return o1.getBytes().compareTo(o2.getBytes());
}
});
}
}
// init property type table
{
propertySortHandler = new SortHandler<PropertyTypeBreakdown>();
propertyTypeTable = new CellTable<PropertyTypeBreakdown>();
propertyTypeTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
propertyTypeTable.addColumnSortHandler(propertySortHandler);
propertyTypeTable.setVisibleRange(0, Integer.MAX_VALUE);
propertySelectionModel =
new MultiSelectionModel<PropertyTypeBreakdown>(PropertyTypeBreakdown.KEY_PROVIDER);
propertyTypeTable.setSelectionModel(propertySelectionModel,
DefaultSelectionEventManager.<PropertyTypeBreakdown>createCheckboxManager());
propertySelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
refreshPropertyTypeChart();
}
});
// checkbox for chart rendering, unsortable
{
Column<PropertyTypeBreakdown, Boolean> checkColumn = new Column<PropertyTypeBreakdown, Boolean>(
new CheckboxCell(true, false)) {
@Override
public Boolean getValue(PropertyTypeBreakdown object) {
return propertySelectionModel.isSelected(object);
}
};
//empty nothing
propertyTypeTable.addColumn(checkColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));
}
// property type
{
SortableColumn<PropertyTypeBreakdown, String> column =
new SortableColumn<PropertyTypeBreakdown, String>(new TextCell()) {
@Override
public String getValue(PropertyTypeBreakdown property) {
return property.getPropertyType();
}
};
propertyTypeTable.addColumn(column, "Type");
propertySortHandler.setComparator(column, new Comparator<PropertyTypeBreakdown>() {
@Override
public int compare(PropertyTypeBreakdown o1, PropertyTypeBreakdown o2) {
return o1.getPropertyType().compareTo(o2.getPropertyType());
}
});
}
// count
{
SortableColumn<PropertyTypeBreakdown, String> column =
new SortableColumn<PropertyTypeBreakdown, String>(new TextCell()) {
@Override
public String getValue(PropertyTypeBreakdown property) {
return property.getCount().toString();
}
};
propertyTypeTable.addColumn(column, "Count");
propertySortHandler.setComparator(column, new Comparator<PropertyTypeBreakdown>() {
@Override
public int compare(PropertyTypeBreakdown o1, PropertyTypeBreakdown o2) {
return o1.getCount().compareTo(o2.getCount());
}
});
}
// size
{
SortableColumn<PropertyTypeBreakdown, String> column =
new SortableColumn<PropertyTypeBreakdown, String>(new TextCell()) {
@Override
public String getValue(PropertyTypeBreakdown property) {
return property.getBytes().toString();
}
};
propertyTypeTable.addColumn(column, "Size(Bytes)");
propertySortHandler.setComparator(column, new Comparator<PropertyTypeBreakdown>() {
@Override
public int compare(PropertyTypeBreakdown o1, PropertyTypeBreakdown o2) {
return o1.getBytes().compareTo(o2.getBytes());
}
});
}
}
// init kinds table with sorting handlers
{
kindSortHandler = new SortHandler<KindBreakdown>();
kindTable = new CellTable<KindBreakdown>();
kindTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
kindTable.addColumnSortHandler(kindSortHandler);
kindTable.setVisibleRange(0, Integer.MAX_VALUE);
kindSelectionModel =
new MultiSelectionModel<KindBreakdown>(KindBreakdown.KEY_PROVIDER);
kindTable.setSelectionModel(kindSelectionModel,
DefaultSelectionEventManager.<KindBreakdown>createCheckboxManager());
kindSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
refreshKindChart();
}
});
// checkbox for chart rendering, unsortable
{
Column<KindBreakdown, Boolean> checkColumn = new Column<KindBreakdown, Boolean>(
new CheckboxCell(true, false)) {
@Override
public Boolean getValue(KindBreakdown object) {
return kindSelectionModel.isSelected(object);
}
};
//empty nothing
kindTable.addColumn(checkColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));
}
// name column
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getKindName();
}
};
kindTable.addColumn(column, "Name");;
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return arg0.getKindName().compareTo(arg1.getKindName());
}
});
}
// count column for all entitities
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getCount().toString();
}
};
kindTable.addColumn(column, "Count(All)");;
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return arg0.getCount().compareTo(arg1.getCount());
}
});
}
// size all
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getSize().toString();
}
};
kindTable.addColumn(column, "Size(All)");;
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return arg0.getSize().compareTo(arg1.getSize());
}
});
}
// count for root entity
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getRootCount().toString();
}
};
kindTable.addColumn(column, "Count(Root)");
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return ComparisonChain.start().compare(arg0.getRootCount(), arg1.getRootCount()).result();
}
});
}
// size for root entity
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getRootSize().toString();
}
};
kindTable.addColumn(column, "Size(Root)");
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return ComparisonChain.start().compare(arg0.getRootSize(), arg1.getRootSize()).result();
}
});
}
// count for nonroot entity
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getNonRootCount().toString();
}
};
kindTable.addColumn(column, "Count(Non Root)");
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return ComparisonChain.start().compare(
arg0.getNonRootCount(), arg1.getNonRootCount()).result();
}
});
}
// size for nonroot entity
{
SortableColumn<KindBreakdown, String> column =
new SortableColumn<KindBreakdown, String>(new TextCell()) {
@Override
public String getValue(KindBreakdown kind) {
return kind.getNonRootSize().toString();
}
};
kindTable.addColumn(column, "Size(Non Root)");
kindSortHandler.setComparator(column, new Comparator<KindBreakdown>() {
@Override
public int compare(KindBreakdown arg0, KindBreakdown arg1) {
return ComparisonChain.start().compare(
arg0.getNonRootSize(), arg1.getNonRootSize()).result();
}
});
}
}
// init UI binders
initWidget(uiBinder.createAndBindUi(this));
// init chart types
// TODO : use i18n message
chartTypeChoice.addItem("Bar Chart", CHART_TYPE_BAR);
chartTypeChoice.addItem("Pie Chart", CHART_TYPE_PIE);
chartTypeChoice.addItem("Column Chart", CHART_TYPE_COLUMN);
// ================init filter configuration panel===================
// init namespace filters
namespaceSingleConfig = new CountSizeSingleFilterPanel(NAMESPACE_RADIO_GROUP);
namespaceSingleConfig.addOnChangeHandler(new CountSizeSingleFilterPanel.OnChangeHandler() {
@Override
public void onChange(CountSizeFilterChoice val) {
refreshNamespaceChart();
}
});
namespaceMultiConfig = new CountSizeMultiFilterPanel();
namespaceMultiConfig.addOnChangeHandler(new CountSizeMultiFilterPanel.OnChangeHandler() {
@Override
public void onChange(Set<CountSizeFilterChoice> vals) {
refreshNamespaceChart();
}
});
// has to be added in this order
namespaceChartConfig.add(namespaceSingleConfig);
namespaceChartConfig.add(namespaceMultiConfig);
namespaceChartConfig.setAnimationEnabled(true);
namespaceChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN); // bar chart will be selected by default
// init property type filters
propertyTypeSingleConfig = new CountSizeSingleFilterPanel(PROPERTY_TYPE_RADIO_GROUP);
propertyTypeSingleConfig.addOnChangeHandler(new CountSizeSingleFilterPanel.OnChangeHandler() {
@Override
public void onChange(CountSizeFilterChoice val) {
refreshPropertyTypeChart();
}
});
propertyTypeMultiConfig = new CountSizeMultiFilterPanel();
propertyTypeMultiConfig.addOnChangeHandler(new CountSizeMultiFilterPanel.OnChangeHandler() {
@Override
public void onChange(Set<CountSizeFilterChoice> vals) {
refreshPropertyTypeChart();
}
});
// has to be added in this order
propertyTypeChartConfig.add(propertyTypeSingleConfig);
propertyTypeChartConfig.add(propertyTypeMultiConfig);
propertyTypeChartConfig.setAnimationEnabled(true);
propertyTypeChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN); // bar chart will be selected by default
// init kind filters
kindSingleConfig = new KindSingleFilterPanel(KIND_RADIO_GROUP);
kindSingleConfig.addOnChangeHandler(new KindSingleFilterPanel.OnChangeHandler() {
@Override
public void onChange(KindFilterChoice val) {
refreshKindChart();
}
});
kindMultiConfig = new KindMultiFilterPanel();
kindMultiConfig.addOnChangeHandler(new KindMultiFilterPanel.OnChangeHandler() {
@Override
public void onChange(Set<KindFilterChoice> vals) {
refreshKindChart();
}
});
// has to be added in this order
kindChartConfig.add(kindSingleConfig);
kindChartConfig.add(kindMultiConfig);
kindChartConfig.setAnimationEnabled(true);
kindChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN); // bar chart will be selected by default
}
@Override
public void setPresenter(Presenter listener) {
this.listener = listener;
}
private void refreshNamespaceChart() {
VisualizationUtils.loadVisualizationApi(new Runnable() {
@Override
public void run() {
String val = chartTypeChoice.getValue(chartTypeChoice.getSelectedIndex());
// init data provider here instead of constructor to show the loading icon
ListDataProvider<NamespaceBreakdown> namespaceProvider =
new ListDataProvider<NamespaceBreakdown>(namespaceBreakdownList);
namespaceProvider.addDataDisplay(namespaceTable);
namespaceSortHandler.setDataProvider(namespaceProvider);
if (CHART_TYPE_PIE.equals(val)) {
namespaceChart.setWidget(
new PieChart(namespacePieChartDataTable(), namespacePieOptions()));
namespaceChartConfig.showWidget(CONFIG_IDX_PIE);
} else if (CHART_TYPE_BAR.equals(val)) {
namespaceChart.setWidget(new BarChart(namespaceBarColumnChartDataTable(), namespaceBarOptions()));
namespaceChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN);
} else if (CHART_TYPE_COLUMN.equals(val)) {
namespaceChart.setWidget(new ColumnChart(namespaceBarColumnChartDataTable(), namespaceColumnOptions()));
namespaceChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN);
}
}
}, PieChart.PACKAGE);
}
private ColumnChart.Options namespaceColumnOptions() {
ColumnChart.Options options = ColumnChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private BarChart.Options namespaceBarOptions() {
BarChart.Options options = BarChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private PieChart.Options namespacePieOptions() {
PieChart.Options options = PieChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private List<NamespaceBreakdown> selectedNamespaceList() {
List<NamespaceBreakdown> selectedList = new LinkedList<NamespaceBreakdown>();
for (NamespaceBreakdown breakdown : namespaceBreakdownList) {
if (namespaceSelectionModel.isSelected(breakdown)) {
selectedList.add(breakdown);
}
}
// if nothing is selected, then select all records
if (selectedList.isEmpty()) {
selectedList = namespaceBreakdownList;
}
return selectedList;
}
private DataTable namespacePieChartDataTable() {
CountSizeFilterChoice selectedChoice = namespaceSingleConfig.selectedValue();
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Namespace");
if (selectedChoice == CountSizeFilterChoice.COUNT) {
data.addColumn(ColumnType.NUMBER, "Count");
} else {
data.addColumn(ColumnType.NUMBER, "Size");
}
List<NamespaceBreakdown> selectedList = selectedNamespaceList();
data.addRows(selectedList.size());
int rowCount = 0;
for (NamespaceBreakdown breakdown : selectedList) {
data.setValue(rowCount, 0, breakdown.getNamespace());
if (selectedChoice == CountSizeFilterChoice.COUNT) {
data.setValue(rowCount, 1, breakdown.getCount());
} else {
data.setValue(rowCount, 1, breakdown.getBytes());
}
rowCount ++;
}
return data;
}
private DataTable namespaceBarColumnChartDataTable() {
Set<CountSizeFilterChoice> selectedCols = namespaceMultiConfig.selectedValues();
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Namespace");
if (selectedCols.contains(CountSizeFilterChoice.COUNT)) {
data.addColumn(ColumnType.NUMBER, "Count");
}
if (selectedCols.contains(CountSizeFilterChoice.SIZE)) {
data.addColumn(ColumnType.NUMBER, "Size");
}
List<NamespaceBreakdown> selectedList = selectedNamespaceList();
data.addRows(selectedList.size());
int rowCount = 0;
for (NamespaceBreakdown breakdown : selectedList) {
data.setValue(rowCount, 0, breakdown.getNamespace());
int colIdx = 1;
if (selectedCols.contains(CountSizeFilterChoice.COUNT)) {
data.setValue(rowCount, colIdx ++, breakdown.getCount());
}
if (selectedCols.contains(CountSizeFilterChoice.SIZE)) {
data.setValue(rowCount, colIdx ++, breakdown.getBytes());
}
rowCount ++;
}
return data;
}
private void refreshPropertyTypeChart() {
VisualizationUtils.loadVisualizationApi(new Runnable() {
@Override
public void run() {
String val = chartTypeChoice.getValue(chartTypeChoice.getSelectedIndex());
// init data provider here instead of constructor to show the loading icon
ListDataProvider<PropertyTypeBreakdown> propertiesProvider =
new ListDataProvider<PropertyTypeBreakdown>(propertyBreakdownList);
propertiesProvider.addDataDisplay(propertyTypeTable);
propertySortHandler.setDataProvider(propertiesProvider);
if (CHART_TYPE_PIE.equals(val)) {
propertyTypeChart.setWidget(
new PieChart(propertyTypePieChartDataTable(), propertyTypePieOptions()));
propertyTypeChartConfig.showWidget(CONFIG_IDX_PIE);
} else if (CHART_TYPE_BAR.equals(val)) {
propertyTypeChart.setWidget(
new BarChart(propertyTypeBarColumnChartDataTable(), propertyTypeBarOptions()));
propertyTypeChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN);
} else if (CHART_TYPE_COLUMN.equals(val)) {
propertyTypeChart.setWidget(
new ColumnChart(propertyTypeBarColumnChartDataTable(), propertyTypeColumnOptions()));
propertyTypeChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN);
}
}
}, PieChart.PACKAGE);
}
private ColumnChart.Options propertyTypeColumnOptions() {
ColumnChart.Options options = ColumnChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private BarChart.Options propertyTypeBarOptions() {
BarChart.Options options = BarChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private PieChart.Options propertyTypePieOptions() {
PieChart.Options options = PieChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private List<PropertyTypeBreakdown> selectedPropertyTypeList() {
List<PropertyTypeBreakdown> selectedList = new LinkedList<PropertyTypeBreakdown>();
for (PropertyTypeBreakdown breakdown : propertyBreakdownList) {
if (propertySelectionModel.isSelected(breakdown)) {
selectedList.add(breakdown);
}
}
// if nothing is selected, then select all records
if (selectedList.isEmpty()) {
selectedList = propertyBreakdownList;
}
return selectedList;
}
private DataTable propertyTypePieChartDataTable() {
CountSizeFilterChoice selectedChoice = propertyTypeSingleConfig.selectedValue();
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Property Type");
if (selectedChoice == CountSizeFilterChoice.COUNT) {
data.addColumn(ColumnType.NUMBER, "Count");
} else {
data.addColumn(ColumnType.NUMBER, "Size");
}
List<PropertyTypeBreakdown> selectedList = selectedPropertyTypeList();
data.addRows(selectedList.size());
int rowCount = 0;
for (PropertyTypeBreakdown breakdown : selectedList) {
data.setValue(rowCount, 0, breakdown.getPropertyType());
if (selectedChoice == CountSizeFilterChoice.COUNT) {
data.setValue(rowCount, 1, breakdown.getCount());
} else {
data.setValue(rowCount, 1, breakdown.getBytes());
}
rowCount ++;
}
return data;
}
private DataTable propertyTypeBarColumnChartDataTable() {
Set<CountSizeFilterChoice> selectedCols = propertyTypeMultiConfig.selectedValues();
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Property Type");
if (selectedCols.contains(CountSizeFilterChoice.COUNT)) {
data.addColumn(ColumnType.NUMBER, "Count");
}
if (selectedCols.contains(CountSizeFilterChoice.SIZE)) {
data.addColumn(ColumnType.NUMBER, "Size");
}
List<PropertyTypeBreakdown> selectedList = selectedPropertyTypeList();
data.addRows(selectedList.size());
int rowCount = 0;
for (PropertyTypeBreakdown breakdown : selectedList) {
data.setValue(rowCount, 0, breakdown.getPropertyType());
int colIdx = 1;
if (selectedCols.contains(CountSizeFilterChoice.COUNT)) {
data.setValue(rowCount, colIdx ++, breakdown.getCount());
}
if (selectedCols.contains(CountSizeFilterChoice.SIZE)) {
data.setValue(rowCount, colIdx ++, breakdown.getBytes());
}
rowCount ++;
}
return data;
}
private BarChart.Options kindBarOptions() {
BarChart.Options options = BarChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private ColumnChart.Options kindColumnOptions() {
ColumnChart.Options options = ColumnChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private PieChart.Options kindPieOptions() {
PieChart.Options options = PieChart.Options.create();
options.set3D(false);
options.setWidth(400);
options.setHeight(300);
options.setLegend(LegendPosition.LEFT);
return options;
}
private List<KindBreakdown> selectedKindList() {
List<KindBreakdown> selectedList = new LinkedList<KindBreakdown>();
for (KindBreakdown breakdown : kindBreakdownList) {
if (kindSelectionModel.isSelected(breakdown)) {
selectedList.add(breakdown);
}
}
// if nothing is selected, then select all records
if (selectedList.isEmpty()) {
selectedList = kindBreakdownList;
}
return selectedList;
}
private DataTable kindPieChartDataTable() {
KindFilterChoice selectedChoice = kindSingleConfig.selectedValue();
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Name");
switch (selectedChoice) {
case COUNT_ALL :
data.addColumn(ColumnType.NUMBER, "Count(All)");
break;
case SIZE_ALL :
data.addColumn(ColumnType.NUMBER, "Size(All)");
break;
case COUNT_ROOT :
data.addColumn(ColumnType.NUMBER, "Count(Root)");
break;
case SIZE_ROOT :
data.addColumn(ColumnType.NUMBER, "Size(Root)");
break;
case COUNT_NON_ROOT :
data.addColumn(ColumnType.NUMBER, "Count(Non Root)");
break;
case SIZE_NON_ROOT :
data.addColumn(ColumnType.NUMBER, "Size(Non Root)");
break;
}
List<KindBreakdown> selectedList = selectedKindList();
data.addRows(selectedList.size());
int rowCount = 0;
for (KindBreakdown breakdown : selectedList) {
data.setValue(rowCount, 0, breakdown.getKindName());
switch (selectedChoice) {
case COUNT_ALL :
data.setValue(rowCount, 1, breakdown.getCount());
break;
case SIZE_ALL :
data.setValue(rowCount, 1, breakdown.getSize());
break;
case COUNT_ROOT :
data.setValue(rowCount, 1, breakdown.getRootCount());
break;
case SIZE_ROOT :
data.setValue(rowCount, 1, breakdown.getRootSize());
break;
case COUNT_NON_ROOT :
data.setValue(rowCount, 1, breakdown.getNonRootCount());
break;
case SIZE_NON_ROOT :
data.setValue(rowCount, 1, breakdown.getNonRootSize());
break;
}
rowCount ++;
}
return data;
}
private DataTable kindBarColumnChartDataTable() {
Set<KindFilterChoice> selectedCols = kindMultiConfig.selectedValues();
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Name");
if (selectedCols.contains(KindFilterChoice.COUNT_ALL)) {
data.addColumn(ColumnType.NUMBER, "Count(All)");
}
if (selectedCols.contains(KindFilterChoice.SIZE_ALL)) {
data.addColumn(ColumnType.NUMBER, "Size(All)");
}
if (selectedCols.contains(KindFilterChoice.COUNT_ROOT)) {
data.addColumn(ColumnType.NUMBER, "Count(Root)");
}
if (selectedCols.contains(KindFilterChoice.SIZE_ROOT)) {
data.addColumn(ColumnType.NUMBER, "Size(Root)");
}
if (selectedCols.contains(KindFilterChoice.COUNT_NON_ROOT)) {
data.addColumn(ColumnType.NUMBER, "Count(Non Root)");
}
if (selectedCols.contains(KindFilterChoice.SIZE_NON_ROOT)) {
data.addColumn(ColumnType.NUMBER, "Size(Non Root)");
}
List<KindBreakdown> selectedList = selectedKindList();
data.addRows(selectedList.size());
int rowCount = 0;
for (KindBreakdown breakdown : selectedList) {
data.setValue(rowCount, 0, breakdown.getKindName());
int colIdx = 1;
if (selectedCols.contains(KindFilterChoice.COUNT_ALL)) {
data.setValue(rowCount, colIdx ++, breakdown.getCount());
}
if (selectedCols.contains(KindFilterChoice.SIZE_ALL)) {
data.setValue(rowCount, colIdx ++, breakdown.getSize());
}
if (selectedCols.contains(KindFilterChoice.COUNT_ROOT)) {
data.setValue(rowCount, colIdx ++,
breakdown.getRootCount() == null ? 0l : breakdown.getRootCount());
}
if (selectedCols.contains(KindFilterChoice.SIZE_ROOT)) {
data.setValue(rowCount, colIdx ++,
breakdown.getRootSize() == null ? 0l : breakdown.getRootSize());
}
if (selectedCols.contains(KindFilterChoice.COUNT_NON_ROOT)) {
data.setValue(rowCount, colIdx ++,
breakdown.getNonRootCount() == null ? 0l : breakdown.getNonRootCount());
}
if (selectedCols.contains(KindFilterChoice.SIZE_NON_ROOT)) {
data.setValue(rowCount, colIdx ++,
breakdown.getNonRootSize() == null ? 0l : breakdown.getNonRootSize());
}
rowCount ++;
}
return data;
}
@UiHandler("chartTypeChoice")
void onChartTypeChange(ChangeEvent event) {
// refresh all charts
refreshPropertyTypeChart();
refreshNamespaceChart();
refreshKindChart();
}
private void refreshKindChart() {
VisualizationUtils.loadVisualizationApi(new Runnable() {
@Override
public void run() {
String val = chartTypeChoice.getValue(chartTypeChoice.getSelectedIndex());
// init data provider here instead of constructor to show the loading icon
ListDataProvider<KindBreakdown> kindsProvider =
new ListDataProvider<KindBreakdown>(kindBreakdownList);
kindsProvider.addDataDisplay(kindTable);
kindSortHandler.setDataProvider(kindsProvider);
if (CHART_TYPE_PIE.equals(val)) {
kindChart.setWidget(new PieChart(kindPieChartDataTable(), kindPieOptions()));
kindChartConfig.showWidget(CONFIG_IDX_PIE);
} else if (CHART_TYPE_BAR.equals(val)) {
kindChart.setWidget(new BarChart(kindBarColumnChartDataTable(), kindBarOptions()));
kindChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN);
} else if (CHART_TYPE_COLUMN.equals(val)) {
kindChart.setWidget(new ColumnChart(kindBarColumnChartDataTable(), kindColumnOptions()));
kindChartConfig.showWidget(CONFIG_IDX_BAR_COLUMN);
}
}
}, PieChart.PACKAGE);
}
@Override
public void initKindNames(Collection<String> kindNames) {
ListBoxUtil.resetItems(kindChoice, SELECT_ALL, kindNames);
}
@UiHandler("kindChoice")
void onKindChoiceChange(ChangeEvent event) {
onFilterChange();
}
@Override
public void initNamespaceNames(Collection<String> namespaceNames) {
ListBoxUtil.resetItems(namespaceChoice, SELECT_ALL, namespaceNames);
}
@UiHandler("namespaceChoice")
void onNamespaceChoiceChange(ChangeEvent event) {
onFilterChange();
}
private void onFilterChange() {
String selectedNamespace = ListBoxUtil.selectedVal(namespaceChoice);
String selectedKind = ListBoxUtil.selectedVal(kindChoice);
this.listener.onFilterChange(selectedNamespace, selectedKind);
}
@Override
public void updateSummary(Summary summary) {
// TODO : i18n
String desc = "Last updated " + summary.getDate().toString() + ", total number of entities " + summary.getNoEntities()
+ ", size of all entities " + summary.getSizeEntities();
descElem.setInnerHTML(SafeHtmlUtils.fromString(desc).asString());
}
@Override
public void updateNamespaceBreakdown(List<NamespaceBreakdown> breakdownList) {
// update namespaceTable
this.namespaceBreakdownList = breakdownList;
// update chart
refreshNamespaceChart();
}
@Override
public void updatePropertyTypeBreakdown(List<PropertyTypeBreakdown> breakdownList) {
// update table
this.propertyBreakdownList = breakdownList;
// update chart
refreshPropertyTypeChart();
}
@Override
public void updateKindBreakdown(List<KindBreakdown> breakdownList) {
this.kindBreakdownList = breakdownList;
// update chart
refreshKindChart();
}
}