1 /*
2  * Copyright (c) 2016 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.google.common.primitives.Doubles;
21 import com.google.gson.Gson;
22 import com.google.gson.JsonObject;
23 import com.google.gson.JsonPrimitive;
24 import java.util.ArrayList;
25 import java.util.List;
26 import org.apache.commons.math3.stat.descriptive.rank.Percentile;
27 
28 /** Helper object for describing graph data. */
29 public class Histogram extends Graph {
30     public static final String PERCENTILES_KEY = "percentiles";
31     public static final String PERCENTILE_VALUES_KEY = "percentile_values";
32     public static final String MIN_KEY = "min";
33     public static final String MAX_KEY = "max";
34 
35     private List<Double> values;
36     private List<String> ids;
37     private String xLabel;
38     private String yLabel;
39     private String name;
40     private GraphType type = GraphType.HISTOGRAM;
41     private Double min = null;
42     private Double max = null;
43 
Histogram(String name)44     public Histogram(String name) {
45         this.name = name;
46         this.values = new ArrayList<>();
47         this.ids = new ArrayList<>();
48     }
49 
50     /**
51      * Get the x axis label.
52      *
53      * @return The x axis label.
54      */
55     @Override
getXLabel()56     public String getXLabel() {
57         return xLabel;
58     }
59 
60     /**
61      * Get the graph type.
62      *
63      * @return The graph type.
64      */
65     @Override
getType()66     public GraphType getType() {
67         return type;
68     }
69 
70     /**
71      * Get the name of the graph.
72      *
73      * @return The name of the graph.
74      */
75     @Override
getName()76     public String getName() {
77         return name;
78     }
79 
80     /**
81      * Get the y axis label.
82      *
83      * @return The y axis label.
84      */
85     @Override
getYLabel()86     public String getYLabel() {
87         return yLabel;
88     }
89 
90     /**
91      * Get the number of data points stored in the graph.
92      *
93      * @return The number of data points stored in the graph.
94      */
95     @Override
size()96     public int size() {
97         return values.size();
98     }
99 
100     /**
101      * Get the minimum value.
102      *
103      * @return The minimum value.
104      */
getMin()105     public Double getMin() {
106         return min;
107     }
108 
109     /**
110      * Get the maximum value.
111      *
112      * @return The maximum value.
113      */
getMax()114     public Double getMax() {
115         return max;
116     }
117 
118     /**
119      * Add data to the graph.
120      *
121      * @param id The name of the graph.
122      * @param profilingPoint The ProfilingPointRunEntity containing data to add.
123      */
124     @Override
addData(String id, ProfilingPointRunEntity profilingPoint)125     public void addData(String id, ProfilingPointRunEntity profilingPoint) {
126         if (profilingPoint.getValues().size() == 0)
127             return;
128         xLabel = profilingPoint.getXLabel();
129         yLabel = profilingPoint.getYLabel();
130         for (long v : profilingPoint.getValues()) {
131             double value = v;
132             values.add(value);
133             ids.add(id);
134             if (max == null || value > max)
135                 max = value;
136             if (min == null || value < min)
137                 min = value;
138         }
139     }
140 
141     /**
142      * Serializes the graph to json format.
143      *
144      * @return A JsonElement object representing the graph object.
145      */
146     @Override
toJson()147     public JsonObject toJson() {
148         int[] percentiles = {1, 2, 5, 10, 25, 50, 75, 90, 95, 98, 99};
149         double[] percentileValues = new double[percentiles.length];
150         double[] valueList = Doubles.toArray(values);
151         for (int i = 0; i < percentiles.length; i++) {
152             percentileValues[i] =
153                     Math.round(new Percentile().evaluate(valueList, percentiles[i]) * 1000d)
154                     / 1000d;
155         }
156         JsonObject json = super.toJson();
157         json.add(VALUE_KEY, new Gson().toJsonTree(values).getAsJsonArray());
158         json.add(PERCENTILES_KEY, new Gson().toJsonTree(percentiles).getAsJsonArray());
159         json.add(PERCENTILE_VALUES_KEY, new Gson().toJsonTree(percentileValues).getAsJsonArray());
160         json.add(IDS_KEY, new Gson().toJsonTree(ids).getAsJsonArray());
161         json.add(MIN_KEY, new JsonPrimitive(min));
162         json.add(MAX_KEY, new JsonPrimitive(max));
163         return json;
164     }
165 }
166