updateMessage("preparing update");
Platform.runLater(() -> {
setCursor(Cursor.WAIT);
});
final RangeDivisionInfo rangeInfo = RangeDivisionInfo.getRangeDivisionInfo(filteredEvents.timeRange().get());
chart.setRangeInfo(rangeInfo);
//extend range to block bounderies (ie day, month, year)
final long lowerBound = rangeInfo.getLowerBound();
final long upperBound = rangeInfo.getUpperBound();
final Interval timeRange = new Interval(new DateTime(lowerBound, TimeLineController.getJodaTimeZone()), new DateTime(upperBound, TimeLineController.getJodaTimeZone()));
int max = 0;
int p = 0; // progress counter
//clear old data, and reset ranges and series
Platform.runLater(() -> {
updateMessage("resetting ui");
eventTypeMap.clear();
dataSets.clear();
dateAxis.getCategories().clear();
DateTime start = timeRange.getStart();
while (timeRange.contains(start)) {
//add bar/'category' label for the current interval
final String dateString = start.toString(rangeInfo.getTickFormatter());
dateAxis.getCategories().add(dateString);
//increment for next iteration
start = start.plus(rangeInfo.getPeriodSize().getPeriod());
}
//make all series to ensure they get created in consistent order
EventType.allTypes.forEach(CountsViewPane.this::getSeries);
});
DateTime start = timeRange.getStart();
while (timeRange.contains(start)) {
final String dateString = start.toString(rangeInfo.getTickFormatter());
DateTime end = start.plus(rangeInfo.getPeriodSize().getPeriod());
final Interval interval = new Interval(start, end);
//query for current range
Map<EventType, Long> eventCounts = filteredEvents.getEventCounts(interval);
//increment for next iteration
start = end;
int dateMax = 0; //used in max tracking
//for each type add data to graph
for (final EventType et : eventCounts.keySet()) {
if (isCancelled()) {
return null;
}
final Long count = eventCounts.get(et);
final int fp = p++;
if (count > 0) {
final double adjustedCount = count == 0 ? 0 : scale.get().adjust(count);
dateMax += adjustedCount;
final XYChart.Data<String, Number> xyData = new BarChart.Data<>(dateString, adjustedCount);
xyData.nodeProperty().addListener((Observable o) -> {
final Node node = xyData.getNode();
if (node != null) {
node.setStyle("-fx-border-width: 2; -fx-border-color: " + ColorUtilities.getRGBCode(et.getSuperType().getColor()) + "; -fx-bar-fill: " + ColorUtilities.getRGBCode(et.getColor()));
node.setCursor(Cursor.HAND);
node.setOnMouseEntered((MouseEvent event) -> {
//defer tooltip creation till needed, this had a surprisingly large impact on speed of loading the chart
final Tooltip tooltip = new Tooltip(count + " " + et.getDisplayName() + " events\n"
+ "between " + dateString + "\n"
+ "and "
+ interval.getEnd().toString(rangeInfo.getTickFormatter()));
tooltip.setGraphic(new ImageView(et.getFXImage()));
Tooltip.install(node, tooltip);
node.setEffect(new DropShadow(10, et.getColor()));
});
node.setOnMouseExited((MouseEvent event) -> {
if (selectedNodes.contains(node)) {
node.setEffect(SELECTED_NODE_EFFECT);
} else {
node.setEffect(null);
}
});
node.addEventHandler(MouseEvent.MOUSE_CLICKED, new BarClickHandler(node, dateString, interval, et));
}
});
max = Math.max(max, dateMax);
final double fmax = max;
Platform.runLater(() -> {
updateMessage("updating counts");
getSeries(et).getData().add(xyData);
if (scale.get().equals(ScaleType.LINEAR)) {
countAxis.setTickUnit(Math.pow(10, Math.max(0, Math.floor(Math.log10(fmax)) - 1)));
} else {
countAxis.setTickUnit(Double.MAX_VALUE);
}
countAxis.setUpperBound(1 + fmax * 1.2);
layoutDateLabels();
updateProgress(fp, rangeInfo.getPeriodsInRange());
});
} else {
final double fmax = max;
Platform.runLater(() -> {
updateMessage("updating counts");
updateProgress(fp, rangeInfo.getPeriodsInRange());
});
}
}
}