001: package prefuse.render;
002:
003: import java.awt.FontMetrics;
004: import java.awt.Graphics2D;
005: import java.awt.Shape;
006: import java.awt.geom.AffineTransform;
007: import java.awt.geom.Line2D;
008: import java.awt.geom.Point2D;
009: import java.awt.geom.Rectangle2D;
010:
011: import prefuse.Constants;
012: import prefuse.util.ColorLib;
013: import prefuse.util.GraphicsLib;
014: import prefuse.visual.VisualItem;
015:
016: /**
017: * Renderer for drawing an axis tick mark and label.
018: *
019: * @author <a href="http://jheer.org">jeffrey heer</a>
020: * @author jgood
021: */
022: public class AxisRenderer extends AbstractShapeRenderer {
023:
024: private Line2D m_line = new Line2D.Double();
025: private Rectangle2D m_box = new Rectangle2D.Double();
026:
027: private int m_xalign;
028: private int m_yalign;
029: private int m_ascent;
030:
031: /**
032: * Create a new AxisRenderer. By default, axis labels are drawn along the
033: * left edge and underneath the tick marks.
034: */
035: public AxisRenderer() {
036: this (Constants.LEFT, Constants.BOTTOM);
037: }
038:
039: /**
040: * Create a new AxisRenderer.
041: * @param xalign the horizontal alignment for the axis label. One of
042: * {@link prefuse.Constants#LEFT}, {@link prefuse.Constants#RIGHT},
043: * or {@link prefuse.Constants#CENTER}.
044: * @param yalign the vertical alignment for the axis label. One of
045: * {@link prefuse.Constants#TOP}, {@link prefuse.Constants#BOTTOM},
046: * or {@link prefuse.Constants#CENTER}.
047: */
048: public AxisRenderer(int xalign, int yalign) {
049: m_xalign = xalign;
050: m_yalign = yalign;
051: }
052:
053: /**
054: * Set the horizontal alignment of axis labels.
055: * @param xalign the horizontal alignment for the axis label. One of
056: * {@link prefuse.Constants#LEFT}, {@link prefuse.Constants#RIGHT},
057: * or {@link prefuse.Constants#CENTER}.
058: */
059: public void setHorizontalAlignment(int xalign) {
060: m_xalign = xalign;
061: }
062:
063: /**
064: * Set the vertical alignment of axis labels.
065: * @param yalign the vertical alignment for the axis label. One of
066: * {@link prefuse.Constants#TOP}, {@link prefuse.Constants#BOTTOM},
067: * or {@link prefuse.Constants#CENTER}.
068: */
069: public void setVerticalAlignment(int yalign) {
070: m_yalign = yalign;
071: }
072:
073: /**
074: * @see prefuse.render.AbstractShapeRenderer#getRawShape(prefuse.visual.VisualItem)
075: */
076: protected Shape getRawShape(VisualItem item) {
077: double x1 = item.getDouble(VisualItem.X);
078: double y1 = item.getDouble(VisualItem.Y);
079: double x2 = item.getDouble(VisualItem.X2);
080: double y2 = item.getDouble(VisualItem.Y2);
081: m_line.setLine(x1, y1, x2, y2);
082:
083: if (!item.canGetString(VisualItem.LABEL))
084: return m_line;
085:
086: String label = item.getString(VisualItem.LABEL);
087: if (label == null)
088: return m_line;
089:
090: FontMetrics fm = DEFAULT_GRAPHICS
091: .getFontMetrics(item.getFont());
092: m_ascent = fm.getAscent();
093: int h = fm.getHeight();
094: int w = fm.stringWidth(label);
095:
096: double tx, ty;
097:
098: // get text x-coord
099: switch (m_xalign) {
100: case Constants.FAR_RIGHT:
101: tx = x2 + 2;
102: break;
103: case Constants.FAR_LEFT:
104: tx = x1 - w - 2;
105: break;
106: case Constants.CENTER:
107: tx = x1 + (x2 - x1) / 2 - w / 2;
108: break;
109: case Constants.RIGHT:
110: tx = x2 - w;
111: break;
112: case Constants.LEFT:
113: default:
114: tx = x1;
115: }
116: // get text y-coord
117: switch (m_yalign) {
118: case Constants.FAR_TOP:
119: ty = y1 - h;
120: break;
121: case Constants.FAR_BOTTOM:
122: ty = y2;
123: break;
124: case Constants.CENTER:
125: ty = y1 + (y2 - y1) / 2 - h / 2;
126: break;
127: case Constants.TOP:
128: ty = y1;
129: break;
130: case Constants.BOTTOM:
131: default:
132: ty = y2 - h;
133: }
134: m_box.setFrame(tx, ty, w, h);
135: return m_box;
136: }
137:
138: /**
139: * @see prefuse.render.Renderer#render(java.awt.Graphics2D, prefuse.visual.VisualItem)
140: */
141: public void render(Graphics2D g, VisualItem item) {
142: Shape s = getShape(item);
143: GraphicsLib.paint(g, item, m_line, getStroke(item),
144: getRenderType(item));
145:
146: // check if we have a text label, if so, render it
147: if (item.canGetString(VisualItem.LABEL)) {
148: float x = (float) m_box.getMinX();
149: float y = (float) m_box.getMinY() + m_ascent;
150:
151: // draw label background
152: GraphicsLib.paint(g, item, s, null, RENDER_TYPE_FILL);
153:
154: String str = item.getString(VisualItem.LABEL);
155: AffineTransform origTransform = g.getTransform();
156: AffineTransform transform = this .getTransform(item);
157: if (transform != null)
158: g.setTransform(transform);
159:
160: g.setFont(item.getFont());
161: g.setColor(ColorLib.getColor(item.getTextColor()));
162: g.drawString(str, x, y);
163:
164: if (transform != null)
165: g.setTransform(origTransform);
166: }
167: }
168:
169: /**
170: * @see prefuse.render.Renderer#locatePoint(java.awt.geom.Point2D, prefuse.visual.VisualItem)
171: */
172: public boolean locatePoint(Point2D p, VisualItem item) {
173: Shape s = getShape(item);
174: if (s == null) {
175: return false;
176: } else if (s == m_box && m_box.contains(p)) {
177: return true;
178: } else {
179: double width = Math.max(2, item.getSize());
180: double halfWidth = width / 2.0;
181: return s.intersects(p.getX() - halfWidth, p.getY()
182: - halfWidth, width, width);
183: }
184: }
185:
186: /**
187: * @see prefuse.render.Renderer#setBounds(prefuse.visual.VisualItem)
188: */
189: public void setBounds(VisualItem item) {
190: if (!m_manageBounds)
191: return;
192: Shape shape = getShape(item);
193: if (shape == null) {
194: item.setBounds(item.getX(), item.getY(), 0, 0);
195: } else if (shape == m_line) {
196: GraphicsLib.setBounds(item, shape, getStroke(item));
197: } else {
198: m_box.add(m_line.getX1(), m_line.getY1());
199: m_box.add(m_line.getX2(), m_line.getY2());
200: item.setBounds(m_box.getMinX(), m_box.getMinY(), m_box
201: .getWidth(), m_box.getHeight());
202: }
203: }
204:
205: } // end of class AxisRenderer
|