Well ok, let's say you hover and then click an item of the view, the item always has a startAngle and an endAngle associated for drawing the arc. Let's assume one item has the startAngle 2.3 and the endAngle 2.7 (values between 0 and 2 PI obviously). Then I simply want to transform this item to the new root. That is considering the screenshot as an example -- if someone clicks on "eclipse 3.7" it's getting the new root with the subtree items adjusted. But currently it's implemented as if the items didn't exist before, that is diffs between two tree-revisions are calculated and then the extends (the startAngle/endAngle) based on the descendant-or-self count and the modification-count of each node.
Instead I'd now like to transform the existing items or generate new items thereof but with the angles adjusted. Clearly the new root must have startAngle 0 and endAngle 2 * PI. Now I somehow don't get how to adjust the items in the subtree to the new parent size such that the angles are scaled:
- /**
- * Transforms a subtree into the new root.
- *
- * @param pHitItemIndex
- * index of the item to represent as the new root
- */
- @SuppressWarnings("unchecked")
- public void transformRoot(final int pHitItemIndex) {
- checkArgument(pHitItemIndex >= 0, "pHitItemIndex must be >=0!");
- checkNotNull(mBuffer);
- final IModel<?, ?> model = mControl.getModel();
- final int depth = ((SunburstItem)model.getItem(pHitItemIndex)).getDepth();
- final ListIterator<SunburstItem> items =
- ((AbsModel<SunburstContainer, SunburstItem>)model).listIterator(pHitItemIndex);
- final List<SunburstItem> newItems = Lists.newArrayList();
- int itemDepth = depth;
- int index = 0;
- int parentIndex = 0;
- SunburstItem oldParent = null;
- SunburstItem newParent = null;
- // New root node.
- if (items.hasNext()) {
- oldParent = items.next();
- final SunburstItem root = new SunburstItem(oldParent);
- root.update(mMappingMode, mBuffer);
- root.setAngleStart(0f);
- root.setAngleCenter(PConstants.PI);
- root.setAngleEnd(PConstants.TWO_PI);
- root.setDepth(0);
- root.setIndexToParent(-1);
- root.update(mMappingMode, mBuffer);
- newItems.add(root);
- newParent = root;
- index++;
- }
- if (items.hasNext()) {
- do {
- final SunburstItem oldChild = items.next();
- final SunburstItem newChild = new SunburstItem(oldChild);
- newChild.setAngleStart(newChild.getAngleStart() * newParent.getAngleEnd() / oldParent.getAngleStart());
- LOGWRAPPER.debug("angleStart: " + newChild.getAngleStart());
- newChild.setAngleEnd(newChild.getAngleEnd() * newParent.getAngleEnd() / oldParent.getAngleEnd());
- LOGWRAPPER.debug("angleEnd: " + newChild.getAngleEnd());
- newChild.setAngleCenter((newChild.getAngleEnd() - newChild.getAngleStart()) / 2f);
- newChild.setDepth(newChild.getDepth() - depth);
- newChild.setIndexToParent(parentIndex);
- newChild.update(mMappingMode, mBuffer);
- newItems.add(newChild);
- if (items.hasNext()) {
- final int nextIndex = items.nextIndex();
- final SunburstItem nextItem = (SunburstItem)model.getItem(nextIndex);
- if (nextItem.getIndexToParent() == nextIndex - 1) {
- newParent = newChild;
- oldParent = oldChild;
- parentIndex = index;
- }
- itemDepth = nextItem.getDepth();
- }
- index++;
- } while (items.hasNext() && itemDepth > depth);
- }
- mControl.setItems(newItems);
- update();
- }
So, the new angles are not correct within this calculation (I'm receiving an AssertionError, that the first newChild.
setAngleStart(...) is not between 0 and 2*PI) and I don't know but it seems I'm too stupid right now to get the formula right which must be really easy.
Thanks for your interest, it's a great motivation. This visualization is part of my master thesis and uses a treebased database system and is a maven module (and uses Swing/Java7). I'll provide it on github in about one or two months.
kind regards,
Johannes