1 /* 2 * Copyright (c) 2017 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you 5 * may not use this file except in compliance with the License. You may 6 * obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 * implied. See the License for the specific language governing 14 * permissions and limitations under the License. 15 */ 16 17 package com.android.vts.util; 18 19 import com.android.vts.entity.ProfilingPointRunEntity; 20 import com.android.vts.proto.VtsReportMessage; 21 import com.google.gson.Gson; 22 import com.google.gson.JsonObject; 23 import java.util.ArrayList; 24 import java.util.Comparator; 25 import java.util.HashMap; 26 import java.util.HashSet; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Set; 30 31 /** Helper object for describing time-series box plot data. */ 32 public class BoxPlot extends Graph { 33 private static final String LABEL_KEY = "label"; 34 private static final String SERIES_KEY = "seriesList"; 35 private static final String MEAN_KEY = "mean"; 36 private static final String STD_KEY = "std"; 37 private static final String COUNT_KEY = "count"; 38 39 private static final String DAY = "Day"; 40 41 private final GraphType type = GraphType.BOX_PLOT; 42 private final String name; 43 private final String xLabel; 44 private final String yLabel; 45 private final Map<String, Map<String, StatSummary>> labelSeriesMap; 46 private final Set<String> seriesSet; 47 48 private int count; 49 private List<String> labels; 50 BoxPlot(String name, String xLabel, String yLabel)51 public BoxPlot(String name, String xLabel, String yLabel) { 52 this.name = name; 53 this.xLabel = xLabel == null ? DAY : xLabel; 54 this.yLabel = yLabel; 55 this.count = 0; 56 this.labelSeriesMap = new HashMap<>(); 57 this.seriesSet = new HashSet<>(); 58 this.labels = new ArrayList<>(); 59 } 60 61 /** 62 * Get the x axis label. 63 * 64 * @return The x axis label. 65 */ 66 @Override getXLabel()67 public String getXLabel() { 68 return xLabel; 69 } 70 71 /** 72 * Get the graph type. 73 * 74 * @return The graph type. 75 */ 76 @Override getType()77 public GraphType getType() { 78 return type; 79 } 80 81 /** 82 * Get the name of the graph. 83 * 84 * @return The name of the graph. 85 */ 86 @Override getName()87 public String getName() { 88 return name; 89 } 90 91 /** 92 * Get the y axis label. 93 * 94 * @return The y axis label. 95 */ 96 @Override getYLabel()97 public String getYLabel() { 98 return yLabel; 99 } 100 101 /** 102 * Get the number of data points stored in the graph. 103 * 104 * @return The number of data points stored in the graph. 105 */ 106 @Override size()107 public int size() { 108 return this.count; 109 } 110 111 /** 112 * Add data to the graph. 113 * 114 * @param label The name of the category. 115 * @param profilingPoint The ProfilingPointRunEntity containing data to add. 116 */ 117 @Override addData(String label, ProfilingPointRunEntity profilingPoint)118 public void addData(String label, ProfilingPointRunEntity profilingPoint) { 119 StatSummary stat = 120 new StatSummary( 121 label, VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE); 122 for (long value : profilingPoint.getValues()) { 123 stat.updateStats(value); 124 } 125 addSeriesData(label, "", stat); 126 } 127 addSeriesData(String label, String series, StatSummary stats)128 public void addSeriesData(String label, String series, StatSummary stats) { 129 if (!labelSeriesMap.containsKey(label)) { 130 labelSeriesMap.put(label, new HashMap<>()); 131 } 132 Map<String, StatSummary> seriesMap = labelSeriesMap.get(label); 133 seriesMap.put(series, stats); 134 seriesSet.add(series); 135 count += stats.getCount(); 136 } 137 setLabels(List<String> labels)138 public void setLabels(List<String> labels) { 139 this.labels = labels; 140 } 141 142 /** 143 * Serializes the graph to json format. 144 * 145 * @return A JsonElement object representing the graph object. 146 */ 147 @Override toJson()148 public JsonObject toJson() { 149 JsonObject json = super.toJson(); 150 List<JsonObject> stats = new ArrayList<>(); 151 List<String> seriesList = new ArrayList<>(seriesSet); 152 seriesList.sort(Comparator.naturalOrder()); 153 for (String label : labels) { 154 JsonObject statJson = new JsonObject(); 155 String boxLabel = label; 156 List<JsonObject> statList = new ArrayList<>(seriesList.size()); 157 Map<String, StatSummary> seriesMap = labelSeriesMap.get(label); 158 for (String series : seriesList) { 159 JsonObject statSummary = new JsonObject(); 160 Double mean = null; 161 Double std = null; 162 Integer count = null; 163 if (seriesMap.containsKey(series) && seriesMap.get(series).getCount() > 0) { 164 StatSummary stat = seriesMap.get(series); 165 mean = stat.getMean(); 166 std = 0.; 167 if (stat.getCount() > 1) { 168 std = stat.getStd(); 169 } 170 count = stat.getCount(); 171 } 172 statSummary.addProperty(MEAN_KEY, mean); 173 statSummary.addProperty(STD_KEY, std); 174 statSummary.addProperty(COUNT_KEY, count); 175 statList.add(statSummary); 176 } 177 statJson.addProperty(LABEL_KEY, boxLabel); 178 statJson.add(VALUE_KEY, new Gson().toJsonTree(statList)); 179 stats.add(statJson); 180 } 181 json.add(VALUE_KEY, new Gson().toJsonTree(stats)); 182 json.add(SERIES_KEY, new Gson().toJsonTree(seriesList)); 183 return json; 184 } 185 } 186