Index: tracing/tracing/value/histogram.html |
diff --git a/tracing/tracing/value/histogram.html b/tracing/tracing/value/histogram.html |
index 38ea9adbebb4163130463b608f4db00685571273..6a9b4ae398802a830771e5e0477f95fe9b039984 100644 |
--- a/tracing/tracing/value/histogram.html |
+++ b/tracing/tracing/value/histogram.html |
@@ -30,12 +30,14 @@ tr.exportTo('tr.v', function() { |
SIGNIFICANT: 1 |
}; |
- var DEFAULT_BUILDER_FOR_UNIT = new Map(); |
+ var DEFAULT_BOUNDARIES_FOR_UNIT = new Map(); |
class HistogramBin { |
- constructor(parentNumeric, min, max) { |
- this.parentNumeric = parentNumeric; |
- this.range = tr.b.Range.fromExplicitRange(min, max); |
+ /** |
+ * @param {!tr.b.Range} range |
+ */ |
+ constructor(range) { |
+ this.range = range; |
this.count = 0; |
this.diagnosticMaps = []; |
} |
@@ -93,18 +95,19 @@ tr.exportTo('tr.v', function() { |
* Histogram stores a random sample of optional per-sample DiagnosticMaps. |
* Histogram is visualized by <tr-v-ui-histogram-span>, which supports |
* selecting bins, and visualizing the DiagnosticMaps of selected bins. |
+ * |
+ * @param {!tr.v.Unit} unit |
+ * @param {!tr.v.HistogramBinBoundaries=} opt_binBoundaries |
*/ |
class Histogram extends tr.v.NumericBase { |
- constructor(unit, opt_binBounds) { |
+ constructor(unit, opt_binBoundaries) { |
super(unit); |
- var binBounds = opt_binBounds; |
- if (!binBounds) { |
+ var binBoundaries = opt_binBoundaries; |
+ if (!binBoundaries) { |
var baseUnit = unit.baseUnit ? unit.baseUnit : unit; |
- binBounds = DEFAULT_BUILDER_FOR_UNIT.get(baseUnit.unitName).binBounds; |
+ binBoundaries = DEFAULT_BOUNDARIES_FOR_UNIT.get(baseUnit.unitName); |
} |
- if (binBounds.length < 2) |
- throw new Error('Need at least 2 binBounds'); |
this.allBins = []; |
this.centralBins = []; |
@@ -124,15 +127,13 @@ tr.exportTo('tr.v', function() { |
percentile: [] |
}; |
- this.underflowBin = new HistogramBin(this, |
- -Number.MAX_VALUE, binBounds[0]); |
- this.overflowBin = new HistogramBin(this, |
- binBounds[binBounds.length - 1], Number.MAX_VALUE); |
+ this.underflowBin = new HistogramBin(tr.b.Range.fromExplicitRange( |
+ -Number.MAX_VALUE, binBoundaries.minBinBoundary)); |
+ this.overflowBin = new HistogramBin(tr.b.Range.fromExplicitRange( |
+ binBoundaries.maxBinBoundary, Number.MAX_VALUE)); |
- for (var i = 0; i < binBounds.length - 1; ++i) { |
- this.centralBins.push(new HistogramBin( |
- this, binBounds[i], binBounds[i + 1])); |
- } |
+ for (var range of binBoundaries) |
+ this.centralBins.push(new HistogramBin(range)); |
this.allBins.push(this.underflowBin); |
for (var bin of this.centralBins) |
@@ -143,7 +144,9 @@ tr.exportTo('tr.v', function() { |
} |
static fromDict(d) { |
- var n = new Histogram(tr.v.Unit.fromJSON(d.unit), d.binBounds); |
+ var boundaries = HistogramBinBoundaries.createWithBoundaries( |
+ d.binBoundaries); |
+ var n = new Histogram(tr.v.Unit.fromJSON(d.unit), boundaries); |
n.underflowBin.fromDict(d.underflowBin); |
for (var i = 0; i < d.centralBins.length; ++i) |
n.centralBins[i].fromDict(d.centralBins[i]); |
@@ -179,7 +182,8 @@ tr.exportTo('tr.v', function() { |
* @return {!Histogram} |
*/ |
static buildFromSamples(unit, samples) { |
- var result = NumericBuilder.createFromSamples(unit, samples).build(); |
+ var boundaries = HistogramBinBoundaries.createFromSamples(samples); |
+ var result = new Histogram(unit, boundaries); |
result.maxNumSampleValues = 1000; |
// TODO(eakuefner): Propagate diagnosticMaps? |
@@ -441,12 +445,12 @@ tr.exportTo('tr.v', function() { |
return this.sampleValues_; |
} |
- get binBounds() { |
- var bounds = []; |
+ get binBoundaries() { |
+ var boundaries = []; |
for (var bin of this.centralBins) |
- bounds.push(bin.range.min); |
- bounds.push(this.overflowBin.range.min); |
- return bounds; |
+ boundaries.push(bin.range.min); |
+ boundaries.push(this.overflowBin.range.min); |
+ return boundaries; |
} |
clone() { |
@@ -457,10 +461,10 @@ tr.exportTo('tr.v', function() { |
return { |
type: 'numeric', |
unit: this.unit.asJSON(), |
- binBounds: this.binBounds, |
+ binBoundaries: this.binBoundaries, |
underflowBin: this.underflowBin.asDict(), |
- centralBins: this.centralBins.map((bin) => bin.asDict()), |
+ centralBins: this.centralBins.map(bin => bin.asDict()), |
overflowBin: this.overflowBin.asDict(), |
running: this.running.asDict(), |
@@ -509,48 +513,51 @@ tr.exportTo('tr.v', function() { |
* the underflow bin and the first central bin (or the overflow bin if |
* no other boundaries are added later). |
*/ |
- class NumericBuilder { |
+ class HistogramBinBoundaries { |
/** |
- * Create a linearly scaled tr.v.NumericBuilder with |numBins| bins ranging |
- * from |range.min| to |range.max|. |
+ * Create a linearly scaled tr.v.HistogramBinBoundaries with |numBins| bins |
+ * ranging from |min| to |max|. |
* |
- * @param {!tr.v.Unit} unit |
- * @param {!tr.b.Range} range |
+ * @param {number} min |
+ * @param {number} max |
* @param {number} numBins |
- * @return {tr.v.NumericBuilder} |
+ * @return {tr.v.HistogramBinBoundaries} |
*/ |
- static createLinear(unit, range, numBins) { |
- if (range.isEmpty) |
- throw new Error('Range must be non-empty'); |
- |
- return new NumericBuilder(unit, range.min).addLinearBins( |
- range.max, numBins); |
+ static createLinear(min, max, numBins) { |
+ return new HistogramBinBoundaries(min).addLinearBins(max, numBins); |
} |
/** |
- * Create an exponentially scaled tr.v.NumericBuilder with |numBins| bins |
- * ranging from |range.min| to |range.max|. |
+ * Create an exponentially scaled tr.v.HistogramBinBoundaries with |numBins| |
+ * bins ranging from |min| to |max|. |
* |
- * @param {!tr.v.Unit} unit |
- * @param {!tr.b.Range} range |
+ * @param {number} min |
+ * @param {number} max |
* @param {number} numBins |
- * @return {tr.v.NumericBuilder} |
+ * @return {tr.v.HistogramBinBoundaries} |
*/ |
- static createExponential(unit, range, numBins) { |
- if (range.isEmpty) |
- throw new Error('Range must be non-empty'); |
- return new NumericBuilder(unit, range.min).addExponentialBins( |
- range.max, numBins); |
+ static createExponential(min, max, numBins) { |
+ return new HistogramBinBoundaries(min).addExponentialBins(max, numBins); |
} |
- static createFromSamples(unit, samples) { |
+ /** |
+ * @param {Array.<number>} binBoundaries |
+ */ |
+ static createWithBoundaries(binBoundaries) { |
+ var builder = new HistogramBinBoundaries(binBoundaries[0]); |
+ for (var boundary of binBoundaries.slice(1)) |
+ builder.addBinBoundary(boundary); |
+ return builder; |
+ } |
+ |
+ static createFromSamples(samples) { |
var range = new tr.b.Range(); |
// Prevent non-numeric samples from introducing NaNs into the range. |
for (var sample of samples) |
if (!isNaN(Math.max(sample))) |
range.addValue(sample); |
- // NumericBuilder.addLinearBins() requires this. |
+ // HistogramBinBoundaries.addLinearBins() requires this. |
if (range.isEmpty) |
range.addValue(1); |
if (range.min === range.max) |
@@ -559,20 +566,18 @@ tr.exportTo('tr.v', function() { |
// This optimizes the resolution when samples are uniformly distributed |
// (which is almost never the case). |
var numBins = Math.ceil(Math.sqrt(samples.length)); |
- var builder = new NumericBuilder(unit, range.min); |
+ var builder = new HistogramBinBoundaries(range.min); |
builder.addLinearBins(range.max, numBins); |
return builder; |
} |
- constructor(unit, minBinBoundary) { |
- this.unit_ = unit; |
+ /** |
+ * @param {number} minBinBoundary |
+ */ |
+ constructor(minBinBoundary) { |
this.boundaries_ = [minBinBoundary]; |
} |
- get binBounds() { |
- return this.boundaries_; |
- } |
- |
get minBinBoundary() { |
return this.boundaries_[0]; |
} |
@@ -582,6 +587,16 @@ tr.exportTo('tr.v', function() { |
} |
/** |
+ * Yield Ranges of adjacent boundaries. |
+ */ |
+ *[Symbol.iterator]() { |
+ for (var i = 0; i < this.boundaries_.length - 1; ++i) { |
+ yield tr.b.Range.fromExplicitRange( |
+ this.boundaries_[i], this.boundaries_[i + 1]); |
+ } |
+ } |
+ |
+ /** |
* Add a bin boundary |nextMaxBinBoundary| to the builder. |
* |
* This operation effectively corresponds to appending a new central bin |
@@ -686,50 +701,44 @@ tr.exportTo('tr.v', function() { |
return this; |
} |
- |
- /** |
- * Build a tr.v.Histogram from the list of bin boundaries. |
- * |
- * As explained earlier, this method can be called arbitrarily many times |
- * to produce arbitrarily many distinct numerics. |
- */ |
- build() { |
- return new Histogram(this.unit_, this.boundaries_); |
- } |
}; |
- function defineDefaultBuilder(unit, options) { |
- var range = tr.b.Range.fromExplicitRange(options.min, options.max); |
- var builder; |
- if (options.exponential) |
- builder = NumericBuilder.createExponential(unit, range, options.numBins); |
- else |
- builder = NumericBuilder.createLinear(unit, range, options.numBins); |
- DEFAULT_BUILDER_FOR_UNIT.set(unit.unitName, builder); |
- } |
- |
- defineDefaultBuilder(tr.v.Unit.byName.timeDurationInMs, { |
- exponential: true, min: 1e-3, max: 1e6, numBins: 1e2}); |
- defineDefaultBuilder(tr.v.Unit.byName.timeStampInMs, { |
- exponential: false, min: 0, max: 1e10, numBins: 1e3}); |
- defineDefaultBuilder(tr.v.Unit.byName.normalizedPercentage, { |
- exponential: false, min: 0.0, max: 1.0, numBins: 20}); |
- defineDefaultBuilder(tr.v.Unit.byName.sizeInBytes, { |
- exponential: true, min: 1, max: 1e12, numBins: 1e2}); |
- defineDefaultBuilder(tr.v.Unit.byName.energyInJoules, { |
- exponential: true, min: 1e-3, max: 1e2, numBins: 30}); |
- defineDefaultBuilder(tr.v.Unit.byName.powerInWatts, { |
- exponential: true, min: 1e-3, max: 1e2, numBins: 30}); |
- defineDefaultBuilder(tr.v.Unit.byName.unitlessNumber, { |
- exponential: true, min: 1e-3, max: 1e3, numBins: 20}); |
- defineDefaultBuilder(tr.v.Unit.byName.count, { |
- exponential: true, min: 1, max: 1e3, numBins: 20}); |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.timeDurationInMs.unitName, |
+ HistogramBinBoundaries.createExponential(1e-3, 1e6, 1e2)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.timeStampInMs.unitName, |
+ HistogramBinBoundaries.createLinear(0, 1e10, 1e3)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.normalizedPercentage.unitName, |
+ HistogramBinBoundaries.createLinear(0, 1.0, 20)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.sizeInBytes.unitName, |
+ HistogramBinBoundaries.createExponential(1, 1e12, 1e2)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.energyInJoules.unitName, |
+ HistogramBinBoundaries.createExponential(1e-3, 1e3, 50)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.powerInWatts.unitName, |
+ HistogramBinBoundaries.createExponential(1e-3, 1, 50)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.unitlessNumber.unitName, |
+ HistogramBinBoundaries.createExponential(1e-3, 1e3, 50)); |
+ |
+ DEFAULT_BOUNDARIES_FOR_UNIT.set( |
+ tr.v.Unit.byName.count.unitName, |
+ HistogramBinBoundaries.createExponential(1, 1e3, 20)); |
return { |
Significance: Significance, |
- HistogramBin: HistogramBin, |
Histogram: Histogram, |
- NumericBuilder: NumericBuilder, |
+ HistogramBinBoundaries: HistogramBinBoundaries, |
}; |
}); |
</script> |