Home | History | Annotate | Download | only in tko
      1 package autotest.tko;
      2 
      3 import autotest.common.Utils;
      4 import autotest.common.ui.ExtendedListBox;
      5 import autotest.common.ui.NotifyManager;
      6 import autotest.common.ui.TabView;
      7 import autotest.tko.SeriesSelector.Series;
      8 
      9 import com.google.gwt.event.dom.client.ChangeEvent;
     10 import com.google.gwt.event.dom.client.ChangeHandler;
     11 import com.google.gwt.event.dom.client.ClickEvent;
     12 import com.google.gwt.event.dom.client.ClickHandler;
     13 import com.google.gwt.json.client.JSONObject;
     14 import com.google.gwt.json.client.JSONString;
     15 import com.google.gwt.user.client.ui.HorizontalPanel;
     16 import com.google.gwt.user.client.ui.Panel;
     17 import com.google.gwt.user.client.ui.RadioButton;
     18 import com.google.gwt.user.client.ui.TextBox;
     19 import com.google.gwt.user.client.ui.VerticalPanel;
     20 
     21 import java.util.HashMap;
     22 import java.util.List;
     23 import java.util.Map;
     24 
     25 public class MetricsPlotFrontend extends DynamicGraphingFrontend implements ClickHandler {
     26 
     27     public static final String NORMALIZE_SINGLE = "single";
     28     public static final String NORMALIZE_FIRST = "first";
     29     public static final String NORMALIZE_SERIES_PREFIX = "series__";
     30     public static final String NORMALIZE_X_PREFIX = "x__";
     31 
     32     protected FilterSelector globalFilter = new FilterSelector(DBColumnSelector.PERF_VIEW);
     33     private ExtendedListBox plotSelector = new ExtendedListBox();
     34     private ExtendedListBox xAxis = new DBColumnSelector(DBColumnSelector.PERF_VIEW, true);
     35     private RadioButton noNormalizeMultiple =
     36         new RadioButton("normalize", "No normalization (multiple subplots)");
     37     private RadioButton noNormalizeSingle =
     38         new RadioButton("normalize", "No normalization (single plot)");
     39     private RadioButton normalizeFirst = new RadioButton("normalize", "First data point");
     40     private RadioButton normalizeSeries = new RadioButton("normalize", "Specified series:");
     41     private ExtendedListBox normalizeSeriesSelect = new ExtendedListBox();
     42     private RadioButton normalizeX = new RadioButton("normalize", "Specified X-axis value:");
     43     private TextBox normalizeXSelect = new TextBox();
     44     private SeriesSelector seriesSelector = new SeriesSelector(new ChangeHandler() {
     45         public void onChange(ChangeEvent event) {
     46             refreshSeries();
     47         }
     48     });
     49 
     50     public MetricsPlotFrontend(final TabView parent) {
     51         super(parent, new MetricsPlot(), "metrics");
     52 
     53         noNormalizeSingle.setValue(true);
     54 
     55         noNormalizeMultiple.addClickHandler(this);
     56         noNormalizeSingle.addClickHandler(this);
     57         normalizeFirst.addClickHandler(this);
     58         normalizeSeries.addClickHandler(this);
     59         normalizeX.addClickHandler(this);
     60 
     61         normalizeSeriesSelect.setEnabled(false);
     62         normalizeXSelect.setEnabled(false);
     63 
     64         plotSelector.addItem("Line");
     65         plotSelector.addItem("Bar");
     66         plotSelector.addChangeHandler(new ChangeHandler() {
     67             public void onChange(ChangeEvent event) {
     68                 checkNormalizeInput();
     69             }
     70         });
     71 
     72         Panel normalizePanel = new VerticalPanel();
     73         normalizePanel.add(noNormalizeMultiple);
     74         normalizePanel.add(noNormalizeSingle);
     75         Panel seriesPanel = new HorizontalPanel();
     76         seriesPanel.add(normalizeSeries);
     77         seriesPanel.add(normalizeSeriesSelect);
     78         normalizePanel.add(seriesPanel);
     79         normalizePanel.add(normalizeFirst);
     80         Panel baselinePanel = new HorizontalPanel();
     81         baselinePanel.add(normalizeX);
     82         baselinePanel.add(normalizeXSelect);
     83         normalizePanel.add(baselinePanel);
     84 
     85         addControl("Preconfigured:", preconfig);
     86         addControl("Plot:", plotSelector);
     87         addControl("X-axis values:", xAxis);
     88         addControl("Global filters:", globalFilter);
     89         addControl("Series:", seriesSelector);
     90         addControl("Normalize to:", normalizePanel);
     91 
     92         commonInitialization();
     93     }
     94 
     95     @Override
     96     public void onClick(ClickEvent event) {
     97         if (event.getSource() != noNormalizeSingle && event.getSource() != noNormalizeMultiple
     98                 && event.getSource() != normalizeSeries && event.getSource() != normalizeX) {
     99             super.onClick(event);
    100             return;
    101         }
    102 
    103         normalizeSeriesSelect.setEnabled(false);
    104         normalizeXSelect.setEnabled(false);
    105         if (event.getSource() == normalizeSeries) {
    106             normalizeSeriesSelect.setEnabled(true);
    107             refreshSeries();
    108         } else if (event.getSource() == normalizeX) {
    109             normalizeXSelect.setEnabled(true);
    110         }
    111 
    112         checkInvertible();
    113     }
    114 
    115     private void addNormalizeParameter(String plotType, Map<String, String> parameters) {
    116         String normalizationType = null;
    117         if (plotType.equals("Line") && noNormalizeSingle.getValue()) {
    118             normalizationType = NORMALIZE_SINGLE;
    119         } else if (normalizeFirst.getValue()) {
    120             normalizationType = NORMALIZE_FIRST;
    121         } else if (normalizeSeries.getValue()) {
    122             String series = normalizeSeriesSelect.getSelectedValue();
    123             normalizationType = NORMALIZE_SERIES_PREFIX + series;
    124         } else if (normalizeX.getValue()) {
    125             String baseline = normalizeXSelect.getText();
    126             normalizationType = NORMALIZE_X_PREFIX + baseline;
    127         }
    128 
    129         if (normalizationType != null) {
    130             parameters.put("normalize", normalizationType);
    131         }
    132     }
    133 
    134     @Override
    135     public void addToHistory(Map<String, String> args) {
    136         String plot = plotSelector.getValue(plotSelector.getSelectedIndex());
    137         args.put("plot", plot);
    138         args.put("xAxis", xAxis.getSelectedValue());
    139         globalFilter.addToHistory(args, "globalFilter");
    140         seriesSelector.addToHistory(args);
    141         addNormalizeParameter(plot, args);
    142     }
    143 
    144     @Override
    145     public void handleHistoryArguments(Map<String, String> args) {
    146         setVisible(false);
    147         plot.setVisible(false);
    148         embeddingLink.setVisible(false);
    149         globalFilter.reset();
    150         seriesSelector.reset();
    151         for (int i = 0; i < plotSelector.getItemCount(); i++) {
    152             if (plotSelector.getValue(i).equals(args.get("plot"))) {
    153                 plotSelector.setSelectedIndex(i);
    154                 break;
    155             }
    156         }
    157 
    158         xAxis.selectByValue(args.get("xAxis"));
    159         globalFilter.handleHistoryArguments(args, "globalFilter");
    160         seriesSelector.handleHistoryArguments(args);
    161 
    162         refreshSeries();
    163         noNormalizeMultiple.setValue(true);
    164         normalizeSeriesSelect.setEnabled(false);
    165         normalizeXSelect.setEnabled(false);
    166         String normalizeString = args.get("normalize");
    167         if (normalizeString != null) {
    168             if (normalizeString.equals(NORMALIZE_SINGLE)) {
    169                 noNormalizeSingle.setValue(true);
    170             } else if (normalizeString.equals(NORMALIZE_FIRST)) {
    171                 normalizeFirst.setValue(true);
    172             } else if (normalizeString.startsWith(NORMALIZE_SERIES_PREFIX)) {
    173                 normalizeSeries.setValue(true);
    174                 String series = normalizeString.substring(NORMALIZE_SERIES_PREFIX.length());
    175                 for (int i = 0; i < normalizeSeriesSelect.getItemCount(); i++) {
    176                     if (normalizeSeriesSelect.getValue(i).equals(series)) {
    177                         normalizeSeriesSelect.setSelectedIndex(i);
    178                         break;
    179                     }
    180                 }
    181                 normalizeSeriesSelect.setEnabled(true);
    182             } else if (normalizeString.startsWith(NORMALIZE_X_PREFIX)) {
    183                 normalizeX.setValue(true);
    184                 normalizeXSelect.setText(normalizeString.substring(NORMALIZE_X_PREFIX.length()));
    185                 normalizeXSelect.setEnabled(true);
    186             }
    187         }
    188         checkNormalizeInput();
    189         checkInvertible();
    190 
    191         setVisible(true);
    192     }
    193 
    194     @Override
    195     protected void addAdditionalEmbeddingParams(JSONObject params) {
    196         params.put("graph_type", new JSONString("metrics"));
    197         params.put("params", buildParams());
    198     }
    199 
    200     private void refreshSeries() {
    201         String selectedValue = normalizeSeriesSelect.getSelectedValue();
    202         normalizeSeriesSelect.clear();
    203         for (Series selector : seriesSelector.getAllSeries()) {
    204             normalizeSeriesSelect.addItem(selector.getName());
    205             if (selector.getName().equals(selectedValue)) {
    206                 normalizeSeriesSelect.setSelectedIndex(normalizeSeriesSelect.getItemCount() - 1);
    207             }
    208         }
    209     }
    210 
    211     // Disable "No Normalization (multiple)" for bar charts
    212     private void checkNormalizeInput() {
    213         if (plotSelector.getValue(plotSelector.getSelectedIndex()).equals("Line")) {
    214             noNormalizeMultiple.setEnabled(true);
    215         } else {
    216             noNormalizeMultiple.setEnabled(false);
    217             if (noNormalizeMultiple.getValue()) {
    218                 noNormalizeSingle.setValue(true);
    219             }
    220         }
    221     }
    222 
    223     private JSONObject buildQueries() {
    224         List<Series> seriesList = seriesSelector.getAllSeries();
    225         JSONObject queries = new JSONObject();
    226         StringBuilder sql = new StringBuilder();
    227 
    228         sql.append("SELECT ");
    229         sql.append(xAxis.getSelectedValue());
    230         for (Series series : seriesList) {
    231             addSeriesSelects(series, sql);
    232         }
    233 
    234         sql.append(" FROM tko_perf_view_2");
    235 
    236         String xFilterString = globalFilter.getFilterString();
    237         if (xFilterString.equals("")) {
    238             NotifyManager.getInstance().showError("You must enter a global filter");
    239             return null;
    240         }
    241 
    242         sql.append(" WHERE ");
    243         sql.append(xFilterString);
    244 
    245         sql.append(" GROUP BY ");
    246         sql.append(xAxis.getSelectedValue());
    247         queries.put("__main__", new JSONString(sql.toString()));
    248 
    249         for (Series series : seriesList) {
    250             String drilldownQuery = getSeriesDrilldownQuery(series, xFilterString);
    251             queries.put("__" + series.getName() + "__", new JSONString(drilldownQuery));
    252         }
    253 
    254         return queries;
    255     }
    256 
    257     private String getSeriesDrilldownQuery(Series series, String xFilterString) {
    258         StringBuilder sql;
    259         sql = new StringBuilder();
    260         ExtendedListBox valueSelector = series.getDBColumnSelector();
    261 
    262         sql.append("SELECT test_idx, ");
    263         sql.append(valueSelector.getSelectedValue());
    264         sql.append(" FROM tko_perf_view_2 WHERE ");
    265 
    266         String seriesFilter = series.getFilterString();
    267         if (!xFilterString.equals("") || !seriesFilter.equals("")) {
    268             sql.append(xFilterString.replace("%", "%%"));
    269             if (!xFilterString.equals("") && !seriesFilter.equals("")) {
    270                 sql.append(" AND ");
    271             }
    272             sql.append(seriesFilter.replace("%", "%%"));
    273             sql.append(" AND ");
    274         }
    275 
    276         sql.append(xAxis.getSelectedValue());
    277         sql.append(" = %s ORDER BY ");
    278         sql.append(valueSelector.getSelectedValue());
    279         return sql.toString();
    280     }
    281 
    282     private void addSeriesSelects(Series series, StringBuilder sql) {
    283         ExtendedListBox valueSelector = series.getDBColumnSelector();
    284 
    285         StringBuilder ifClause = new StringBuilder();
    286         String seriesFilter = series.getFilterString();
    287         if (!seriesFilter.equals("")) {
    288             ifClause.append("IF(");
    289             ifClause.append(seriesFilter);
    290             ifClause.append(", ");
    291         }
    292         ifClause.append(valueSelector.getSelectedValue());
    293         if (!seriesFilter.equals("")) {
    294             ifClause.append(", NULL)");
    295         }
    296 
    297         sql.append(", ");
    298         sql.append(series.getAggregation());
    299         sql.append(ifClause.toString());
    300         sql.append(") '");
    301         sql.append(series.getName());
    302         sql.append("'");
    303         if (series.wantErrorBars()) {
    304             sql.append(", STDDEV(");
    305             sql.append(ifClause.toString());
    306             sql.append(") 'errors-");
    307             sql.append(series.getName());
    308             sql.append("'");
    309         }
    310     }
    311 
    312     // Disable the "Invert y-axis" checkboxes if inversion doesn't make sense
    313     private void checkInvertible() {
    314         boolean invertible = noNormalizeMultiple.getValue() || normalizeFirst.getValue()
    315                              || normalizeX.getValue();
    316         seriesSelector.setInvertible(invertible);
    317     }
    318 
    319     @Override
    320     protected JSONObject buildParams() {
    321         JSONObject queries = buildQueries();
    322         if (queries == null) {
    323             return null;
    324         }
    325 
    326         Map<String, String> params = new HashMap<String, String>();
    327         String plot = plotSelector.getSelectedValue();
    328         params.put("plot", plot);
    329         addNormalizeParameter(plot, params);
    330 
    331         JSONObject jsonParams = Utils.mapToJsonObject(params);
    332         jsonParams.put("invert", Utils.stringsToJSON(seriesSelector.getInverted()));
    333         jsonParams.put("queries", queries);
    334         return jsonParams;
    335     }
    336 
    337     @Override
    338     public String getFrontendId() {
    339         return "metrics_plot";
    340     }
    341 }
    342