001: /**
002: * Copyright (c) 2004-2006 Regents of the University of California.
003: * See "license-prefuse.txt" for licensing terms.
004: */package prefuse.action.assignment;
005:
006: import java.util.logging.Logger;
007:
008: import prefuse.action.EncoderAction;
009: import prefuse.data.expression.Predicate;
010: import prefuse.data.expression.parser.ExpressionParser;
011: import prefuse.util.ColorLib;
012: import prefuse.util.PrefuseLib;
013: import prefuse.visual.VisualItem;
014:
015: /**
016: * <p>Assignment Action that assigns color values to VisualItems for a
017: * given color field (e.g., the stroke, text, or fill color).</p>
018: *
019: * <p>By default, a ColorAction simply assigns a single default color value
020: * to all items (the initial default color is black). Clients can change this
021: * default value to achieve uniform color assignment, or can add any number
022: * of additional rules for color assignment. Rules are specified by a Predicate
023: * instance which, if returning true, will trigger that rule, causing either the
024: * provided color value or the result of a delegate ColorAction to be
025: * applied. Rules are evaluated in the order in which they are added to the
026: * ColorAction, so earlier rules will have precedence over rules added later.
027: * </p>
028: *
029: * <p>In addition, subclasses can simply override {@link #getColor(VisualItem)}
030: * to achieve custom color assignment. In some cases, this may be the simplest
031: * or most flexible approach.</p>
032: *
033: * <p>To automatically assign color values based on varying values of a
034: * particular data field, consider using the DataColorAction.</p>
035: *
036: * <p>Color values are represented using integers, into which 8-bit values for
037: * the red, green, blue, and alpha channels are stored. For more information
038: * and utilities for creating and manipulating color values, see the
039: * {@link prefuse.util.ColorLib} class.</p>
040: *
041: * @author <a href="http://jheer.org">jeffrey heer</a>
042: * @see prefuse.util.ColorLib
043: * @see DataColorAction
044: */
045: public class ColorAction extends EncoderAction {
046:
047: protected String m_colorField;
048: protected String m_startField;
049: protected String m_endField;
050:
051: protected int m_cidx, m_sidx, m_eidx;
052:
053: protected int m_defaultColor = ColorLib.gray(0); // initial default = black
054:
055: /**
056: * Constructor, sets the data group and color field for color assignment.
057: * Uses an initial default color value of black [RGB value (0,0,0)].
058: * @param group the data group processed by this Action
059: * @param field the color field assigned by this Action
060: */
061: public ColorAction(String group, String field) {
062: super (group);
063: setField(field);
064: }
065:
066: /**
067: * Constructor, sets the data group, color field, and default color value
068: * for color assignment.
069: * @param group the data group processed by this Action
070: * @param field the color field assigned by this Action
071: * @param color the default color value assigned by this ColorAction
072: */
073: public ColorAction(String group, String field, int color) {
074: this (group, field);
075: m_defaultColor = color;
076: }
077:
078: /**
079: * Constructor, sets the data group, filter predicate and color field
080: * for color assignment.
081: * Uses an initial default color value of black [RGB value (0,0,0)].
082: * @param group the data group processed by this Action
083: * @param filter the filter predicate
084: * {@link prefuse.data.expression.Predicate}
085: * @param field the color field assigned by this Action
086: */
087: public ColorAction(String group, Predicate filter, String field) {
088: super (group, filter);
089: setField(field);
090: }
091:
092: /**
093: * Constructor, sets the data group, filter predicate,
094: * color field, and default color value for color assignment.
095: * @param group the data group processed by this Action
096: * @param filter the filter predicate
097: * {@link prefuse.data.expression.Predicate}
098: * @param field the color field assigned by this Action
099: * @param color the default color value assigned by this ColorAction
100: */
101: public ColorAction(String group, Predicate filter, String field,
102: int color) {
103: this (group, filter, field);
104: setDefaultColor(color);
105: }
106:
107: /**
108: * Set the color field name that this ColorAction should set. The
109: * ColorAction will automatically try to update the start and end
110: * values for this field if it is an interpolated field.
111: * @param field
112: */
113: public void setField(String field) {
114: m_colorField = field;
115: m_startField = PrefuseLib.getStartField(field);
116: m_endField = PrefuseLib.getEndField(field);
117: }
118:
119: /**
120: * Returns the default color for this ColorAction
121: * @return the default color value
122: */
123: public int getDefaultColor() {
124: return m_defaultColor;
125: }
126:
127: /**
128: * Sets the default color for this ColorAction. Items will be assigned
129: * the default color if they do not match any registered rules.
130: * @param color the new default color
131: */
132: public void setDefaultColor(int color) {
133: m_defaultColor = color;
134: }
135:
136: /**
137: * Add a color mapping rule to this ColorAction. VisualItems that match
138: * the provided predicate will be assigned the given color value (assuming
139: * they do not match an earlier rule).
140: * @param p the rule Predicate
141: * @param color the color value
142: */
143: public void add(Predicate p, int color) {
144: super .add(p, new Integer(color));
145: }
146:
147: /**
148: * Add a color mapping rule to this ColorAction. VisualItems that match
149: * the provided expression will be assigned the given color value (assuming
150: * they do not match an earlier rule). The provided expression String will
151: * be parsed to generate the needed rule Predicate.
152: * @param expr the expression String, should parse to a Predicate.
153: * @param color the color value
154: * @throws RuntimeException if the expression does not parse correctly or
155: * does not result in a Predicate instance.
156: */
157: public void add(String expr, int color) {
158: Predicate p = (Predicate) ExpressionParser.parse(expr);
159: add(p, color);
160: }
161:
162: /**
163: * Add a color mapping rule to this ColorAction. VisualItems that match
164: * the provided predicate will be assigned the color value returned by
165: * the given ColorAction's getColor() method.
166: * @param p the rule Predicate
167: * @param f the delegate ColorAction to use
168: */
169: public void add(Predicate p, ColorAction f) {
170: super .add(p, f);
171: }
172:
173: /**
174: * Add a color mapping rule to this ColorAction. VisualItems that match
175: * the provided expression will be assigned the given color value (assuming
176: * they do not match an earlier rule). The provided expression String will
177: * be parsed to generate the needed rule Predicate.
178: * @param expr the expression String, should parse to a Predicate.
179: * @param f the delegate ColorAction to use
180: * @throws RuntimeException if the expression does not parse correctly or
181: * does not result in a Predicate instance.
182: */
183: public void add(String expr, ColorAction f) {
184: Predicate p = (Predicate) ExpressionParser.parse(expr);
185: super .add(p, f);
186: }
187:
188: // ------------------------------------------------------------------------
189:
190: /**
191: * @see prefuse.action.ItemAction#process(prefuse.visual.VisualItem, double)
192: */
193: public void process(VisualItem item, double frac) {
194: int c = getColor(item);
195: int o = item.getInt(m_colorField);
196: item.setInt(m_startField, o);
197: item.setInt(m_endField, c);
198: item.setInt(m_colorField, c);
199: }
200:
201: /**
202: * Returns a color value for the given item. Colors are represented as
203: * integers, interpreted as holding values for the red, green, blue, and
204: * alpha channels. This is the same color representation returned by
205: * the Color.getRGB() method.
206: * @param item the item for which to get the color value
207: * @return the color value for the item
208: */
209: public int getColor(VisualItem item) {
210: Object o = lookup(item);
211: if (o != null) {
212: if (o instanceof ColorAction) {
213: return ((ColorAction) o).getColor(item);
214: } else if (o instanceof Integer) {
215: return ((Integer) o).intValue();
216: } else {
217: Logger.getLogger(this .getClass().getName()).warning(
218: "Unrecognized Object from predicate chain.");
219: }
220: }
221: return m_defaultColor;
222: }
223:
224: } // end of class ColorAction
|