Something to consider when looking into https://sourceforge.net/tracker/?func=detail&aid=3551320&group_id=73840&atid=539119
I have an AggregateLayout with several CircleLayouts. There is a workaround above which allows the user to change the Size or Graph of each CircleLayout after it is initialised.
However, there is still one more problem. Lets say there is only one CircleLayout and it is displaying a subGraph in a little circle. If the user moves vertices (contained in the CircleLayout) and then adds some more vertices to its Graph, then the user's translations are ignored and the subGraph is again drawn at the original location.
There are two ways to think about how the AggregateLayout *should* behave: (a) remember the user's translations for each node or (b) to calculate the average of all the vertices in the subLayout and use it as the new centre.
I'm afraid I cannot do a workaround because every time I try to get the location of a vertex (by calling AggregateLayout.transform) then it doesn't seem to tell me the user's translations.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
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)