1 package autotest.tko;
2 
3 import autotest.common.Utils;
4 import autotest.common.ui.ExtendedListBox;
5 
6 import com.google.gwt.event.dom.client.ChangeEvent;
7 import com.google.gwt.event.dom.client.ChangeHandler;
8 import com.google.gwt.event.dom.client.ClickEvent;
9 import com.google.gwt.event.dom.client.ClickHandler;
10 import com.google.gwt.user.client.ui.Anchor;
11 import com.google.gwt.user.client.ui.CheckBox;
12 import com.google.gwt.user.client.ui.Composite;
13 import com.google.gwt.user.client.ui.FlexTable;
14 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
15 import com.google.gwt.user.client.ui.HasVerticalAlignment;
16 import com.google.gwt.user.client.ui.HorizontalPanel;
17 import com.google.gwt.user.client.ui.Panel;
18 import com.google.gwt.user.client.ui.TextBox;
19 import com.google.gwt.user.client.ui.Widget;
20 
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 
28 public class SeriesSelector extends Composite {
29 
30     private FlexTable table = new FlexTable();
31     private ArrayList<Series> series = new ArrayList<Series>();
32     private Anchor addLink = new Anchor("[Add Series]");
33     private boolean enabled = true;
34     private boolean invertible = false;
35     private final ChangeHandler handler;
36 
37     public class Series extends Composite {
38 
39         private FlexTable seriesTable = new FlexTable();
40         private TextBox name = new TextBox();
41         private CheckBox invert = new CheckBox("Invert y-axis");
42         private ExtendedListBox values = new DBColumnSelector(DBColumnSelector.PERF_VIEW);
43         private ExtendedListBox aggregation = new ExtendedListBox();
44         private CheckBox errorBars = new CheckBox();
45         private FilterSelector filter = new FilterSelector(DBColumnSelector.PERF_VIEW);
46         private Anchor deleteLink = new Anchor("Delete Series");
47         private int row;
48 
Series(int aRow)49         private Series(int aRow) {
50             this.row = aRow;
51             deleteLink.addClickHandler(new ClickHandler() {
52                 public void onClick(ClickEvent event) {
53                     if (enabled) {
54                         deleteSeries(row);
55                     }
56                 }
57             });
58 
59             name.addChangeHandler(handler);
60 
61             aggregation.addItem("AVG", "AVG(");
62             aggregation.addItem("COUNT (DISTINCT)", "COUNT(DISTINCT ");
63             aggregation.addItem("MIN", "MIN(");
64             aggregation.addItem("MAX", "MAX(");
65             aggregation.setSelectedIndex(0);
66             aggregation.addChangeHandler(new ChangeHandler() {
67                 public void onChange(ChangeEvent event) {
68                     if (getAggregation().equals("AVG(")) {
69                         errorBars.setEnabled(true);
70                     } else {
71                         errorBars.setEnabled(false);
72                         errorBars.setValue(false);
73                     }
74                 }
75             });
76 
77             errorBars.setText("error bars");
78 
79             Panel aggregationPanel = new HorizontalPanel();
80             aggregationPanel.add(aggregation);
81             aggregationPanel.add(errorBars);
82 
83             addControl("Name:", name);
84             addControl("Values:", values);
85             addControl("Aggregation:", aggregationPanel);
86             addControl("Filters:", filter);
87             seriesTable.getFlexCellFormatter().setVerticalAlignment(
88                     seriesTable.getRowCount() - 1, 0, HasVerticalAlignment.ALIGN_TOP);
89 
90             seriesTable.setWidget(seriesTable.getRowCount() - 1, 2, deleteLink);
91             seriesTable.getFlexCellFormatter().setHorizontalAlignment(
92                     seriesTable.getRowCount() - 1, 2, HasHorizontalAlignment.ALIGN_RIGHT);
93             seriesTable.getFlexCellFormatter().setVerticalAlignment(
94                     seriesTable.getRowCount() - 1, 2, HasVerticalAlignment.ALIGN_BOTTOM);
95 
96             seriesTable.setWidget(0, 2, invert);
97             seriesTable.getFlexCellFormatter().setHorizontalAlignment(
98                     0, 2, HasHorizontalAlignment.ALIGN_RIGHT);
99 
100             initWidget(seriesTable);
101         }
102 
addControl(String text, Widget control)103         private void addControl(String text, Widget control) {
104             TkoUtils.addControlRow(seriesTable, text, control);
105         }
106 
getAggregation()107         public String getAggregation() {
108             return aggregation.getSelectedValue();
109         }
110 
getDBColumnSelector()111         public ExtendedListBox getDBColumnSelector() {
112             return values;
113         }
114 
wantErrorBars()115         public boolean wantErrorBars() {
116             return errorBars.getValue();
117         }
118 
getName()119         public String getName() {
120             return name.getText();
121         }
122 
getFilterString()123         public String getFilterString() {
124             return filter.getFilterString();
125         }
126 
setInverted(boolean isInverted)127         public void setInverted(boolean isInverted) {
128             invert.setValue(isInverted);
129         }
130 
addToHistory(Map<String, String> args, int index)131         public void addToHistory(Map<String, String> args, int index) {
132             args.put(parameterString("name", index), getName());
133             args.put(parameterString("values", index), getDBColumnSelector().getSelectedValue());
134             args.put(parameterString("aggregation", index), aggregation.getSelectedName());
135             args.put(parameterString("errorBars", index), String.valueOf(wantErrorBars()));
136             filter.addToHistory(args, parameterString("seriesFilters", index));
137         }
138 
readHistoryArguments(Map<String, String> args, int index)139         public void readHistoryArguments(Map<String, String> args, int index) {
140             name.setText(args.get(parameterString("name", index)));
141 
142             String valueColumn = args.get(parameterString("values", index));
143             getDBColumnSelector().selectByValue(valueColumn);
144 
145             String aggregationString = args.get(parameterString("aggregation", index));
146             aggregation.selectByName(aggregationString);
147 
148             boolean errorBarsChecked =
149                 Boolean.parseBoolean(args.get(parameterString("errorBars", index)));
150             errorBars.setValue(errorBarsChecked);
151 
152             filter.handleHistoryArguments(args, parameterString("seriesFilters", index));
153         }
154     }
155 
SeriesSelector(ChangeHandler handler)156     public SeriesSelector(ChangeHandler handler) {
157         this.handler = handler;
158 
159         addLink.addClickHandler(new ClickHandler() {
160             public void onClick(ClickEvent event) {
161                 if (enabled) {
162                     addSeries();
163                 }
164             }
165         });
166         table.setWidget(0, 0, addLink);
167         table.setText(0, 1, "");
168 
169         addSeries();
170 
171         initWidget(table);
172     }
173 
getAllSeries()174     public List<Series> getAllSeries() {
175         return Collections.unmodifiableList(series);
176     }
177 
reset()178     public void reset() {
179         for (int i = 0; i < series.size(); i++) {
180             table.removeRow(0);
181         }
182         series.clear();
183         addSeries();
184     }
185 
getInverted()186     public List<String> getInverted() {
187         List<String> inverted = new ArrayList<String>();
188         for (Series s : series) {
189             if (s.invert.getValue()) {
190                 inverted.add(s.getName());
191             }
192         }
193         return inverted;
194     }
195 
setInvertible(boolean invertible)196     public void setInvertible(boolean invertible) {
197         for (Series s : series) {
198             s.invert.setEnabled(invertible);
199             if (!invertible) {
200                 s.invert.setValue(false);
201             }
202         }
203         this.invertible = invertible;
204     }
205 
parameterString(String parameterName, int index)206     private static String parameterString(String parameterName, int index) {
207         return parameterName + "[" + index + "]";
208     }
209 
addToHistory(Map<String, String> args)210     protected void addToHistory(Map<String, String> args) {
211         for (int index = 0; index < series.size(); index++) {
212             series.get(index).addToHistory(args, index);
213         }
214         List<String> inverted = getInverted();
215         if (!inverted.isEmpty()) {
216             args.put("inverted", Utils.joinStrings(",", inverted));
217         }
218     }
219 
handleHistoryArguments(Map<String, String> args)220     protected void handleHistoryArguments(Map<String, String> args) {
221         String invertedString = args.get("inverted");
222         Set<String> inverted = new HashSet<String>();
223         if (invertedString != null) {
224             for (String s : invertedString.split(",")) {
225                 inverted.add(s);
226             }
227         }
228 
229         for (int index = 0; args.get(parameterString("name", index)) != null; index++) {
230             Series thisSeries;
231             if (index == 0) {
232                 thisSeries = series.get(0);
233             } else {
234                 thisSeries = addSeries();
235             }
236 
237             thisSeries.readHistoryArguments(args, index);
238             thisSeries.setInverted(inverted.contains(thisSeries.getName()));
239         }
240     }
241 
addSeries()242     private Series addSeries() {
243         int row = table.getRowCount() - 1;
244         Series nextSeries = new Series(row);
245         nextSeries.invert.setEnabled(invertible);
246         series.add(nextSeries);
247         table.insertRow(row);
248         table.setWidget(row, 0, nextSeries);
249         table.getFlexCellFormatter().setColSpan(row, 0, 2);
250         table.getFlexCellFormatter().setStylePrimaryName(row, 0, "box");
251         return nextSeries;
252     }
253 
deleteSeries(int row)254     private void deleteSeries(int row) {
255         if (series.size() == 1) {
256             reset();
257             return;
258         }
259 
260         series.remove(row);
261         table.removeRow(row);
262         for (int i = row; i < series.size(); i++) {
263             series.get(i).row--;
264         }
265     }
266 }
267