group plots by a single field

This commit is contained in:
2016-12-30 18:45:01 +01:00
parent 62437f384f
commit c283568757
8 changed files with 125 additions and 24 deletions

View File

@@ -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;
}
} }

View File

@@ -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);
final File dataFile = File.createTempFile("data", ".dat", tmpBaseDir.toFile()); for (final GroupResult groupResult : result.getGroups()) {
final DataSeries dataSerie = new DataSeries(dataFile, query);
toCsv(entries, dataFile);
dataSeries.add(dataSerie); final Stream<Entry> entries = groupResult.asStream();
final File dataFile = File.createTempFile("data", ".dat", tmpBaseDir.toFile());
final int values = toCsv(entries, dataFile);
final String title = title(groupResult.getGroupedBy(), values);
final DataSeries dataSerie = new DataSeries(dataFile, title, values);
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;
} }
} }

View File

@@ -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<>();

View File

@@ -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;
}
} }

View File

@@ -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">

View File

@@ -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);
}

View File

@@ -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());
} }

View File

@@ -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);
}
} }