add percentile information if available
This commit is contained in:
@@ -19,6 +19,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
|
|||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import {MatProgressBarModule} from '@angular/material/progress-bar';
|
import {MatProgressBarModule} from '@angular/material/progress-bar';
|
||||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
|
||||||
|
import {MatRadioModule} from '@angular/material/radio';
|
||||||
import {MatSnackBarModule} from '@angular/material/snack-bar';
|
import {MatSnackBarModule} from '@angular/material/snack-bar';
|
||||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||||
import { YAxisDefinitionComponent } from './y-axis-definition/y-axis-definition.component';
|
import { YAxisDefinitionComponent } from './y-axis-definition/y-axis-definition.component';
|
||||||
@@ -56,6 +57,7 @@ import { ImageToggleComponent } from './image-toggle/image-toggle.component';
|
|||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
|
MatRadioModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
|
<mat-radio-group [(ngModel)]="valueFormat" aria-label="Value format">
|
||||||
|
<mat-radio-button value="time">Time</mat-radio-button>
|
||||||
|
<mat-radio-button value="numbers">Numbers</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
|
||||||
<table class="gallery-item-details">
|
<table class="gallery-item-details">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Values</th>
|
<th>Values</th>
|
||||||
<th>Avg</th>
|
<th>Avg</th>
|
||||||
|
<td *ngFor="let label of percentilesToPlot.keys()">{{label}}</td>
|
||||||
|
<td>Max</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngFor="let stat of stats.dataSeriesStats">
|
<tr *ngFor="let stat of stats.dataSeriesStats">
|
||||||
<td>{{ stat.name }}</td>
|
<td>{{ stat.name }}</td>
|
||||||
<td><div class="{{ pointTypeClass(stat.dashTypeAndColor) }}" title="{{ stat.name }}"></div></td>
|
<td><div class="{{ pointTypeClass(stat.dashTypeAndColor) }}" title="{{ stat.name }}"></div></td>
|
||||||
<td>{{ stat.values }}</td>
|
<td>{{ stat.values }}</td>
|
||||||
<td>{{ utils.formatMs(stat.average) }}</td>
|
<td>{{ utils.format(stat.average, valueFormat) }}</td>
|
||||||
|
<td *ngFor="let key of percentilesToPlot.keys()">{{utils.format(stat.percentiles[percentilesToPlot.get(key)], valueFormat)}}</td>
|
||||||
|
<td>{{ utils.format(stat.maxValue, valueFormat)}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<div *ngIf="stats.dataSeriesStats.length > 1">
|
||||||
|
<h2>Compare Averages</h2>
|
||||||
<table class="gallery-item-details-matrix">
|
<table class="gallery-item-details-matrix">
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
@@ -26,3 +37,23 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h2>Compare Percentiles</h2>
|
||||||
|
<div *ngFor="let p of percentilesToPlot.keys()">
|
||||||
|
<h3>{{p}} percentile</h3>
|
||||||
|
<table class="gallery-item-details-matrix">
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th *ngFor="let statsCol of stats.dataSeriesStats">
|
||||||
|
<div class="{{ pointTypeClass(statsCol.dashTypeAndColor) }}" title="{{ statsCol.name }}"></div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr *ngFor="let statsRow of stats.dataSeriesStats">
|
||||||
|
<td><div class="{{ pointTypeClass(statsRow.dashTypeAndColor) }}" title="{{ statsRow.name }}"></div></td>
|
||||||
|
<td *ngFor="let statsCol of stats.dataSeriesStats">
|
||||||
|
{{ utils.toPercent(statsRow.percentiles[percentilesToPlot.get(p)] / statsCol.percentiles[percentilesToPlot.get(p)]) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -28,3 +28,8 @@
|
|||||||
.plot-details-plotType_e51e10 {background-position-y: -40px;}
|
.plot-details-plotType_e51e10 {background-position-y: -40px;}
|
||||||
.plot-details-plotType_57a1c2 {background-position-y: -48px;}
|
.plot-details-plotType_57a1c2 {background-position-y: -48px;}
|
||||||
.plot-details-plotType_bd36c2 {background-position-y: -56px;}
|
.plot-details-plotType_bd36c2 {background-position-y: -56px;}
|
||||||
|
|
||||||
|
|
||||||
|
.gallery-item-details td {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
@@ -12,10 +12,38 @@ export class PlotDetailsComponent {
|
|||||||
@Input()
|
@Input()
|
||||||
stats: PlotResponseStats;
|
stats: PlotResponseStats;
|
||||||
|
|
||||||
|
hasPercentiles = false;
|
||||||
|
|
||||||
|
valueFormat = "time";
|
||||||
|
|
||||||
|
percentilesToPlot : Map<string,string> = new Map();
|
||||||
|
|
||||||
constructor(public utils: UtilService){
|
constructor(public utils: UtilService){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.hasPercentiles = false;
|
||||||
|
this.percentilesToPlot.clear();
|
||||||
|
for (let i = 0; i < this.stats.dataSeriesStats.length; i++)
|
||||||
|
{
|
||||||
|
const stat = this.stats.dataSeriesStats[i];
|
||||||
|
if (stat.percentiles.hasOwnProperty("50.000"))
|
||||||
|
{
|
||||||
|
this.hasPercentiles = true;
|
||||||
|
this.percentilesToPlot.set('median','50.000');
|
||||||
|
this.percentilesToPlot.set('75th','75.000');
|
||||||
|
this.percentilesToPlot.set('95th','95.000');
|
||||||
|
this.percentilesToPlot.set('99th','99.000');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
percentile(value: number): string {
|
||||||
|
return this.utils.format(value, this.valueFormat);
|
||||||
|
}
|
||||||
|
|
||||||
pointTypeClass(typeAndColor: DashTypeAndColor): string {
|
pointTypeClass(typeAndColor: DashTypeAndColor): string {
|
||||||
return "plot-details-plotType"
|
return "plot-details-plotType"
|
||||||
+" plot-details-plotType_"+typeAndColor.pointType
|
+" plot-details-plotType_"+typeAndColor.pointType
|
||||||
|
|||||||
@@ -19,4 +19,5 @@ img {
|
|||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
box-shadow: 5px 5px 10px 0px #e0e0e0;
|
box-shadow: 5px 5px 10px 0px #e0e0e0;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
@@ -249,6 +249,7 @@ export class DataSeriesStats {
|
|||||||
average : number;
|
average : number;
|
||||||
plottedValues : number;
|
plottedValues : number;
|
||||||
dashTypeAndColor: DashTypeAndColor;
|
dashTypeAndColor: DashTypeAndColor;
|
||||||
|
percentiles: Map<string, number>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DashTypeAndColor {
|
export class DashTypeAndColor {
|
||||||
|
|||||||
@@ -9,6 +9,14 @@ export class UtilService {
|
|||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
format(value: number, type: string) {
|
||||||
|
if (type == "time"){
|
||||||
|
return this.formatMs(value);
|
||||||
|
} else {
|
||||||
|
return ""+value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
formatMs(valueInMs):string {
|
formatMs(valueInMs):string {
|
||||||
const ms = Math.floor(valueInMs % 1000);
|
const ms = Math.floor(valueInMs % 1000);
|
||||||
const s = Math.floor((valueInMs / 1000) % 60);
|
const s = Math.floor((valueInMs / 1000) % 60);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#filters {
|
#filters {
|
||||||
grid-area: filters;
|
grid-area: filters;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
#filterpanel {
|
#filterpanel {
|
||||||
background-color: #f8f8f8;/*#fafafa;*/
|
background-color: #f8f8f8;/*#fafafa;*/
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.lucares.pdb.plot.api;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.lucares.pdb.api.Tags;
|
import org.lucares.pdb.api.Tags;
|
||||||
@@ -27,4 +28,15 @@ public class AggregatorCollection {
|
|||||||
return Optional.ofNullable(aggregators.get(type));
|
return Optional.ofNullable(aggregators.get(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends CustomAggregator> Optional<T> getAggregator(final Class<T> aggregatorType) {
|
||||||
|
|
||||||
|
for (final CustomAggregator aggregator : aggregators.values()) {
|
||||||
|
if (Objects.equals(aggregator.getClass(), aggregatorType)) {
|
||||||
|
return Optional.of((T) aggregator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import java.io.OutputStreamWriter;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.lucares.collections.LongLongConsumer;
|
import org.lucares.collections.LongLongConsumer;
|
||||||
import org.lucares.collections.LongLongHashMap;
|
import org.lucares.collections.LongLongHashMap;
|
||||||
@@ -24,7 +24,7 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
|||||||
|
|
||||||
private long maxValue = 0;
|
private long maxValue = 0;
|
||||||
|
|
||||||
private final LinkedHashMap<Double, Long> percentiles = new LinkedHashMap<>(POINTS);
|
private final Percentiles percentiles = new Percentiles(POINTS);
|
||||||
|
|
||||||
private final double stepSize;
|
private final double stepSize;
|
||||||
|
|
||||||
@@ -49,7 +49,8 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
|||||||
if (newPercentile >= nextPercentile) {
|
if (newPercentile >= nextPercentile) {
|
||||||
double currentPercentile = lastPercentile + stepSize;
|
double currentPercentile = lastPercentile + stepSize;
|
||||||
while (currentPercentile <= newPercentile) {
|
while (currentPercentile <= newPercentile) {
|
||||||
percentiles.put(currentPercentile, duration);
|
final String percentile = String.format(Locale.US, "%.3f", currentPercentile);
|
||||||
|
percentiles.put(percentile, duration);
|
||||||
currentPercentile += stepSize;
|
currentPercentile += stepSize;
|
||||||
}
|
}
|
||||||
nextPercentile = currentPercentile;
|
nextPercentile = currentPercentile;
|
||||||
@@ -61,10 +62,15 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
|||||||
return maxValue;
|
return maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedHashMap<Double, Long> getPercentiles() {
|
public Percentiles getPercentiles() {
|
||||||
return percentiles;
|
return percentiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void collect(final LongLongHashMap map) {
|
||||||
|
map.forEachOrdered(this);
|
||||||
|
percentiles.put("100.000", maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the rather large initial capacity should prevent too many grow&re-hash phases
|
// the rather large initial capacity should prevent too many grow&re-hash phases
|
||||||
@@ -84,14 +90,27 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
|||||||
totalValues++;
|
totalValues++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Percentiles getPercentiles() {
|
||||||
|
final long start = System.nanoTime();
|
||||||
|
|
||||||
|
final ToPercentiles toPercentiles = new ToPercentiles(totalValues);
|
||||||
|
toPercentiles.collect(map);
|
||||||
|
|
||||||
|
final Percentiles result = toPercentiles.getPercentiles();
|
||||||
|
System.out.println("getPercentiles took: " + (System.nanoTime() - start) / 1_000_000.0 + " ms");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AggregatedData getAggregatedData() {
|
public AggregatedData getAggregatedData() {
|
||||||
try {
|
try {
|
||||||
final char separator = ',';
|
final char separator = ',';
|
||||||
final char newline = '\n';
|
final char newline = '\n';
|
||||||
|
|
||||||
|
final long start = System.nanoTime();
|
||||||
final ToPercentiles toPercentiles = new ToPercentiles(totalValues);
|
final ToPercentiles toPercentiles = new ToPercentiles(totalValues);
|
||||||
map.forEachOrdered(toPercentiles);
|
toPercentiles.collect(map);
|
||||||
|
System.out.println("getAggregated took: " + (System.nanoTime() - start) / 1_000_000.0 + " ms");
|
||||||
|
|
||||||
final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile());
|
final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile());
|
||||||
try (final Writer output = new BufferedWriter(
|
try (final Writer output = new BufferedWriter(
|
||||||
@@ -107,12 +126,6 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
|||||||
data.append(value);
|
data.append(value);
|
||||||
data.append(newline);
|
data.append(newline);
|
||||||
});
|
});
|
||||||
|
|
||||||
final long maxValue = toPercentiles.getMaxValue();
|
|
||||||
data.append(100);
|
|
||||||
data.append(separator);
|
|
||||||
data.append(maxValue);
|
|
||||||
data.append(newline);
|
|
||||||
}
|
}
|
||||||
output.write(data.toString());
|
output.write(data.toString());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps percentiles to their value. E.g.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {"50.00": 123, "75.00": 567}
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* This class uses Strings for the precentiles instead of doubles, because
|
||||||
|
* doubles are bad keys for maps.
|
||||||
|
*/
|
||||||
|
public class Percentiles extends LinkedHashMap<String, Long> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4957667781086113971L;
|
||||||
|
|
||||||
|
public Percentiles() {
|
||||||
|
super(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Percentiles(final int initialSize) {
|
||||||
|
super(initialSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Percentiles(final Map<String, Long> percentiles) {
|
||||||
|
super(percentiles.size());
|
||||||
|
putAll(percentiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.lucares.pdb.plot.api.AggregatorCollection;
|
import org.lucares.pdb.plot.api.AggregatorCollection;
|
||||||
import org.lucares.pdb.plot.api.Limit;
|
import org.lucares.pdb.plot.api.Limit;
|
||||||
|
import org.lucares.pdb.plot.api.Percentiles;
|
||||||
|
|
||||||
public interface DataSeries {
|
public interface DataSeries {
|
||||||
public static final Comparator<? super DataSeries> BY_NUMBER_OF_VALUES = (a, b) -> {
|
public static final Comparator<? super DataSeries> BY_NUMBER_OF_VALUES = (a, b) -> {
|
||||||
@@ -35,6 +36,8 @@ public interface DataSeries {
|
|||||||
|
|
||||||
public double getAverage();
|
public double getAverage();
|
||||||
|
|
||||||
|
public Percentiles getPercentiles();
|
||||||
|
|
||||||
public void setStyle(LineStyle style);
|
public void setStyle(LineStyle style);
|
||||||
|
|
||||||
public LineStyle getStyle();
|
public LineStyle getStyle();
|
||||||
@@ -114,5 +117,4 @@ public interface DataSeries {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.lucares.recommind.logs;
|
package org.lucares.recommind.logs;
|
||||||
|
|
||||||
import org.lucares.pdb.plot.api.AggregatorCollection;
|
import org.lucares.pdb.plot.api.AggregatorCollection;
|
||||||
|
import org.lucares.pdb.plot.api.CumulativeDistributionCustomAggregator;
|
||||||
|
import org.lucares.pdb.plot.api.Percentiles;
|
||||||
|
|
||||||
public class FileBackedDataSeries implements DataSeries {
|
public class FileBackedDataSeries implements DataSeries {
|
||||||
|
|
||||||
@@ -55,11 +57,19 @@ public class FileBackedDataSeries implements DataSeries {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getAverage() {
|
public double getAverage() {
|
||||||
return csvSummary.getStatsAverage();
|
return Math.round(csvSummary.getStatsAverage() * 10.0) / 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AggregatorCollection getAggregators() {
|
public AggregatorCollection getAggregators() {
|
||||||
return csvSummary.getAggregators();
|
return csvSummary.getAggregators();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Percentiles getPercentiles() {
|
||||||
|
return csvSummary.getAggregators()//
|
||||||
|
.getAggregator(CumulativeDistributionCustomAggregator.class)//
|
||||||
|
.map(CumulativeDistributionCustomAggregator::getPercentiles)//
|
||||||
|
.orElse(new Percentiles());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ package org.lucares.pdbui.domain;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.lucares.pdb.plot.api.Percentiles;
|
||||||
|
|
||||||
public class DataSeriesStats {
|
public class DataSeriesStats {
|
||||||
private final int values;
|
private final int values;
|
||||||
private final long maxValue;
|
private final long maxValue;
|
||||||
private final double average;
|
private final double average;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final StyleAndColor dashTypeAndColor;
|
private final StyleAndColor dashTypeAndColor;
|
||||||
|
private Percentiles percentiles;
|
||||||
|
|
||||||
public DataSeriesStats(final int values, final long maxValue, final double average) {
|
public DataSeriesStats(final int values, final long maxValue, final double average) {
|
||||||
this.name = "<noName>";
|
this.name = "<noName>";
|
||||||
@@ -17,13 +20,14 @@ public class DataSeriesStats {
|
|||||||
this.average = average;
|
this.average = average;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataSeriesStats(final String name, final StyleAndColor dashTypeAndColor, final int values,
|
public DataSeriesStats(final String name, final StyleAndColor dashTypeAndColor, final int values, final long maxValue,
|
||||||
final long maxValue, final double average) {
|
final double average, final Percentiles percentiles) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.dashTypeAndColor = dashTypeAndColor;
|
this.dashTypeAndColor = dashTypeAndColor;
|
||||||
this.values = values;
|
this.values = values;
|
||||||
this.maxValue = maxValue;
|
this.maxValue = maxValue;
|
||||||
this.average = average;
|
this.average = average;
|
||||||
|
this.percentiles = percentiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,14 +51,18 @@ public class DataSeriesStats {
|
|||||||
return average;
|
return average;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Percentiles getPercentiles() {
|
||||||
|
return percentiles;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[name=" + name + ", dashTypeAndColor=" + dashTypeAndColor + ", values=" + values + ", maxValue="
|
return "[name=" + name + ", dashTypeAndColor=" + dashTypeAndColor + ", values=" + values + ", maxValue=" + maxValue
|
||||||
+ maxValue + ", average=" + average + "]";
|
+ ", average=" + average + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double average(final Collection<DataSeriesStats> stats) {
|
public static double average(final Collection<DataSeriesStats> stats) {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class PlotResponseStats {
|
|||||||
dataSerie.getStyle().getPointType());
|
dataSerie.getStyle().getPointType());
|
||||||
|
|
||||||
dataSeriesStats.add(new DataSeriesStats(dataSerie.getTitle(), lineStyle, dataSerie.getValues(),
|
dataSeriesStats.add(new DataSeriesStats(dataSerie.getTitle(), lineStyle, dataSerie.getValues(),
|
||||||
dataSerie.getMaxValue(), dataSerie.getAverage()));
|
dataSerie.getMaxValue(), dataSerie.getAverage(), dataSerie.getPercentiles()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final double average = Math.round(DataSeriesStats.average(dataSeriesStats));
|
final double average = Math.round(DataSeriesStats.average(dataSeriesStats));
|
||||||
|
|||||||
Reference in New Issue
Block a user