range definitions for the y-axis
Sometimes it is useful to specify the certain y-axis range. For example when you are only interested in the values that take longer than a threshold. Or when you want to exclude some outliers. When you want to compare plots in a gallery, it is very handy when all plots have the same data-area.
This commit is contained in:
@@ -69,12 +69,10 @@ public class QueryCompletionPdbLangParser extends PdbLangParser {
|
|||||||
return new Proposal(v, newQuery.toString(), false, newQuery.toString(),
|
return new Proposal(v, newQuery.toString(), false, newQuery.toString(),
|
||||||
start + v.length() + 1);
|
start + v.length() + 1);
|
||||||
}).map(p -> {
|
}).map(p -> {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
try {
|
try {
|
||||||
count = dataStore.count(p.getProposedQuery());
|
count = dataStore.count(p.getProposedQuery());
|
||||||
}
|
} catch (final SyntaxException e) {
|
||||||
catch(SyntaxException e)
|
|
||||||
{
|
|
||||||
// ignore: if the query is not valid, then it does not find any results
|
// ignore: if the query is not valid, then it does not find any results
|
||||||
}
|
}
|
||||||
return new Proposal(p, count > 0);
|
return new Proposal(p, count > 0);
|
||||||
@@ -139,23 +137,7 @@ public class QueryCompletionPdbLangParser extends PdbLangParser {
|
|||||||
|
|
||||||
return new Proposal(key, String.format(newQueryPattern, key + "=* "), true, newQuery,
|
return new Proposal(key, String.format(newQueryPattern, key + "=* "), true, newQuery,
|
||||||
newCaretPosition);
|
newCaretPosition);
|
||||||
})
|
}).forEach(proposals::add);
|
||||||
// .map(p -> {
|
|
||||||
//
|
|
||||||
// final String proposedQuery = p.getProposedQuery();
|
|
||||||
// final int count = count(proposedQuery);
|
|
||||||
// return new Proposal(p, count > 0);
|
|
||||||
// })
|
|
||||||
.forEach(proposals::add);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int count(final String proposedQuery) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
return dataStore.count(proposedQuery);
|
|
||||||
} catch (final SyntaxException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEOF(final Object offendingSymbol) {
|
private boolean isEOF(final Object offendingSymbol) {
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ public class PlotSettings {
|
|||||||
|
|
||||||
private AggregateHandler aggregate;
|
private AggregateHandler aggregate;
|
||||||
|
|
||||||
|
private int yRangeMin;
|
||||||
|
private int yRangeMax;
|
||||||
|
private TimeRangeUnitInternal yRangeUnit = TimeRangeUnitInternal.AUTOMATIC;
|
||||||
|
|
||||||
private boolean keyOutside;
|
private boolean keyOutside;
|
||||||
|
|
||||||
private boolean generateThumbnail;
|
private boolean generateThumbnail;
|
||||||
@@ -183,7 +187,9 @@ public class PlotSettings {
|
|||||||
return "PlotSettings [query=" + query + ", height=" + height + ", width=" + width + ", thumbnailMaxWidth="
|
return "PlotSettings [query=" + query + ", height=" + height + ", width=" + width + ", thumbnailMaxWidth="
|
||||||
+ thumbnailMaxWidth + ", thumbnailMaxHeight=" + thumbnailMaxHeight + ", groupBy=" + groupBy
|
+ thumbnailMaxWidth + ", thumbnailMaxHeight=" + thumbnailMaxHeight + ", groupBy=" + groupBy
|
||||||
+ ", limitBy=" + limitBy + ", limit=" + limit + ", dateFrom=" + dateFrom + ", dateRange=" + dateRange
|
+ ", limitBy=" + limitBy + ", limit=" + limit + ", dateFrom=" + dateFrom + ", dateRange=" + dateRange
|
||||||
+ ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", keyOutside=" + keyOutside + "]";
|
+ ", yAxisScale=" + yAxisScale + ", aggregate=" + aggregate + ", yRangeMin=" + yRangeMin
|
||||||
|
+ ", yRangeMax=" + yRangeMax + ", yRangeUnit=" + yRangeUnit + ", keyOutside=" + keyOutside
|
||||||
|
+ ", generateThumbnail=" + generateThumbnail + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAggregate(final AggregateHandler aggregate) {
|
public void setAggregate(final AggregateHandler aggregate) {
|
||||||
@@ -209,4 +215,29 @@ public class PlotSettings {
|
|||||||
public boolean isGenerateThumbnail() {
|
public boolean isGenerateThumbnail() {
|
||||||
return generateThumbnail;
|
return generateThumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getYRangeMin() {
|
||||||
|
return yRangeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYRangeMin(final int yRangeMin) {
|
||||||
|
this.yRangeMin = yRangeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYRangeMax() {
|
||||||
|
return yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYRangeMax(final int yRangeMax) {
|
||||||
|
this.yRangeMax = yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeRangeUnitInternal getYRangeUnit() {
|
||||||
|
return yRangeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYRangeUnit(final TimeRangeUnitInternal yRangeUnit) {
|
||||||
|
this.yRangeUnit = yRangeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
public enum TimeRangeUnitInternal {
|
||||||
|
AUTOMATIC, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS;
|
||||||
|
|
||||||
|
public int toMilliSeconds(final int value) {
|
||||||
|
|
||||||
|
switch (this) {
|
||||||
|
case MILLISECONDS:
|
||||||
|
return value;
|
||||||
|
case SECONDS:
|
||||||
|
return value * 1000;
|
||||||
|
case MINUTES:
|
||||||
|
return value * 60 * 1000;
|
||||||
|
case HOURS:
|
||||||
|
return value * 60 * 60 * 1000;
|
||||||
|
case DAYS:
|
||||||
|
return value * 24 * 60 * 60 * 1000;
|
||||||
|
case AUTOMATIC:
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,8 +28,14 @@ public class GnuplotFileGenerator {
|
|||||||
appendfln(result, "set xlabel \"%s\"", xAxis.getXlabel());
|
appendfln(result, "set xlabel \"%s\"", xAxis.getXlabel());
|
||||||
appendfln(result, "set xrange [\"%s\":\"%s\"]", xAxis.getFrom(), xAxis.getTo());
|
appendfln(result, "set xrange [\"%s\":\"%s\"]", xAxis.getFrom(), xAxis.getTo());
|
||||||
|
|
||||||
final long graphOffset = settings.getYAxisScale() == AxisScale.LINEAR ? 0 : 1;
|
final int graphOffset = settings.getYAxisScale() == AxisScale.LINEAR ? 0 : 1;
|
||||||
appendfln(result, "set yrange [\"" + graphOffset + "\":]");
|
if (settings.hasYRange()) {
|
||||||
|
final int min = Math.max(settings.getYRangeMin(), graphOffset);
|
||||||
|
final int max = settings.getYRangeMax();
|
||||||
|
appendfln(result, String.format("set yrange [\"%d\":\"%d\"]", min, max));
|
||||||
|
} else {
|
||||||
|
appendfln(result, "set yrange [\"" + graphOffset + "\":]");
|
||||||
|
}
|
||||||
|
|
||||||
appendfln(result, "set ylabel \"%s\"", settings.getYlabel());
|
appendfln(result, "set ylabel \"%s\"", settings.getYlabel());
|
||||||
switch (settings.getYAxisScale()) {
|
switch (settings.getYAxisScale()) {
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ public class GnuplotSettings {
|
|||||||
|
|
||||||
private XAxisSettings xAxisSettings = new XAxisSettings();
|
private XAxisSettings xAxisSettings = new XAxisSettings();
|
||||||
private boolean renderLabels = true;
|
private boolean renderLabels = true;
|
||||||
|
private int yRangeMin = -1;
|
||||||
|
private int yRangeMax = -1;
|
||||||
|
|
||||||
public GnuplotSettings(final Path output) {
|
public GnuplotSettings(final Path output) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
@@ -123,6 +125,23 @@ public class GnuplotSettings {
|
|||||||
return renderLabels;
|
return renderLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasYRange() {
|
||||||
|
return yRangeMin >= 0 && yRangeMax >= 0 && yRangeMin < yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYRange(final int yRangeMin, final int yRangeMax) {
|
||||||
|
this.yRangeMin = yRangeMin;
|
||||||
|
this.yRangeMax = yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYRangeMin() {
|
||||||
|
return yRangeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYRangeMax() {
|
||||||
|
return yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
// plot 'sample.txt' using 1:2 title 'Bytes' with linespoints 2
|
// plot 'sample.txt' using 1:2 title 'Bytes' with linespoints 2
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.lucares.pdb.api.Tags;
|
|||||||
import org.lucares.pdb.plot.api.CustomAggregator;
|
import org.lucares.pdb.plot.api.CustomAggregator;
|
||||||
import org.lucares.pdb.plot.api.Limit;
|
import org.lucares.pdb.plot.api.Limit;
|
||||||
import org.lucares.pdb.plot.api.PlotSettings;
|
import org.lucares.pdb.plot.api.PlotSettings;
|
||||||
|
import org.lucares.pdb.plot.api.TimeRangeUnitInternal;
|
||||||
import org.lucares.performance.db.PerformanceDb;
|
import org.lucares.performance.db.PerformanceDb;
|
||||||
import org.lucares.utils.file.FileUtils;
|
import org.lucares.utils.file.FileUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -120,6 +121,8 @@ public class ScatterPlot {
|
|||||||
|
|
||||||
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
||||||
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
||||||
|
defineYRange(gnuplotSettings, plotSettings.getYRangeMin(), plotSettings.getYRangeMax(),
|
||||||
|
plotSettings.getYRangeUnit());
|
||||||
gnuplotSettings.setKeyOutside(plotSettings.isKeyOutside());
|
gnuplotSettings.setKeyOutside(plotSettings.isKeyOutside());
|
||||||
gnuplot.plot(gnuplotSettings, dataSeries);
|
gnuplot.plot(gnuplotSettings, dataSeries);
|
||||||
}
|
}
|
||||||
@@ -135,6 +138,8 @@ public class ScatterPlot {
|
|||||||
|
|
||||||
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
gnuplotSettings.setYAxisScale(plotSettings.getYAxisScale());
|
||||||
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
gnuplotSettings.setAggregate(plotSettings.getAggregate());
|
||||||
|
defineYRange(gnuplotSettings, plotSettings.getYRangeMin(), plotSettings.getYRangeMax(),
|
||||||
|
plotSettings.getYRangeUnit());
|
||||||
gnuplotSettings.setKeyOutside(false);
|
gnuplotSettings.setKeyOutside(false);
|
||||||
gnuplotSettings.renderLabels(false);
|
gnuplotSettings.renderLabels(false);
|
||||||
gnuplot.plot(gnuplotSettings, dataSeries);
|
gnuplot.plot(gnuplotSettings, dataSeries);
|
||||||
@@ -154,6 +159,16 @@ public class ScatterPlot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void defineYRange(final GnuplotSettings gnuplotSettings, final int yRangeMin, final int yRangeMax,
|
||||||
|
final TimeRangeUnitInternal yRangeUnit) {
|
||||||
|
|
||||||
|
if (yRangeUnit != TimeRangeUnitInternal.AUTOMATIC) {
|
||||||
|
final int min = yRangeUnit.toMilliSeconds(yRangeMin);
|
||||||
|
final int max = yRangeUnit.toMilliSeconds(yRangeMax);
|
||||||
|
gnuplotSettings.setYRange(min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void defineXAxis(final GnuplotSettings gnuplotSettings, final OffsetDateTime minDate,
|
private void defineXAxis(final GnuplotSettings gnuplotSettings, final OffsetDateTime minDate,
|
||||||
final OffsetDateTime maxDate) {
|
final OffsetDateTime maxDate) {
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ public class PlotRequest {
|
|||||||
|
|
||||||
private Aggregate aggregate = Aggregate.NONE;
|
private Aggregate aggregate = Aggregate.NONE;
|
||||||
|
|
||||||
|
private int yRangeMin;
|
||||||
|
private int yRangeMax;
|
||||||
|
private TimeRangeUnit yRangeUnit = TimeRangeUnit.AUTOMATIC;
|
||||||
|
|
||||||
private boolean keyOutside;
|
private boolean keyOutside;
|
||||||
|
|
||||||
private boolean generateThumbnail;
|
private boolean generateThumbnail;
|
||||||
@@ -154,4 +158,27 @@ public class PlotRequest {
|
|||||||
this.generateThumbnail = generateThumbnail;
|
this.generateThumbnail = generateThumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getyRangeMin() {
|
||||||
|
return yRangeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setyRangeMin(final int yRangeMin) {
|
||||||
|
this.yRangeMin = yRangeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getyRangeMax() {
|
||||||
|
return yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setyRangeMax(final int yRangeMax) {
|
||||||
|
this.yRangeMax = yRangeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeRangeUnit getyRangeUnit() {
|
||||||
|
return yRangeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setyRangeUnit(final TimeRangeUnit yRangeUnit) {
|
||||||
|
this.yRangeUnit = yRangeUnit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.lucares.pdbui.domain;
|
||||||
|
|
||||||
|
public enum TimeRangeUnit {
|
||||||
|
AUTOMATIC, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS
|
||||||
|
}
|
||||||
@@ -124,8 +124,8 @@ textarea {
|
|||||||
background: lightgrey;
|
background: lightgrey;
|
||||||
}
|
}
|
||||||
|
|
||||||
#search-limit-value {
|
.number-input-1k {
|
||||||
width: 4em;
|
width: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input_date {
|
.input_date {
|
||||||
|
|||||||
@@ -599,6 +599,9 @@ Vue.component('search-bar', {
|
|||||||
'dateRange': data.searchBar.dateRange,
|
'dateRange': data.searchBar.dateRange,
|
||||||
'axisScale': data.searchBar.axisScale,
|
'axisScale': data.searchBar.axisScale,
|
||||||
'aggregate': data.searchBar.aggregate,
|
'aggregate': data.searchBar.aggregate,
|
||||||
|
'yRangeMin': data.searchBar.yRange.min,
|
||||||
|
'yRangeMax': data.searchBar.yRange.max,
|
||||||
|
'yRangeUnit': data.searchBar.yRange.unit,
|
||||||
'keyOutside': data.searchBar.keyOutside,
|
'keyOutside': data.searchBar.keyOutside,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -640,9 +643,10 @@ Vue.component('search-bar', {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
id="search-limit-value"
|
id="search-limit-value"
|
||||||
name="search-limit-value"
|
name="search-limit-value"
|
||||||
|
class="number-input-1k"
|
||||||
min="1"
|
min="1"
|
||||||
max="1000"
|
max="999"
|
||||||
v-show="searchBar.limitBy.selected != 'NO_LIMIT'"
|
v-show="searchBar.limitBy.selected != 'NO_LIMIT'"
|
||||||
v-model="searchBar.limitBy.number"/>
|
v-model="searchBar.limitBy.number"/>
|
||||||
</div>
|
</div>
|
||||||
@@ -695,6 +699,34 @@ Vue.component('search-bar', {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<label for="y-max-value">Y-Range</label>
|
||||||
|
<input
|
||||||
|
v-show="searchBar.yRange.unit != 'AUTOMATIC'"
|
||||||
|
type="number"
|
||||||
|
id="y-range-min"
|
||||||
|
class="number-input-1k"
|
||||||
|
min="0"
|
||||||
|
max="999"
|
||||||
|
v-model="searchBar.yRange.min"/>
|
||||||
|
<input
|
||||||
|
v-show="searchBar.yRange.unit != 'AUTOMATIC'"
|
||||||
|
type="number"
|
||||||
|
id="y-range-max"
|
||||||
|
class="number-input-1k"
|
||||||
|
min="0"
|
||||||
|
max="999"
|
||||||
|
v-model="searchBar.yRange.max"/>
|
||||||
|
<select id="y-max-unit" v-model="searchBar.yRange.unit">
|
||||||
|
<option value="AUTOMATIC" title="adjust automatically">automatic</option>
|
||||||
|
<option value="MILLISECONDS" title="milli seconds">milli seconds</option>
|
||||||
|
<option value="SECONDS" title="seconds">seconds</option>
|
||||||
|
<option value="MINUTES" title="minutes">minutes</option>
|
||||||
|
<option value="HOURS" title="hours">hours</option>
|
||||||
|
<option value="DAYS" title="days">hours</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="group">
|
<div class="group">
|
||||||
<input type="checkbox" id="key-outside" v-model="searchBar.keyOutside"/>
|
<input type="checkbox" id="key-outside" v-model="searchBar.keyOutside"/>
|
||||||
<label for="key-outside">Legend outside</label>
|
<label for="key-outside">Legend outside</label>
|
||||||
@@ -775,6 +807,11 @@ var data = {
|
|||||||
dateRange: GetURLParameter('dateRange','1 week'),
|
dateRange: GetURLParameter('dateRange','1 week'),
|
||||||
axisScale: GetURLParameter('axisScale','LOG10'),
|
axisScale: GetURLParameter('axisScale','LOG10'),
|
||||||
aggregate: GetURLParameter('aggregate','NONE'),
|
aggregate: GetURLParameter('aggregate','NONE'),
|
||||||
|
yRange: {
|
||||||
|
min: GetURLParameter('yRangeMin','0'),
|
||||||
|
max: GetURLParameter('yRangeMax','999'),
|
||||||
|
unit: GetURLParameter('yRangeUnit','AUTOMATIC')
|
||||||
|
},
|
||||||
keyOutside: GetURLParameterBoolean('keyOutside', 'false'),
|
keyOutside: GetURLParameterBoolean('keyOutside', 'false'),
|
||||||
|
|
||||||
splitBy: {
|
splitBy: {
|
||||||
@@ -879,6 +916,9 @@ function createRequest(query, generateThumbnail){
|
|||||||
request['aggregate'] = data.searchBar.aggregate;
|
request['aggregate'] = data.searchBar.aggregate;
|
||||||
request['keyOutside'] = data.searchBar.keyOutside;
|
request['keyOutside'] = data.searchBar.keyOutside;
|
||||||
request['generateThumbnail'] = generateThumbnail;
|
request['generateThumbnail'] = generateThumbnail;
|
||||||
|
request['yRangeMin'] = data.searchBar.yRange.min;
|
||||||
|
request['yRangeMax'] = data.searchBar.yRange.max;
|
||||||
|
request['yRangeUnit'] = data.searchBar.yRange.unit;
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
@@ -928,6 +968,9 @@ function updateImageLink(query) {
|
|||||||
'dateRange': data.searchBar.dateRange,
|
'dateRange': data.searchBar.dateRange,
|
||||||
'axisScale': data.searchBar.axisScale,
|
'axisScale': data.searchBar.axisScale,
|
||||||
'aggregate': data.searchBar.aggregate,
|
'aggregate': data.searchBar.aggregate,
|
||||||
|
'yRangeMin': data.searchBar.yRange.min,
|
||||||
|
'yRangeMax': data.searchBar.yRange.max,
|
||||||
|
'yRangeUnit': data.searchBar.yRange.unit,
|
||||||
'keyOutside': data.searchBar.keyOutside,
|
'keyOutside': data.searchBar.keyOutside,
|
||||||
'width': Math.floor($('#result').width()),
|
'width': Math.floor($('#result').width()),
|
||||||
'height': Math.floor($('#result').height())
|
'height': Math.floor($('#result').height())
|
||||||
|
|||||||
Reference in New Issue
Block a user