OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2017 The Chromium Authors. All rights reserved. | 3 Copyright 2017 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <script src="/jquery/jquery-2.1.4.min.js"></script> | 8 <script src="/jquery/jquery-2.1.4.min.js"></script> |
9 <script src="/flot/jquery.flot.min.js"></script> | 9 <script src="/flot/jquery.flot.min.js"></script> |
10 <script src="/flot/jquery.flot.crosshair.min.js"></script> | 10 <script src="/flot/jquery.flot.crosshair.min.js"></script> |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 valuesByChange.push([sum / exceptions.length]); | 88 valuesByChange.push([sum / exceptions.length]); |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 // Calculate the chart bounds. | 92 // Calculate the chart bounds. |
93 let lowerBound = 0; | 93 let lowerBound = 0; |
94 let upperBound = 1; | 94 let upperBound = 1; |
95 | 95 |
96 if (anyNumbers) { | 96 if (anyNumbers) { |
97 // Numeric data. Set the bounds based on the data. | 97 // Numeric data. Set the bounds based on the data. |
98 const flatValues = [].concat(...valuesByChange); | 98 // The bounds are the interquartile range of all points, but at the |
99 lowerBound = percentile(flatValues, 0.1); | 99 // same time ensuring that every median point shows up on the graph. |
100 upperBound = percentile(flatValues, 0.9); | 100 const allValues = [].concat(...valuesByChange); |
| 101 const changeMedians = |
| 102 valuesByChange.filter(v => v.length).map(v => percentile(v, 0.5)); |
| 103 lowerBound = |
| 104 Math.min(percentile(allValues, 0.25), Math.min(...changeMedians)); |
| 105 upperBound = |
| 106 Math.max(percentile(allValues, 0.75), Math.max(...changeMedians)); |
101 if (!(isFinite(lowerBound) && isFinite(upperBound))) { | 107 if (!(isFinite(lowerBound) && isFinite(upperBound))) { |
102 lowerBound = 0; | 108 lowerBound = 0; |
103 upperBound = 0; | 109 upperBound = 0; |
104 } | 110 } |
105 if (lowerBound == upperBound) { | 111 if (lowerBound == upperBound) { |
106 lowerBound -= 1; | 112 lowerBound -= 1; |
107 upperBound += 1; | 113 upperBound += 1; |
108 } | 114 } |
109 } | 115 } |
110 | 116 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 function percentile(values, p) { | 221 function percentile(values, p) { |
216 values.sort(function(a, b) {return a - b;}); | 222 values.sort(function(a, b) {return a - b;}); |
217 const index = (values.length - 1) * p; | 223 const index = (values.length - 1) * p; |
218 const lower = Math.floor(index); | 224 const lower = Math.floor(index); |
219 const upper = Math.ceil(index); | 225 const upper = Math.ceil(index); |
220 const weight = index % 1; | 226 const weight = index % 1; |
221 return values[lower] * (1 - weight) + values[upper] * weight; | 227 return values[lower] * (1 - weight) + values[upper] * weight; |
222 } | 228 } |
223 </script> | 229 </script> |
224 </dom-module> | 230 </dom-module> |
OLD | NEW |