/**
   * Render cells, starting at specified item.
   *
   * @param graphics
   * @param treemap
   * @param item
   * @param active
   */
  public void renderTree(TreemapGraphics graphics, Treemap treemap, Object item, boolean active) {
    TreemapCell cell = treemap.getCell(item);
    if (cell == null) {
      return;
    }
    boolean visible = cell.isLeaf() || cell.getFramed() != null;
    Object value = cell.getValue();

    if (active) {
      if (visible) {
        graphics.fill(cell, colorProvider.getHighlightColor(item, value));
      }
    } else {
      Rectangle borders = cell.getBorders();
      if (borders != null) {
        graphics.fill(borders, colorProvider.getBorderColor(item, value));
      }
      if (visible) {
        Color color1 = colorProvider.getBackgroundColor(item, value);
        Color color2 = colorProvider.getBackgroundGradientColor(item, value);
        graphics.fill(cell, color1, color2);
      }
    }
    if (!cell.isLeaf()) {
      Rectangle framed = cell.getFramed();
      if (framed != null) {
        graphics.fill(framed, colorProvider.getBorderColor(item, value));
      }
      for (Object node : cell.getChildren()) {
        renderTree(graphics, treemap, node, false);
      }
    }
  }
 private void renderLabels(
     TreemapGraphics graphics, Treemap treemap, Object item, boolean forked, int levels) {
   if (levels == 0) {
     return;
   }
   TreemapCell cell = treemap.getCell(item);
   if (cell == null) {
     return;
   }
   boolean attachLabel;
   switch (attachLabelMode) {
     case AnyVisible:
       attachLabel = cell.isLeaf() || cell.getFramed() != null;
       break;
     case VisibleForked:
       attachLabel = cell.isLeaf() || cell.getFramed() != null || forked;
       break;
     default:
       attachLabel = true;
   }
   if (attachLabel) {
     if (renderLabel(graphics, cell, item) && cell.getFramed() != null) {
       renderChildrenLabels(graphics, treemap, cell.getChildren(), levels - 1);
     }
   } else if (attachLabelMode != AttachLabelMode.TopLevelsOnly) {
     renderChildrenLabels(graphics, treemap, cell.getChildren(), levels - 1);
   }
 }
  private boolean renderLabel(TreemapGraphics graphics, TreemapCell cell, Object item) {
    Rectangle framed = cell.getFramed();
    int width = framed != null ? (cell.width - framed.width) / 2 : cell.width;
    int height = framed != null ? (cell.height - framed.height) / 2 : cell.height;
    Object value = cell.getValue();
    String label = labelProvider.getText(item, value);
    Dimension dimension = graphics.getDimension(label);
    Point anchor = null;
    boolean vertical = false;
    if (dimension.width <= cell.width - labelSpaceLR
        && dimension.height <= height - labelSpaceTB) { // string fits horizontally
      anchor = new Point((cell.width - dimension.width) / 2, (height - dimension.height) / 2);
    } else if (dimension.width <= cell.height - labelSpaceLR
        && dimension.height <= width - labelSpaceTB) { // string fits vertically
      anchor = new Point((width - dimension.height) / 2, (cell.height + dimension.width) / 2);
      vertical = true;
    } else if (truncateLabelMode
        != TruncateLabelMode.NoTruncate) { // string doesn't fit, try to truncate...
      String hLabel = null;
      if (dimension.height <= height - labelSpaceTB) {
        hLabel = truncateLabel(label, cell.width - labelSpaceLR, dimension.width, 3);
      }
      String vLabel = null;
      if (dimension.height <= width - labelSpaceTB
          && (hLabel == null || cell.height > cell.width)) {
        vLabel = truncateLabel(label, cell.height - labelSpaceLR, dimension.width, 3);
      }
      if (hLabel != null
          && (vLabel == null || hLabel.length() >= vLabel.length())) { // ... horizontally
        dimension = graphics.getDimension(hLabel);
        anchor = new Point((cell.width - dimension.width) / 2, (height - dimension.height) / 2);
        label = hLabel;
      } else if (vLabel != null) { // ... vertically
        dimension = graphics.getDimension(vLabel);
        anchor = new Point((width - dimension.height) / 2, (cell.height + dimension.width) / 2);
        label = vLabel;
        vertical = true;
      }
    }
    if (anchor == null) {
      return false;
    }
    // label background in dark gray
    Color shadow = colorProvider.getForegroundShadowColor(item, value);
    if (shadow != null) {
      graphics.draw(label, cell.x + anchor.x + 1, cell.y + anchor.y, shadow, vertical);
      graphics.draw(label, cell.x + anchor.x - 1, cell.y + anchor.y, shadow, vertical);
      graphics.draw(label, cell.x + anchor.x, cell.y + anchor.y + 1, shadow, vertical);
      graphics.draw(label, cell.x + anchor.x, cell.y + anchor.y - 1, shadow, vertical);
    }
    // label in foreground color
    Color foreground = colorProvider.getForegroundColor(item, value);
    graphics.draw(label, cell.x + anchor.x, cell.y + anchor.y, foreground, vertical);

    return true;
  }