Anonymous - 2012-07-29

Sorry, the AggregateLayout.translate does indeed return the locations with user translations - I was looking it up after the CircleLayout had already reset it! :-) Which means I have a workaround for this:

Now, this now need access to the AggregateLayout, which I am obtaining through the getGraphLayout() call. I'm also using commons-math and Guava in the utility function (also, forgive me my generics):

@Override
public void setGraph(Graph<Note, Weight> graph) {
// https://sourceforge.net/tracker/?func=detail&aid=3551554&group_id=73840&atid=539119
Graph<Note, Weight> oldGraph = getGraph();
if (oldGraph != null && !oldGraph.getVertices().isEmpty() && getGraphLayout().getLayouts().containsKey(this)) {
Point2D average = averagePoint(oldGraph.getVertices());
getGraphLayout().put(this, average);
}

super.setGraph(graph);
// https://sourceforge.net/tracker/?func=detail&aid=3551320&group_id=73840&atid=539119
setVertexOrder(Lists.newArrayList(getGraph().getVertices()));
}

private Point2D averagePoint(Collection<Note> notes) {
List<Double> xs = Lists.newArrayList();
List<Double> ys = Lists.newArrayList();
for (Note note : notes) {
Point2D point = getGraphLayout().transform(note);
xs.add(point.getX());
ys.add(point.getY());
}
double x = StatUtils.mean(Doubles.toArray(xs));
double y = StatUtils.mean(Doubles.toArray(ys));
return new Point2D.Double(x, y);
}

(of course, this will break if the user changes the mutable oldGraph and it would be better if the Graph were an ObservableGraph and we didn't need to respond to explicit setGraph calls at all)