JAL-4033 TODO re highlighting current column selection
[jalview.git] / src / jalview / renderer / ContactMapRenderer.java
1 /**
2  * 
3  */
4 package jalview.renderer;
5
6 import jalview.api.AlignViewportI;
7 import jalview.datamodel.AlignmentAnnotation;
8 import jalview.datamodel.Annotation;
9 import jalview.datamodel.ColumnSelection;
10 import jalview.datamodel.ContactListI;
11 import jalview.datamodel.ContactRange;
12 import jalview.datamodel.HiddenColumns;
13 import jalview.renderer.api.AnnotationRowRendererI;
14
15 import java.awt.Color;
16 import java.awt.Graphics;
17
18 /**
19  * @author jprocter
20  *
21  */
22 public class ContactMapRenderer implements AnnotationRowRendererI
23 {
24
25   @Override
26   public void renderRow(Graphics g, int charWidth, int charHeight,
27           boolean hasHiddenColumns, AlignViewportI viewport, HiddenColumns hiddenColumns,
28           ColumnSelection columnSelection, AlignmentAnnotation _aa,
29           Annotation[] aa_annotations, int sRes, int eRes, float min,
30           float max, int y)
31   {
32     if (sRes > aa_annotations.length)
33     {
34       return;
35     }
36     eRes = Math.min(eRes, aa_annotations.length);
37
38     int x = 0, y2 = y;
39
40     g.setColor(Color.pink);
41
42     g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
43
44     int column;
45     int aaMax = aa_annotations.length - 1;
46     while (x < eRes - sRes)
47     {
48       column = sRes + x;
49       if (hasHiddenColumns)
50       {
51         column = hiddenColumns.visibleToAbsoluteColumn(column);
52       }
53       // // TODO: highlight columns selected
54       // boolean colsel = false;
55       // if (columnSelection != null)
56       // {
57       // colsel = columnSelection.contains(column);
58       // }
59
60       if (column > aaMax)
61       {
62         break;
63       }
64
65       if (aa_annotations[column] == null)
66       {
67         x++;
68         continue;
69       }
70       if (_aa.sequenceRef != null)
71       {
72         // get the sequence position for the column
73         column = _aa.sequenceRef.findPosition(column) - 1;
74       }
75       ContactListI contacts = viewport.getContactList(_aa, column);
76       if (contacts == null)
77       {
78         return;
79       }
80       int contact_height = contacts.getContactHeight();
81       // fractional number of contacts covering each pixel
82       double contacts_per_pixel = ((double) contact_height)
83               / ((double) _aa.graphHeight);
84
85       int pixels_step;
86
87       if (contacts_per_pixel >= 1)
88       {
89         // many contacts rendered per pixel
90         pixels_step = 1;
91       }
92       else
93       {
94         // pixel height for each contact
95         pixels_step = (int) Math
96                 .ceil(((double) _aa.graphHeight) / (double) contact_height);
97       }
98
99       int cstart = 0, cend;
100
101       for (int ht = y2,
102               eht = y2 - _aa.graphHeight; ht >= eht; ht -= pixels_step)
103       {
104         cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
105         cend = (int) Math.min(contact_height,
106                 Math.ceil(cstart + contacts_per_pixel * pixels_step));
107
108         // TODO show maximum colour for range - sort of done
109         // also need a 'getMaxPosForRange(start,end)' to accurately render
110         Color col = getColorForRange(min, max, contacts, cstart, cend);
111
112         // TODO: show selected region
113         // if (colsel || columnSelection!=null &&
114         // columnSelection.intersects(cstart,cend))
115         // {
116         // g.setColor(col.brighter());
117         // }
118         // else
119         {
120           g.setColor(col);
121         }
122         if (pixels_step > 1)
123         {
124           g.fillRect(x * charWidth, ht, charWidth, 1 + pixels_step);
125         }
126         else
127         {
128           g.drawLine(x * charWidth, ht, (x + 1) * charWidth, ht);
129         }
130       }
131       x++;
132     }
133
134   }
135
136   Color minColor = Color.white, maxColor = Color.magenta;
137
138   Color shadeFor(float min, float max, float value)
139   {
140     return jalview.util.ColorUtils.getGraduatedColour(value, 0, minColor,
141             max, maxColor);
142   }
143
144   public Color getColorForRange(float min, float max, ContactListI cl,
145           int i, int j)
146   {
147     ContactRange cr = cl.getRangeFor(i, j);
148     // average for moment - probably more interested in maxIntProj though
149     return shadeFor(min, max, (float) cr.getMean());
150   }
151
152 }