// recursive draw routine public void drawNode( TopoTreeNode node, int left, int right, int level, int px, int py, boolean drawNode, Tag t) { boolean draw_full = false; boolean self_in_tag = t == null ? true : (t.part_components.contains(node) || t.full_components.contains(node)); if (!self_in_tag) { return; } // draw the edge to its parent if (px != -1) { if (t != null && t.part_components.contains(node)) { stroke(t.tag_color.getRed(), t.tag_color.getGreen(), t.tag_color.getBlue()); if (t == m_ttable.topTag()) { strokeWeight(3.f); } else { strokeWeight(2.f); } } else { if (t != null && t.full_components.contains(node)) { draw_full = true; stroke(t.tag_color.getRed(), t.tag_color.getGreen(), t.tag_color.getBlue()); if (t == m_ttable.topTag() || t == m_ttable.topNonListedTag()) { strokeWeight(3.f); } else { strokeWeight(2.f); } } else { stroke(128); strokeWeight(1.f); } } // line((left + right) / 2, level_size * (level + 1), px, py); } // break out if there's no room to recurse if (left != right) { // slice up the remaining space int topsize = 0; for (TopoTreeNode ttn : node.children) { if (ttn.num_points >= ignore_component_size) topsize += ttn.num_points; } int newleft = left; int newright = left; for (TopoTreeNode ttn : node.children) { boolean child_in_tag = t == null ? true : (t.part_components.contains(ttn) || t.full_components.contains(ttn)); if (ttn.num_points >= ignore_component_size) { newright += (int) Math.round((right - left) * ((float) ttn.num_points) / ((float) topsize)); drawNode( ttn, newleft, newright, level + 1, (left + right) / 2, level_size * (level + 1), true, t); newleft = newright; } else { if (child_in_tag && t != null) { draw_full = true; } } } } node.x = (left + right) / 2; node.y = level_size * (level + 1); // draw the node if ((drawNode || node.hilighted) && !node.isSameAsChild) { // chose color based on tags if (draw_full && t != null) { fill(t.tag_color.getRed(), t.tag_color.getGreen(), t.tag_color.getBlue()); } else { fill(PrettyColors.Grey.getRed(), PrettyColors.Grey.getGreen(), PrettyColors.Grey.getBlue()); } stroke(0); if (!node.hilighted) noStroke(); int node_size = DEF_NODE_SIZE; if (node.hilighted || (draw_full && t == m_ttable.topTag())) { node_size = 3 * DEF_NODE_SIZE; } if (t != null && !draw_full) return; rect( (left + right) / 2 - node_size / 2, level_size * (level + 1) - node_size / 2, node_size, node_size); if (node.hilighted) { if (draw_full) { stroke( 2 * t.tag_color.getRed() / 3, 2 * t.tag_color.getGreen() / 3, 2 * t.tag_color.getBlue() / 3); } strokeWeight(2.f); rect( (left + right) / 2 - 3 * node_size / 4, level_size * (level + 1) - 3 * node_size / 4, 3 * node_size / 2, 3 * node_size / 2); } stroke(0); strokeWeight(1.f); } }