group plots by a single field
This commit is contained in:
@@ -11,22 +11,17 @@ public class DataSeries {
|
|||||||
|
|
||||||
private final Integer pointType;
|
private final Integer pointType;
|
||||||
|
|
||||||
public DataSeries(final File dataFile, final String title) {
|
private final int values;
|
||||||
|
|
||||||
|
public DataSeries(final File dataFile, final String title, final int values) {
|
||||||
super();
|
super();
|
||||||
this.dataFile = dataFile;
|
this.dataFile = dataFile;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
this.values = values;
|
||||||
this.color = null;
|
this.color = null;
|
||||||
this.pointType = null;
|
this.pointType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataSeries(final File dataFile, final String title, final GnuplotColor color, final Integer pointType) {
|
|
||||||
super();
|
|
||||||
this.dataFile = dataFile;
|
|
||||||
this.title = title;
|
|
||||||
this.color = color;
|
|
||||||
this.pointType = pointType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GnuplotColor getColor() {
|
public GnuplotColor getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
@@ -42,4 +37,8 @@ public class DataSeries {
|
|||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getValues() {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ import java.util.Iterator;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.lucares.pdb.api.Entry;
|
import org.lucares.pdb.api.Entry;
|
||||||
|
import org.lucares.pdb.api.GroupResult;
|
||||||
|
import org.lucares.pdb.api.Result;
|
||||||
|
import org.lucares.pdb.api.Tags;
|
||||||
import org.lucares.performance.db.FileUtils;
|
import org.lucares.performance.db.FileUtils;
|
||||||
|
import org.lucares.performance.db.Grouping;
|
||||||
import org.lucares.performance.db.PerformanceDb;
|
import org.lucares.performance.db.PerformanceDb;
|
||||||
|
|
||||||
public class Plotter {
|
public class Plotter {
|
||||||
@@ -43,17 +47,24 @@ public class Plotter {
|
|||||||
return outputDir;
|
return outputDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File plot(final String query, final int height, final int width) throws InternalPlottingException {
|
public File plot(final String query, final int height, final int width, final String groupBy)
|
||||||
|
throws InternalPlottingException {
|
||||||
try {
|
try {
|
||||||
final Collection<DataSeries> dataSeries = new ArrayList<>();
|
final Collection<DataSeries> dataSeries = new ArrayList<>();
|
||||||
|
|
||||||
final Stream<Entry> entries = db.get(query).singleGroup().asStream();
|
final Result result = db.get(query, groupBy);
|
||||||
|
|
||||||
|
for (final GroupResult groupResult : result.getGroups()) {
|
||||||
|
|
||||||
|
final Stream<Entry> entries = groupResult.asStream();
|
||||||
|
|
||||||
final File dataFile = File.createTempFile("data", ".dat", tmpBaseDir.toFile());
|
final File dataFile = File.createTempFile("data", ".dat", tmpBaseDir.toFile());
|
||||||
final DataSeries dataSerie = new DataSeries(dataFile, query);
|
final int values = toCsv(entries, dataFile);
|
||||||
toCsv(entries, dataFile);
|
|
||||||
|
|
||||||
|
final String title = title(groupResult.getGroupedBy(), values);
|
||||||
|
final DataSeries dataSerie = new DataSeries(dataFile, title, values);
|
||||||
dataSeries.add(dataSerie);
|
dataSeries.add(dataSerie);
|
||||||
|
}
|
||||||
|
|
||||||
final File outputFile = File.createTempFile("out", ".png", outputDir.toFile());
|
final File outputFile = File.createTempFile("out", ".png", outputDir.toFile());
|
||||||
final Gnuplot gnuplot = new Gnuplot(tmpBaseDir);
|
final Gnuplot gnuplot = new Gnuplot(tmpBaseDir);
|
||||||
@@ -70,6 +81,23 @@ public class Plotter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String title(final Tags tags, final int values) {
|
||||||
|
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
assert tags.getKeys().size() <= 1;
|
||||||
|
tags.forEach((k, v) -> {
|
||||||
|
result.append(v);
|
||||||
|
});
|
||||||
|
|
||||||
|
result.append("(");
|
||||||
|
result.append(values);
|
||||||
|
result.append(")");
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
final Path dataDirectory = Paths.get(args[0]);
|
final Path dataDirectory = Paths.get(args[0]);
|
||||||
final Path outputDirectory = Paths.get(args[1]);
|
final Path outputDirectory = Paths.get(args[1]);
|
||||||
@@ -81,7 +109,7 @@ public class Plotter {
|
|||||||
|
|
||||||
try (PerformanceDb db = new PerformanceDb(dataDirectory)) {
|
try (PerformanceDb db = new PerformanceDb(dataDirectory)) {
|
||||||
final Plotter plotter = new Plotter(db, tmpBaseDir, outputDirectory);
|
final Plotter plotter = new Plotter(db, tmpBaseDir, outputDirectory);
|
||||||
final File image = plotter.plot(query, 1600, 1200);
|
final File image = plotter.plot(query, 1600, 1200, Grouping.NO_GROUPING);
|
||||||
System.out.println("plotted image: " + image);
|
System.out.println("plotted image: " + image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +118,7 @@ public class Plotter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void toCsv(final Stream<Entry> entries, final File dataFile) throws IOException {
|
private static int toCsv(final Stream<Entry> entries, final File dataFile) throws IOException {
|
||||||
|
|
||||||
final long start = System.nanoTime();
|
final long start = System.nanoTime();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -111,6 +139,8 @@ public class Plotter {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("wrote " + count + " values to csv in: " + (System.nanoTime() - start) / 1_000_000.0 + "ms");
|
System.out.println("wrote " + count + " values to csv in: " + (System.nanoTime() - start) / 1_000_000.0 + "ms");
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class PdbController implements HardcodedValues, CollectionUtils {
|
|||||||
final int width = request.getWidth();
|
final int width = request.getWidth();
|
||||||
|
|
||||||
System.out.println(query);
|
System.out.println(query);
|
||||||
final File image = plotter.plot(query, height, width);
|
final File image = plotter.plot(query, height, width, request.getGroupBy());
|
||||||
|
|
||||||
final Path relativeImagePath = plotter.getOutputDir().relativize(image.toPath());
|
final Path relativeImagePath = plotter.getOutputDir().relativize(image.toPath());
|
||||||
return new PlotResponse(WEB_IMAGE_OUTPUT_PATH + "/" + relativeImagePath.toString());
|
return new PlotResponse(WEB_IMAGE_OUTPUT_PATH + "/" + relativeImagePath.toString());
|
||||||
@@ -88,6 +88,26 @@ public class PdbController implements HardcodedValues, CollectionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(path = "/fields", //
|
||||||
|
method = RequestMethod.GET, //
|
||||||
|
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, //
|
||||||
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE //
|
||||||
|
)
|
||||||
|
@ResponseBody
|
||||||
|
List<String> fields() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
final List<String> fields = db.getDb().getFields();
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new InternalServerError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<AutocompleteProposal> toAutocompleteProposals(final List<Proposal> proposals) {
|
private List<AutocompleteProposal> toAutocompleteProposals(final List<Proposal> proposals) {
|
||||||
|
|
||||||
final List<AutocompleteProposal> result = new ArrayList<>();
|
final List<AutocompleteProposal> result = new ArrayList<>();
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ public class PlotRequest {
|
|||||||
|
|
||||||
private int width;
|
private int width;
|
||||||
|
|
||||||
|
private String groupBy;
|
||||||
|
|
||||||
public String getQuery() {
|
public String getQuery() {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
@@ -35,4 +37,12 @@ public class PlotRequest {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return query + ":" + height + "x" + width;
|
return query + ":" + height + "x" + width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getGroupBy() {
|
||||||
|
return groupBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupBy(final String groupBy) {
|
||||||
|
this.groupBy = groupBy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
<input id="search-input" data-autocomplete="autocomplete"
|
<input id="search-input" data-autocomplete="autocomplete"
|
||||||
data-autocomplete-empty-message="nothing found" />
|
data-autocomplete-empty-message="nothing found" />
|
||||||
</div>
|
</div>
|
||||||
|
<div id="search-group-by">
|
||||||
|
</div>
|
||||||
<button id="search-submit"><i class="fa fa-search"> Search</i></button>
|
<button id="search-submit"><i class="fa fa-search"> Search</i></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="result-view">
|
<div id="result-view">
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
$('#search-submit').click(plot);
|
$('#search-submit').click(plot);
|
||||||
|
|
||||||
|
initGroupBy();
|
||||||
|
|
||||||
AutoComplete({
|
AutoComplete({
|
||||||
HttpMethod: "GET",
|
HttpMethod: "GET",
|
||||||
Delay: 300,
|
Delay: 300,
|
||||||
@@ -27,6 +29,24 @@ $(document).ready(function(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function initGroupBy()
|
||||||
|
{
|
||||||
|
var successCallback = function (response) {
|
||||||
|
|
||||||
|
response.forEach(function(item, index){
|
||||||
|
$('#search-group-by').append('<input type="radio" id="groupBy-'+index+'" name="groupBy" value="'+item+'" /><label for="groupBy-'+index+'">'+item+'</label>');
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var errorCallback = function (){
|
||||||
|
$('#result-view').text("FAILED: " + JSON.stringify(e));
|
||||||
|
};
|
||||||
|
|
||||||
|
getJson("fields", {}, successCallback, errorCallback)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function showLoadingIcon()
|
function showLoadingIcon()
|
||||||
{
|
{
|
||||||
$('#result-view').html("<div class='center'><div class='uil-cube-css' style='-webkit-transform:scale(0.41)'><div /><div></div><div></div><div></div></div></div>");
|
$('#result-view').html("<div class='center'><div class='uil-cube-css' style='-webkit-transform:scale(0.41)'><div /><div></div><div></div><div></div></div></div>");
|
||||||
@@ -41,6 +61,7 @@ function plot(event){
|
|||||||
request['query'] = $('#search-input').val();
|
request['query'] = $('#search-input').val();
|
||||||
request['height'] = $('#result-view').height()-10;
|
request['height'] = $('#result-view').height()-10;
|
||||||
request['width'] = $('#result-view').width()-10;
|
request['width'] = $('#result-view').width()-10;
|
||||||
|
request['groupBy'] = $('input[name=groupBy]:checked').val();
|
||||||
|
|
||||||
var success = function(response){
|
var success = function(response){
|
||||||
|
|
||||||
@@ -67,4 +88,15 @@ function postJson(url, requestData, successCallback, errorCallback) {
|
|||||||
.fail(errorCallback);
|
.fail(errorCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getJson(url, requestData, successCallback, errorCallback) {
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
data: requestData,
|
||||||
|
contentType: 'application/json'
|
||||||
|
})
|
||||||
|
.done(successCallback)
|
||||||
|
.fail(errorCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.lucares.pdb.api.Tags;
|
|||||||
public class Grouping {
|
public class Grouping {
|
||||||
|
|
||||||
public static final String NO_GROUPING = null;
|
public static final String NO_GROUPING = null;
|
||||||
|
public static final String DEFAULT_GROUP = "<default>";
|
||||||
private final List<Group> groups = new ArrayList<>();
|
private final List<Group> groups = new ArrayList<>();
|
||||||
|
|
||||||
private Grouping(final Group group) {
|
private Grouping(final Group group) {
|
||||||
@@ -25,7 +26,7 @@ public class Grouping {
|
|||||||
|
|
||||||
final Grouping result;
|
final Grouping result;
|
||||||
if (groupByField == NO_GROUPING) {
|
if (groupByField == NO_GROUPING) {
|
||||||
final Group group = new Group(null, pdbReaders);
|
final Group group = new Group(Tags.EMPTY, pdbReaders);
|
||||||
|
|
||||||
result = new Grouping(group);
|
result = new Grouping(group);
|
||||||
} else {
|
} else {
|
||||||
@@ -35,10 +36,10 @@ public class Grouping {
|
|||||||
final Tags tags = pdbReader.getPdbFile().getTags();
|
final Tags tags = pdbReader.getPdbFile().getTags();
|
||||||
final String value = tags.getValue(groupByField);
|
final String value = tags.getValue(groupByField);
|
||||||
|
|
||||||
if (value != null) {
|
final String groupName = value != null ? value : DEFAULT_GROUP;
|
||||||
addIfNotExists(grouping, groupByField, value);
|
|
||||||
grouping.get(value).addReader(pdbReader);
|
addIfNotExists(grouping, groupByField, groupName);
|
||||||
}
|
grouping.get(groupName).addReader(pdbReader);
|
||||||
}
|
}
|
||||||
result = new Grouping(grouping.values());
|
result = new Grouping(grouping.values());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.logging.Logger;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import org.lucares.ludb.Field;
|
||||||
import org.lucares.ludb.H2DB;
|
import org.lucares.ludb.H2DB;
|
||||||
import org.lucares.ludb.Proposal;
|
import org.lucares.ludb.Proposal;
|
||||||
import org.lucares.pdb.api.Entry;
|
import org.lucares.pdb.api.Entry;
|
||||||
@@ -22,7 +23,7 @@ import org.lucares.pdb.api.GroupResult;
|
|||||||
import org.lucares.pdb.api.Result;
|
import org.lucares.pdb.api.Result;
|
||||||
import org.lucares.pdb.api.Tags;
|
import org.lucares.pdb.api.Tags;
|
||||||
|
|
||||||
public class PerformanceDb implements AutoCloseable {
|
public class PerformanceDb implements AutoCloseable, CollectionUtils {
|
||||||
private static final Logger LOGGER = Logger.getLogger(PerformanceDb.class.getCanonicalName());
|
private static final Logger LOGGER = Logger.getLogger(PerformanceDb.class.getCanonicalName());
|
||||||
|
|
||||||
private final TagsToFile tagsToFile;
|
private final TagsToFile tagsToFile;
|
||||||
@@ -178,4 +179,10 @@ public class PerformanceDb implements AutoCloseable {
|
|||||||
public List<Proposal> autocomplete(final String query, final int caretIndex) {
|
public List<Proposal> autocomplete(final String query, final int caretIndex) {
|
||||||
return db.proposeTagForQuery(query, caretIndex);
|
return db.proposeTagForQuery(query, caretIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getFields() {
|
||||||
|
final List<Field> fields = db.getAvailableFields("");
|
||||||
|
|
||||||
|
return map(fields, Field::getName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user