001 package org.shiftone.jrat.provider.tree.ui.trace.pie; 002 003 004 import org.shiftone.jrat.provider.tree.ui.TraceTreeNode; 005 import org.shiftone.jrat.provider.tree.ui.trace.PercentColorLookup; 006 import org.shiftone.jrat.provider.tree.ui.trace.graph.BufferedJComponent; 007 import org.shiftone.jrat.util.log.Logger; 008 009 import java.awt.*; 010 011 012 /** 013 * @author jeff@shiftone.org (Jeff Drost) 014 */ 015 public class PieGraphComponent extends BufferedJComponent { 016 017 private static final Logger LOG = Logger.getLogger(PieGraphComponent.class); 018 private TraceTreeNode root; 019 private PercentColorLookup colorLookup = new PercentColorLookup(); 020 021 public synchronized void setStackTreeNode(TraceTreeNode root) { 022 023 this.root = root; 024 025 dataChanged(); 026 027 if (isVisible()) { 028 repaint(); 029 } 030 } 031 032 033 protected void paintBuffer(Graphics2D g) { 034 035 double totalRadius = Math.min(getWidth(), getHeight()) / 2; 036 int x = getWidth() / 2; 037 int y = getHeight() / 2; 038 039 // int maxDepth = getMaxEffectiveDepth(root) ; 040 int maxDepth = 10; 041 double radiusDelta = totalRadius / maxDepth; 042 043 paintNode(g, root, x, y, radiusDelta, 0, 360, 1, maxDepth); 044 } 045 046 047 public int getMaxEffectiveDepth(TraceTreeNode node) { 048 049 int maxChildDepth = 0; 050 051 for (int i = 0; i < node.getChildCount(); i++) { 052 TraceTreeNode child = (TraceTreeNode) node.getChildAt(i); 053 054 if (child.getTotalDuration() > 0) { 055 maxChildDepth = Math.max(maxChildDepth, getMaxEffectiveDepth(child)); 056 } 057 } 058 059 return 1 + maxChildDepth; 060 } 061 062 063 public void paintNode(Graphics2D g, TraceTreeNode node, int x, int y, double radiusDelta, int min, int max, 064 int depth, int maxDepth) { 065 066 if ((node == null) || (depth > maxDepth)) { 067 return; 068 } 069 070 long totalDegrees = max - min; 071 long totalNanos = node.getTotalDuration(); 072 073 if ((totalNanos > 0) && (node.getChildCount() > 0)) { 074 int startDegrees = min; 075 076 for (int i = 0; i < node.getChildCount(); i++) { 077 TraceTreeNode child = (TraceTreeNode) node.getChildAt(i); 078 long partNanos = child.getTotalDuration(); 079 int partDegrees = (int) ((partNanos * totalDegrees) / totalNanos); 080 081 if (partDegrees > 1) { 082 paintNode(g, child, x, y, radiusDelta, startDegrees, startDegrees + partDegrees, depth + 1, 083 maxDepth); 084 } 085 086 startDegrees += partDegrees; 087 } 088 } 089 090 int radius = (int) (radiusDelta * depth); 091 int diameter = radius * 2; 092 093 g.setColor(colorLookup.getColor(node.getPctOfAvgParentDuration())); 094 g.fillArc(x - radius, y - radius, diameter, diameter, min, max - min); 095 } 096 }