001    package jigcell.compare.compare2;
002    
003    import java.awt.Color;
004    import java.util.ArrayList;
005    import java.util.List;
006    import javax.swing.JTable;
007    import jigcell.compare.data.SparseTreeDataElement;
008    import jigcell.compare.impl.Compare;
009    import jigcell.compare.views.ObjectiveSeriesView;
010    
011    /**
012     * A table renderer that can color the view of a Compare^2.  The coloring policy is to color by the relative order from the threshold.
013     *
014     * <p>
015     * This code is licensed under the DARPA BioCOMP Open Source License.  See LICENSE for more details.
016     * </p>
017     *
018     * @author Nicholas Allen
019     */
020    
021    public class ThresholdRelativeViewColorer extends TriColorViewColorer {
022    
023       /**
024        * Transparency adjustment value
025        */
026    
027       protected final static float TRANSPARENCY_ADJUST = 0.5f;
028    
029       /**
030        * Number of groups to divide into
031        */
032    
033       protected int groups;
034    
035       /**
036        * A single or collection of colorers that can color a view.
037        *
038        * @param view View
039        */
040    
041       public static Object getInstances (Compare2 view) {
042          List list = new ArrayList ();
043          list.add (new ThresholdRelativeViewColorer (view, 1));
044          list.add (new ThresholdRelativeViewColorer (view, 0));
045          list.add (new ThresholdRelativeViewColorer (view, 4));
046          list.add (new ThresholdRelativeViewColorer (view, 5));
047          return list;
048       }
049    
050       /**
051        * Creates a new view colorer that colors by relative distances to threshold.
052        *
053        * @param view View to color
054        * @param groups Number of groups
055        */
056    
057       public ThresholdRelativeViewColorer (Compare2 view, int groups) {
058          super (view);
059          if (groups < 0)
060             throw new IllegalArgumentException ();
061          this.groups = groups;
062       }
063    
064       /**
065        * {@inheritDoc}
066        */
067    
068       public Color getColorForCell (JTable table, int row, int column, int data, double result) {
069          double threshold = SparseTreeDataElement.createElementSafe (model.getThresholdValue (row)).getRealValue ();
070          ObjectiveSeriesView.Comparison comparison = model.getComparisonType (row);
071          if (comparison == ObjectiveSeriesView.Comparison.IGNORE)
072             return null;
073          if (comparison == ObjectiveSeriesView.Comparison.EQUIVALENT)
074             threshold = 0.0;
075          else if (Double.isNaN (threshold) || Double.isInfinite (threshold))
076             return getColor ("TriColorViewColorer.backgroundUnderThreshold");
077          if (groups == 1)
078             return getColorForThresholdComparison (comparison, threshold, result);
079          String entries [] = getDataValues (table, row);
080          int count = -1;
081          int max = -1;
082          boolean greater = result > threshold;
083          for (int i = 0, l = entries.length; i < l; i++) {
084             String entry = entries [i];
085             if (entry == Compare2Model.VALUE_NOVALUE)
086                continue;
087             double result2 = Double.parseDouble (entry);
088             if (!Double.isNaN (result2) && result2 > threshold == greater) {
089                if (!Double.isInfinite (result2) && (result == result2 || result > result2 == greater))
090                   count++;
091                max++;
092             }
093          }
094          float adjust;
095          if (max == 0)
096             adjust = DEFAULT_TRANSPARENCY;
097          else {
098             if (groups == 0)
099                adjust = (float) count / (float) max;
100             else {
101                count = count * groups / max;
102                adjust = (float) (count == groups ? count - 1 : count) / (float) groups;
103             }
104             adjust = (adjust + TRANSPARENCY_ADJUST) / (TRANSPARENCY_ADJUST + 1.0f);
105          }
106          Color color = getColorForThresholdComparison (comparison, threshold, result);
107          if (color == null)
108             return null;
109          float colors [] = color.getColorComponents (null);
110          return new Color (colors [0], colors [1], colors [2], adjust * adjust);
111       }
112    
113       /**
114        * The number of groups to divide the cells into.
115        */
116    
117       public int getGroups () {
118          return groups;
119       }
120    
121       /**
122        * {@inheritDoc}
123        */
124    
125       public String getName () {
126          switch (groups) {
127             case 0 :
128                return Compare.getString ("ThresholdRelativeViewColorer.nameContinuous");
129             case 1 :
130                return Compare.getString ("ThresholdRelativeViewColorer.namePartition");
131             case 4 :
132                return Compare.getString ("ThresholdRelativeViewColorer.nameQuartile");
133             case 5 :
134                return Compare.getString ("ThresholdRelativeViewColorer.nameQuintile");
135          }
136          return Compare.formatString ("ThresholdRelativeViewColorer.nameFormat", new Long (groups));
137       }
138    
139       /**
140        * Sets the number of groups to divide cells into.
141        *
142        * @param groups Number of groups
143        */
144    
145       public void setGroups (int groups) {
146          this.groups = groups;
147       }
148    }