put off invoking the JFX thread till deeper in the stack. remove unused list, use concurrent hashmaps

This commit is contained in:
jmillman 2015-11-09 16:44:57 -05:00
parent ff2278a98e
commit ddcc2d567f
4 changed files with 43 additions and 41 deletions

View File

@ -33,7 +33,6 @@ import javafx.concurrent.Task;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.chart.Axis; import javafx.scene.chart.Axis;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.Chart; import javafx.scene.chart.Chart;
import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@ -81,7 +80,7 @@ public abstract class AbstractVisualizationPane<X, Y, N, C extends XYChart<X, Y>
} }
protected final SimpleBooleanProperty hasEvents = new SimpleBooleanProperty(true); protected final SimpleBooleanProperty hasEvents = new SimpleBooleanProperty(true);
protected final ObservableList<BarChart.Series<X, Y>> dataSets = FXCollections.<BarChart.Series<X, Y>>observableArrayList(); protected final ObservableList<XYChart.Series<X, Y>> dataSeries = FXCollections.<XYChart.Series<X, Y>> observableArrayList();
protected C chart; protected C chart;

View File

@ -111,7 +111,7 @@ public class CountsViewPane extends AbstractVisualizationPane<String, Number, No
@Override @Override
protected Boolean isTickBold(String value) { protected Boolean isTickBold(String value) {
return dataSets.stream().flatMap((series) -> series.getData().stream()) return dataSeries.stream().flatMap((series) -> series.getData().stream())
.anyMatch((data) -> data.getXValue().equals(value) && data.getYValue().intValue() > 0); .anyMatch((data) -> data.getXValue().equals(value) && data.getYValue().intValue() > 0);
} }
@ -144,7 +144,7 @@ public class CountsViewPane extends AbstractVisualizationPane<String, Number, No
Platform.runLater(() -> { Platform.runLater(() -> {
updateMessage(NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.resetUI")); updateMessage(NbBundle.getMessage(this.getClass(), "CountsViewPane.loggedTask.resetUI"));
eventTypeMap.clear(); eventTypeMap.clear();
dataSets.clear(); dataSeries.clear();
dateAxis.getCategories().clear(); dateAxis.getCategories().clear();
DateTime start = timeRange.getStart(); DateTime start = timeRange.getStart();
@ -264,7 +264,7 @@ public class CountsViewPane extends AbstractVisualizationPane<String, Number, No
super(controller, partPane, contextPane, spacer); super(controller, partPane, contextPane, spacer);
chart = new EventCountsChart(controller, dateAxis, countAxis); chart = new EventCountsChart(controller, dateAxis, countAxis);
setChartClickHandler(); setChartClickHandler();
chart.setData(dataSets); chart.setData(dataSeries);
setCenter(chart); setCenter(chart);
Tooltip.install(chart, getDefaultTooltip()); Tooltip.install(chart, getDefaultTooltip());
@ -337,8 +337,7 @@ public class CountsViewPane extends AbstractVisualizationPane<String, Number, No
series = new XYChart.Series<>(); series = new XYChart.Series<>();
series.setName(et.getDisplayName()); series.setName(et.getDisplayName());
eventTypeMap.put(et, series); eventTypeMap.put(et, series);
dataSeries.add(series);
dataSets.add(series);
} }
return series; return series;
@ -395,7 +394,7 @@ public class CountsViewPane extends AbstractVisualizationPane<String, Number, No
controller.selectTimeAndType(interval, RootEventType.getInstance()); controller.selectTimeAndType(interval, RootEventType.getInstance());
selectedNodes.clear(); selectedNodes.clear();
for (XYChart.Series<String, Number> s : dataSets) { for (XYChart.Series<String, Number> s : dataSeries) {
s.getData().forEach((XYChart.Data<String, Number> d) -> { s.getData().forEach((XYChart.Data<String, Number> d) -> {
if (startDateString.contains(d.getXValue())) { if (startDateString.contains(d.getXValue())) {
selectedNodes.add(d.getNode()); selectedNodes.add(d.getNode());

View File

@ -111,15 +111,13 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
public DetailViewPane(TimeLineController controller, Pane partPane, Pane contextPane, Region bottomLeftSpacer) { public DetailViewPane(TimeLineController controller, Pane partPane, Pane contextPane, Region bottomLeftSpacer) {
super(controller, partPane, contextPane, bottomLeftSpacer); super(controller, partPane, contextPane, bottomLeftSpacer);
//initialize chart; //initialize chart;
chart = new EventDetailsChart(controller, dateAxis, verticalAxis, selectedNodes); chart = new EventDetailsChart(controller, dateAxis, verticalAxis, selectedNodes);
setChartClickHandler(); //can we push this into chart setChartClickHandler(); //can we push this into chart
chart.setData(dataSets); chart.setData(dataSeries);
setCenter(chart); setCenter(chart);
settingsNodes = new ArrayList<>(new DetailViewSettingsPane().getChildrenUnmodifiable()); settingsNodes = new ArrayList<>(new DetailViewSettingsPane().getChildrenUnmodifiable());
//bind layout fo axes and spacers //bind layout fo axes and spacers
dateAxis.setTickLabelGap(0); dateAxis.setTickLabelGap(0);
dateAxis.setAutoRanging(false); dateAxis.setAutoRanging(false);
@ -260,7 +258,10 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
return eventTypeToSeriesMap.computeIfAbsent(et, (EventType t) -> { return eventTypeToSeriesMap.computeIfAbsent(et, (EventType t) -> {
XYChart.Series<DateTime, EventCluster> series = new XYChart.Series<>(); XYChart.Series<DateTime, EventCluster> series = new XYChart.Series<>();
series.setName(et.getDisplayName()); series.setName(et.getDisplayName());
dataSets.add(series); Platform.runLater(() -> {
dataSeries.add(series);
});
return series; return series;
}); });
} }
@ -299,7 +300,7 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
dateAxis.setUpperBound(new DateTime(upperBound, TimeLineController.getJodaTimeZone())); dateAxis.setUpperBound(new DateTime(upperBound, TimeLineController.getJodaTimeZone()));
vertScrollBar.setValue(0); vertScrollBar.setValue(0);
eventTypeToSeriesMap.clear(); eventTypeToSeriesMap.clear();
dataSets.clear(); dataSeries.clear();
}); });
List<EventCluster> eventClusters = filteredEvents.getEventClusters(); List<EventCluster> eventClusters = filteredEvents.getEventClusters();
@ -315,9 +316,9 @@ public class DetailViewPane extends AbstractVisualizationPane<DateTime, EventClu
final XYChart.Data<DateTime, EventCluster> xyData = new BarChart.Data<>(new DateTime(cluster.getSpan().getStartMillis()), cluster); final XYChart.Data<DateTime, EventCluster> xyData = new BarChart.Data<>(new DateTime(cluster.getSpan().getStartMillis()), cluster);
if (isCancelled() == false) { if (isCancelled() == false) {
Platform.runLater(() -> { // Platform.runLater(() -> {
getSeries(cluster.getEventType()).getData().add(xyData); getSeries(cluster.getEventType()).getData().add(xyData);
}); // });
} }
} }

View File

@ -24,11 +24,11 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -36,6 +36,7 @@ import java.util.stream.Stream;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
import javafx.animation.KeyValue; import javafx.animation.KeyValue;
import javafx.animation.Timeline; import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.InvalidationListener; import javafx.beans.InvalidationListener;
import javafx.beans.Observable; import javafx.beans.Observable;
import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty;
@ -148,17 +149,9 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
*/ */
private final Group nodeGroup = new Group(); private final Group nodeGroup = new Group();
private final ObservableList<EventBundle<?>> bundles = FXCollections.observableArrayList(); private final ObservableList<EventBundle<?>> bundles = FXCollections.observableArrayList();
private final Map<ImmutablePair<EventType, String>, EventStripe> stripeDescMap = new HashMap<>(); private final Map<ImmutablePair<EventType, String>, EventStripe> stripeDescMap = new ConcurrentHashMap<>();
private final Map<EventStripe, EventStripeNode> stripeNodeMap = new HashMap<>(); private final Map<EventStripe, EventStripeNode> stripeNodeMap = new ConcurrentHashMap<>();
private final Map<EventCluster, Line> projectionMap = new HashMap<>(); private final Map<EventCluster, Line> projectionMap = new ConcurrentHashMap<>();
/**
* list of series of data added to this chart
*
* TODO: replace this with a map from name to series? -jm
*/
private final ObservableList<Series<DateTime, EventCluster>> seriesList =
FXCollections.<Series<DateTime, EventCluster>>observableArrayList();
/** /**
* true == layout each event type in its own band, false == mix all the * true == layout each event type in its own band, false == mix all the
@ -334,21 +327,26 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
@Override @Override
protected synchronized void dataItemAdded(Series<DateTime, EventCluster> series, int i, Data<DateTime, EventCluster> data) { protected synchronized void dataItemAdded(Series<DateTime, EventCluster> series, int i, Data<DateTime, EventCluster> data) {
final EventCluster eventCluster = data.getYValue(); final EventCluster eventCluster = data.getYValue();
bundles.add(eventCluster);
EventStripe eventStripe = stripeDescMap.merge(ImmutablePair.of(eventCluster.getEventType(), eventCluster.getDescription()), EventStripe eventStripe = stripeDescMap.merge(ImmutablePair.of(eventCluster.getEventType(), eventCluster.getDescription()),
new EventStripe(eventCluster, null), new EventStripe(eventCluster, null),
(EventStripe u, EventStripe v) -> { (EventStripe u, EventStripe v) -> {
EventStripeNode remove = stripeNodeMap.remove(u); EventStripeNode removeU = stripeNodeMap.remove(u);
nodeGroup.getChildren().remove(remove); EventStripeNode removeV = stripeNodeMap.remove(v);
remove = stripeNodeMap.remove(v); Platform.runLater(() -> {
nodeGroup.getChildren().remove(remove); nodeGroup.getChildren().remove(removeU);
nodeGroup.getChildren().remove(removeV);
});
return EventStripe.merge(u, v); return EventStripe.merge(u, v);
} }
); );
EventStripeNode stripeNode = new EventStripeNode(EventDetailsChart.this, eventStripe, null); EventStripeNode stripeNode = new EventStripeNode(EventDetailsChart.this, eventStripe, null);
stripeNodeMap.put(eventStripe, stripeNode); stripeNodeMap.put(eventStripe, stripeNode);
Platform.runLater(() -> {
bundles.add(eventCluster);
nodeGroup.getChildren().add(stripeNode); nodeGroup.getChildren().add(stripeNode);
data.setNode(stripeNode); data.setNode(stripeNode);
});
} }
@Override @Override
@ -360,11 +358,18 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
@Override @Override
protected synchronized void dataItemRemoved(Data<DateTime, EventCluster> data, Series<DateTime, EventCluster> series) { protected synchronized void dataItemRemoved(Data<DateTime, EventCluster> data, Series<DateTime, EventCluster> series) {
EventCluster eventCluster = data.getYValue(); EventCluster eventCluster = data.getYValue();
Platform.runLater(() -> {
bundles.removeAll(eventCluster); bundles.removeAll(eventCluster);
});
EventStripe removedStripe = stripeDescMap.remove(ImmutablePair.of(eventCluster.getEventType(), eventCluster.getDescription())); EventStripe removedStripe = stripeDescMap.remove(ImmutablePair.of(eventCluster.getEventType(), eventCluster.getDescription()));
if (removedStripe != null) {
EventStripeNode removedNode = stripeNodeMap.remove(removedStripe); EventStripeNode removedNode = stripeNodeMap.remove(removedStripe);
Platform.runLater(() -> {
nodeGroup.getChildren().remove(removedNode); nodeGroup.getChildren().remove(removedNode);
data.setNode(null); data.setNode(null);
});
}
} }
@Override @Override
@ -396,7 +401,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
for (int j = 0; j < series.getData().size(); j++) { for (int j = 0; j < series.getData().size(); j++) {
dataItemAdded(series, j, series.getData().get(j)); dataItemAdded(series, j, series.getData().get(j));
} }
seriesList.add(series);
} }
@Override @Override
@ -404,7 +408,6 @@ public final class EventDetailsChart extends XYChart<DateTime, EventCluster> imp
for (int j = 0; j < series.getData().size(); j++) { for (int j = 0; j < series.getData().size(); j++) {
dataItemRemoved(series.getData().get(j), series); dataItemRemoved(series.getData().get(j), series);
} }
seriesList.remove(series);
} }
ReadOnlyDoubleProperty maxVScrollProperty() { ReadOnlyDoubleProperty maxVScrollProperty() {