2 package jalview.renderer;
4 import jalview.analysis.AAFrequency;
5 import jalview.analysis.StructureFrequency;
6 import jalview.api.AlignViewportI;
7 import jalview.datamodel.AlignmentAnnotation;
8 import jalview.datamodel.Annotation;
9 import jalview.datamodel.ColumnSelection;
10 import jalview.schemes.ColourSchemeI;
12 import java.awt.BasicStroke;
13 import java.awt.Color;
15 import java.awt.FontMetrics;
16 import java.awt.Graphics;
17 import java.awt.Graphics2D;
18 import java.awt.Image;
19 import java.awt.font.LineMetrics;
20 import java.awt.geom.AffineTransform;
21 import java.awt.image.ImageObserver;
22 import java.util.Hashtable;
24 import com.stevesoft.pat.Regex;
26 public class AnnotationRenderer
29 public AnnotationRenderer()
31 // TODO Auto-generated constructor stub
34 public void drawStemAnnot(Graphics g, Annotation[] row_annotations,
35 int lastSSX, int x, int y, int iconOffset, int startRes,
36 int column, boolean validRes, boolean validEnd)
39 g.setColor(STEM_COLOUR);
40 int sCol = (lastSSX / charWidth) + startRes;
42 int x2 = (x * charWidth);
43 Regex closeparen = new Regex("(\\))");
45 String dc = (column == 0 || row_annotations[column - 1] == null) ? ""
46 : row_annotations[column - 1].displayCharacter;
48 boolean diffupstream = sCol == 0 || row_annotations[sCol - 1] == null
49 || !dc.equals(row_annotations[sCol - 1].displayCharacter);
50 boolean diffdownstream = !validRes || !validEnd
51 || row_annotations[column] == null
52 || !dc.equals(row_annotations[column].displayCharacter);
53 // System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
54 // If a closing base pair half of the stem, display a backward arrow
55 if (column > 0 && closeparen.search(dc))
59 // if (validRes && column>1 && row_annotations[column-2]!=null &&
60 // dc.equals(row_annotations[column-2].displayCharacter))
62 g.fillPolygon(new int[]
63 { lastSSX + 5, lastSSX + 5, lastSSX }, new int[]
64 { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
75 // display a forward arrow
78 g.fillPolygon(new int[]
79 { x2 - 5, x2 - 5, x2 }, new int[]
80 { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
89 g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
92 private int charWidth, endRes, charHeight;
94 private boolean validCharWidth, hasHiddenColumns;
96 private FontMetrics fm;
98 private final boolean MAC = new jalview.util.Platform().isAMac();
100 boolean av_renderHistogram = true, av_renderProfile = true,
101 av_normaliseProfile = false;
103 ColourSchemeI profcolour = null;
105 private ColumnSelection columnSelection;
107 private Hashtable[] hconsensus;
109 private Hashtable[] hStrucConsensus;
111 private boolean av_ignoreGapsConsensus;
114 * attributes set from AwtRenderPanelI
117 * old image used when data is currently being calculated and cannot be
120 private Image fadedImage;
123 * panel being rendered into
125 private ImageObserver annotationPanel;
128 * width of image to render in panel
130 private int imgWidth;
133 public void drawNotCanonicalAnnot(Graphics g, Color nonCanColor, Annotation[] row_annotations,
134 int lastSSX, int x, int y, int iconOffset, int startRes,
135 int column, boolean validRes, boolean validEnd)
137 //System.out.println(nonCanColor);
139 g.setColor(nonCanColor);
140 int sCol = (lastSSX / charWidth) + startRes;
142 int x2 = (x * charWidth);
143 Regex closeparen = new Regex("}|]|<|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z");
145 String dc = (column == 0 || row_annotations[column - 1] == null) ? ""
146 : row_annotations[column - 1].displayCharacter;
148 boolean diffupstream = sCol == 0 || row_annotations[sCol - 1] == null
149 || !dc.equals(row_annotations[sCol - 1].displayCharacter);
150 boolean diffdownstream = !validRes || !validEnd
151 || row_annotations[column] == null
152 || !dc.equals(row_annotations[column].displayCharacter);
153 // System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
154 // If a closing base pair half of the stem, display a backward arrow
155 if (column > 0 && closeparen.search(dc))// closeletter_b.search(dc)||closeletter_c.search(dc)||closeletter_d.search(dc)||closecrochet.search(dc)) )
159 // if (validRes && column>1 && row_annotations[column-2]!=null &&
160 // dc.equals(row_annotations[column-2].displayCharacter))
162 g.fillPolygon(new int[]
163 { lastSSX + 5, lastSSX + 5, lastSSX }, new int[]
164 { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
175 // display a forward arrow
178 g.fillPolygon(new int[]
179 { x2 - 5, x2 - 5, x2 }, new int[]
180 { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
189 g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
191 // public void updateFromAnnotationPanel(FontMetrics annotFM, AlignViewportI
193 public void updateFromAwtRenderPanel(AwtRenderPanelI annotPanel,
196 fm = annotPanel.getFontMetrics();
197 annotationPanel = annotPanel;
198 fadedImage = annotPanel.getFadedImage();
199 imgWidth = annotPanel.getFadedImageWidth();
200 updateFromAlignViewport(av);
203 public void updateFromAlignViewport(AlignViewportI av)
205 charWidth = av.getCharWidth();
206 endRes = av.getEndRes();
207 charHeight = av.getCharHeight();
208 hasHiddenColumns = av.hasHiddenColumns();
209 validCharWidth = av.isValidCharWidth();
210 av_renderHistogram = av.isShowConsensusHistogram();
211 av_renderProfile = av.isShowSequenceLogo();
212 av_normaliseProfile = av.isNormaliseSequenceLogo();
213 profcolour = av.getGlobalColourScheme();
214 if (profcolour == null)
216 // Set the default colour for sequence logo if the alignnent has no
218 profcolour = av.getAlignment().isNucleotide() ? new jalview.schemes.NucleotideColourScheme()
219 : new jalview.schemes.ZappoColourScheme();
221 columnSelection = av.getColumnSelection();
222 hconsensus = av.getSequenceConsensusHash();// hconsensus;
223 hStrucConsensus = av.getRnaStructureConsensusHash(); // hStrucConsensus;
224 av_ignoreGapsConsensus = av.getIgnoreGapsConsensus();
227 public int[] getProfileFor(AlignmentAnnotation aa, int column)
229 // TODO : consider refactoring the global alignment calculation
230 // properties/rendering attributes as a global 'alignment group' which holds
231 // all vis settings for the alignment as a whole rather than a subset
233 if (aa.autoCalculated && aa.label.startsWith("Consensus"))
235 if (aa.groupRef != null && aa.groupRef.consensusData != null
236 && aa.groupRef.isShowSequenceLogo())
238 return AAFrequency.extractProfile(
239 aa.groupRef.consensusData[column],
240 aa.groupRef.getIgnoreGapsConsensus());
242 // TODO extend annotation row to enable dynamic and static profile data to
244 if (aa.groupRef == null && aa.sequenceRef == null && av_renderProfile)
246 return AAFrequency.extractProfile(hconsensus[column],
247 av_ignoreGapsConsensus);
252 if (aa.autoCalculated && aa.label.startsWith("StrucConsensus"))
254 // TODO implement group structure consensus
256 * if (aa.groupRef != null && aa.groupRef.consensusData != null &&
257 * aa.groupRef.isShowSequenceLogo()) { //TODO check what happens for
258 * group selections return StructureFrequency.extractProfile(
259 * aa.groupRef.consensusData[column], aa.groupRef
260 * .getIgnoreGapsConsensus()); }
262 // TODO extend annotation row to enable dynamic and static profile data
265 if (aa.groupRef == null && aa.sequenceRef == null
266 && av_renderProfile && hStrucConsensus != null
267 && hStrucConsensus.length > column)
269 return StructureFrequency.extractProfile(hStrucConsensus[column],
270 av_ignoreGapsConsensus);
278 * Render the annotation rows associated with an alignment.
282 * data and view settings to render
284 * destination for graphics
286 * row where a mouse event occured (or -1)
288 * first column that will be drawn
290 * last column that will be drawn
291 * @return true if the fadedImage was used for any alignment annotation rows currently being calculated
293 public boolean drawComponent(AwtRenderPanelI annotPanel, AlignViewportI av,
294 Graphics g, int activeRow, int startRes, int endRes)
296 boolean usedFaded=false;
298 // AnnotationPanel needs to implement: ImageObserver, access to
300 updateFromAwtRenderPanel(annotPanel, av);
301 fm = g.getFontMetrics();
302 AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation();
309 boolean validRes = false;
310 boolean validEnd = false;
311 boolean labelAllCols = false;
312 boolean centreColLabels, centreColLabelsDef = av
313 .getCentreColumnLabels();
314 boolean scaleColLabel = false;
315 boolean[] graphGroupDrawn = new boolean[aa.length];
316 int charOffset = 0; // offset for a label
317 float fmWidth, fmScaling = 1f; // scaling for a label to fit it into a
319 Font ofont = g.getFont();
321 for (int i = 0; i < aa.length; i++)
323 AlignmentAnnotation row = aa[i];
324 Annotation[] row_annotations=row.annotations;
329 centreColLabels = row.centreColLabels || centreColLabelsDef;
330 labelAllCols = row.showAllColLabels;
331 scaleColLabel = row.scaleColLabel;
336 if (row.graphGroup > -1 && graphGroupDrawn[row.graphGroup])
341 // this is so that we draw the characters below the graph
346 iconOffset = charHeight - fm.getDescent();
350 else if (row.hasText)
352 iconOffset = charHeight - fm.getDescent();
360 if (row.autoCalculated && av.isCalculationInProgress(row))
364 g.drawImage(fadedImage, 0, y - row.height, imgWidth, y, 0, y
365 - row.height, imgWidth, y, annotationPanel);
366 g.setColor(Color.black);
367 // g.drawString("Calculating "+aa[i].label+"....",20, y-row.height/2);
373 * else if (annotationPanel.av.updatingConservation &&
374 * aa[i].label.equals("Conservation")) {
376 * y += charHeight; g.drawImage(annotationPanel.fadedImage, 0, y -
377 * row.height, annotationPanel.imgWidth, y, 0, y - row.height,
378 * annotationPanel.imgWidth, y, annotationPanel);
380 * g.setColor(Color.black); //
381 * g.drawString("Calculating Conservation.....",20, y-row.height/2);
383 * continue; } else if (annotationPanel.av.updatingConservation &&
384 * aa[i].label.equals("Quality")) {
386 * y += charHeight; g.drawImage(annotationPanel.fadedImage, 0, y -
387 * row.height, annotationPanel.imgWidth, y, 0, y - row.height,
388 * annotationPanel.imgWidth, y, annotationPanel); g.setColor(Color.black);
389 * // / g.drawString("Calculating Quality....",20, y-row.height/2);
393 // first pass sets up state for drawing continuation from left-hand column
395 x = (startRes == 0) ? 0 : -1;
396 while (x < endRes - startRes)
398 if (hasHiddenColumns)
400 column = columnSelection.adjustForHiddenColumns(startRes + x);
401 if (column > row_annotations.length - 1)
408 column = startRes + x;
411 if ((row_annotations == null) || (row_annotations.length <= column)
412 || (row_annotations[column] == null))
424 g.setColor(Color.red);
426 if (columnSelection != null)
428 for (int n = 0; n < columnSelection.size(); n++)
430 int v = columnSelection.columnAt(n);
434 g.fillRect(x * charWidth, y, charWidth, charHeight);
439 if (!row.isValidStruc())
441 g.setColor(Color.orange);
442 g.fillRect((int) row.getInvalidStrucPos() * charWidth, y,
443 charWidth, charHeight);
447 && row_annotations[column].displayCharacter != null
448 && (row_annotations[column].displayCharacter.length() > 0))
451 if (centreColLabels || scaleColLabel)
453 fmWidth = fm.charsWidth(
454 row_annotations[column].displayCharacter
456 row_annotations[column].displayCharacter.length());
460 // justify the label and scale to fit in column
461 if (fmWidth > charWidth)
463 // scale only if the current font isn't already small enough
464 fmScaling = charWidth;
465 fmScaling /= fmWidth;
466 g.setFont(ofont.deriveFont(AffineTransform
467 .getScaleInstance(fmScaling, 1.0)));
468 // and update the label's width to reflect the scaling.
476 .charWidth(row_annotations[column].displayCharacter
479 charOffset = (int) ((charWidth - fmWidth) / 2f);
481 if (row_annotations[column].colour == null)
482 g.setColor(Color.black);
484 g.setColor(row_annotations[column].colour);
486 if (column == 0 || row.graph > 0)
488 g.drawString(row_annotations[column].displayCharacter,
489 (x * charWidth) + charOffset, y + iconOffset);
491 else if (row_annotations[column - 1] == null
493 || !row_annotations[column].displayCharacter
494 .equals(row_annotations[column - 1].displayCharacter) || (row_annotations[column].displayCharacter
495 .length() < 2 && row_annotations[column].secondaryStructure == ' ')))
497 g.drawString(row_annotations[column].displayCharacter
499 * charWidth + charOffset, y + iconOffset);
506 char ss = validRes ? row_annotations[column].secondaryStructure
511 // distinguish between forward/backward base-pairing
512 if (row_annotations[column].displayCharacter.indexOf(')') > -1)
521 if ((row_annotations[column].displayCharacter.indexOf(']') > -1))
530 // distinguish between forward/backward base-pairing
531 if (row_annotations[column].displayCharacter.indexOf('}') > -1)
540 // distinguish between forward/backward base-pairing
541 if (row_annotations[column].displayCharacter.indexOf('<') > -1)
550 // distinguish between forward/backward base-pairing
551 if (row_annotations[column].displayCharacter.indexOf('a') > -1)
561 // distinguish between forward/backward base-pairing
562 if (row_annotations[column].displayCharacter.indexOf('b') > -1)
571 // distinguish between forward/backward base-pairing
572 if (row_annotations[column].displayCharacter.indexOf('c') > -1)
580 // distinguish between forward/backward base-pairing
581 if (row_annotations[column].displayCharacter.indexOf('d') > -1)
589 // distinguish between forward/backward base-pairing
590 if (row_annotations[column].displayCharacter.indexOf('e') > -1)
598 // distinguish between forward/backward base-pairing
599 if (row_annotations[column].displayCharacter.indexOf('f') > -1)
607 // distinguish between forward/backward base-pairing
608 if (row_annotations[column].displayCharacter.indexOf('g') > -1)
616 // distinguish between forward/backward base-pairing
617 if (row_annotations[column].displayCharacter.indexOf('h') > -1)
625 // distinguish between forward/backward base-pairing
626 if (row_annotations[column].displayCharacter.indexOf('i') > -1)
634 // distinguish between forward/backward base-pairing
635 if (row_annotations[column].displayCharacter.indexOf('j') > -1)
643 // distinguish between forward/backward base-pairing
644 if (row_annotations[column].displayCharacter.indexOf('k') > -1)
652 // distinguish between forward/backward base-pairing
653 if (row_annotations[column].displayCharacter.indexOf('l') > -1)
661 // distinguish between forward/backward base-pairing
662 if (row_annotations[column].displayCharacter.indexOf('m') > -1)
670 // distinguish between forward/backward base-pairing
671 if (row_annotations[column].displayCharacter.indexOf('n') > -1)
679 // distinguish between forward/backward base-pairing
680 if (row_annotations[column].displayCharacter.indexOf('o') > -1)
688 // distinguish between forward/backward base-pairing
689 if (row_annotations[column].displayCharacter.indexOf('p') > -1)
697 // distinguish between forward/backward base-pairing
698 if (row_annotations[column].displayCharacter.indexOf('q') > -1)
706 // distinguish between forward/backward base-pairing
707 if (row_annotations[column].displayCharacter.indexOf('r') > -1)
715 // distinguish between forward/backward base-pairing
716 if (row_annotations[column].displayCharacter.indexOf('s') > -1)
724 // distinguish between forward/backward base-pairing
725 if (row_annotations[column].displayCharacter.indexOf('t') > -1)
733 // distinguish between forward/backward base-pairing
734 if (row_annotations[column].displayCharacter.indexOf('u') > -1)
742 // distinguish between forward/backward base-pairing
743 if (row_annotations[column].displayCharacter.indexOf('v') > -1)
751 // distinguish between forward/backward base-pairing
752 if (row_annotations[column].displayCharacter.indexOf('w') > -1)
760 // distinguish between forward/backward base-pairing
761 if (row_annotations[column].displayCharacter.indexOf('x') > -1)
769 // distinguish between forward/backward base-pairing
770 if (row_annotations[column].displayCharacter.indexOf('y') > -1)
778 // distinguish between forward/backward base-pairing
779 if (row_annotations[column].displayCharacter.indexOf('z') > -1)
785 if (!validRes || (ss != lastSS))
792 drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
793 column, validRes, validEnd);
797 drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
798 column, validRes, validEnd);
801 case '(': // Stem case for RNA secondary structure
802 case ')': // and opposite direction
803 drawStemAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
804 column, validRes, validEnd);
864 //System.out.println(lastSS);
865 Color nonCanColor= getNotCanonicalColor(lastSS);
866 drawNotCanonicalAnnot(g, nonCanColor, row_annotations, lastSSX, x, y, iconOffset, startRes,
867 column, validRes, validEnd);
870 g.setColor(Color.gray);
871 g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth)
887 lastSSX = (x * charWidth);
894 if (column >= row_annotations.length)
896 column = row_annotations.length - 1;
903 if ((row_annotations == null) || (row_annotations.length <= column)
904 || (row_annotations[column] == null))
920 drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
921 column, validRes, validEnd);
925 drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
926 column, validRes, validEnd);
929 case 'S': // Stem case for RNA secondary structure
930 drawStemAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
931 column, validRes, validEnd);
989 //System.out.println(lastSS);
990 Color nonCanColor = getNotCanonicalColor(lastSS);
991 drawNotCanonicalAnnot(g,nonCanColor, row_annotations, lastSSX, x, y, iconOffset, startRes,
992 column, validRes, validEnd);
995 drawGlyphLine(g, row_annotations, lastSSX, x, y, iconOffset, startRes,
996 column, validRes, validEnd);
1001 if (row.graph > 0 && row.graphHeight > 0)
1003 if (row.graph == AlignmentAnnotation.LINE_GRAPH)
1005 if (row.graphGroup > -1 && !graphGroupDrawn[row.graphGroup])
1007 float groupmax = -999999, groupmin = 9999999;
1008 for (int gg = 0; gg < aa.length; gg++)
1010 if (aa[gg].graphGroup != row.graphGroup)
1017 aa[gg].visible = false;
1019 if (aa[gg].graphMax > groupmax)
1021 groupmax = aa[gg].graphMax;
1023 if (aa[gg].graphMin < groupmin)
1025 groupmin = aa[gg].graphMin;
1029 for (int gg = 0; gg < aa.length; gg++)
1031 if (aa[gg].graphGroup == row.graphGroup)
1033 drawLineGraph(g, aa[gg], aa[gg].annotations, startRes, endRes, y, groupmin,
1034 groupmax, row.graphHeight);
1038 graphGroupDrawn[row.graphGroup] = true;
1042 drawLineGraph(g, row, row_annotations, startRes, endRes, y, row.graphMin,
1043 row.graphMax, row.graphHeight);
1046 else if (row.graph == AlignmentAnnotation.BAR_GRAPH)
1048 drawBarGraph(g, row, row_annotations, startRes, endRes, row.graphMin,
1053 if (row.graph > 0 && row.hasText)
1066 private final Color GLYPHLINE_COLOR = Color.gray;
1068 private final Color SHEET_COLOUR = Color.green;
1070 private final Color HELIX_COLOUR = Color.red;
1072 private final Color STEM_COLOUR = Color.blue;
1074 private Color sdNOTCANONICAL_COLOUR;
1076 public void drawGlyphLine(Graphics g, Annotation[] row,
1077 int lastSSX, int x, int y, int iconOffset, int startRes,
1078 int column, boolean validRes, boolean validEnd)
1080 g.setColor(GLYPHLINE_COLOR);
1081 g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX, 2);
1084 public void drawSheetAnnot(Graphics g, Annotation[] row,
1086 int lastSSX, int x, int y, int iconOffset, int startRes,
1087 int column, boolean validRes, boolean validEnd)
1089 g.setColor(SHEET_COLOUR);
1091 if (!validEnd || !validRes || row==null || row[column] == null
1092 || row[column].secondaryStructure != 'E')
1094 g.fillRect(lastSSX, y + 4 + iconOffset,
1095 (x * charWidth) - lastSSX - 4, 7);
1096 g.fillPolygon(new int[]
1097 { (x * charWidth) - 4, (x * charWidth) - 4, (x * charWidth) },
1099 { y + iconOffset, y + 14 + iconOffset, y + 7 + iconOffset },
1104 g.fillRect(lastSSX, y + 4 + iconOffset,
1105 (x + 1) * charWidth - lastSSX, 7);
1110 public void drawHelixAnnot(Graphics g, Annotation[] row,
1111 int lastSSX, int x, int y, int iconOffset, int startRes,
1112 int column, boolean validRes, boolean validEnd)
1114 g.setColor(HELIX_COLOUR);
1116 int sCol = (lastSSX / charWidth) + startRes;
1118 int x2 = (x * charWidth);
1122 int ofs = charWidth / 2;
1123 // Off by 1 offset when drawing rects and ovals
1124 // to offscreen image on the MAC
1125 g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1, 8, 8, 8);
1126 if (sCol == 0 || row[sCol - 1] == null
1127 || row[sCol - 1].secondaryStructure != 'H')
1132 // g.setColor(Color.orange);
1133 g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1 - ofs + 1, 8,
1136 if (!validRes || row[column] == null
1137 || row[column].secondaryStructure != 'H')
1143 // g.setColor(Color.magenta);
1144 g.fillRoundRect(lastSSX + ofs, y + 4 + iconOffset, x2 - x1 - ofs
1152 if (sCol == 0 || row[sCol - 1] == null
1153 || row[sCol - 1].secondaryStructure != 'H')
1155 g.fillArc(lastSSX, y + 4 + iconOffset, charWidth, 8, 90, 180);
1156 x1 += charWidth / 2;
1159 if (!validRes || row[column] == null
1160 || row[column].secondaryStructure != 'H')
1162 g.fillArc((x * charWidth) - charWidth, y + 4 + iconOffset, charWidth,
1164 x2 -= charWidth / 2;
1167 g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
1170 public void drawLineGraph(Graphics g, AlignmentAnnotation _aa, Annotation[] aa_annotations, int sRes,
1171 int eRes, int y, float min, float max, int graphHeight)
1173 if (sRes > aa_annotations.length)
1180 // Adjustment for fastpaint to left
1186 eRes = Math.min(eRes, aa_annotations.length);
1194 float range = max - min;
1199 y2 = y - (int) ((0 - min / range) * graphHeight);
1202 g.setColor(Color.gray);
1203 g.drawLine(x - charWidth, y2, (eRes - sRes + 1) * charWidth, y2);
1205 eRes = Math.min(eRes, aa_annotations.length);
1208 int aaMax = aa_annotations.length - 1;
1210 while (x < eRes - sRes)
1213 if (hasHiddenColumns)
1215 column = columnSelection.adjustForHiddenColumns(column);
1223 if (aa_annotations[column] == null
1224 || aa_annotations[column - 1] == null)
1230 if (aa_annotations[column].colour == null)
1231 g.setColor(Color.black);
1233 g.setColor(aa_annotations[column].colour);
1236 - (int) (((aa_annotations[column - 1].value - min) / range) * graphHeight);
1238 - (int) (((aa_annotations[column].value - min) / range) * graphHeight);
1240 g.drawLine(x * charWidth - charWidth / 2, y1, x * charWidth
1241 + charWidth / 2, y2);
1245 if (_aa.threshold != null)
1247 g.setColor(_aa.threshold.colour);
1248 Graphics2D g2 = (Graphics2D) g;
1249 g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE,
1250 BasicStroke.JOIN_ROUND, 3f, new float[]
1253 y2 = (int) (y - ((_aa.threshold.value - min) / range) * graphHeight);
1254 g.drawLine(0, y2, (eRes - sRes) * charWidth, y2);
1255 g2.setStroke(new BasicStroke());
1259 public void drawBarGraph(Graphics g, AlignmentAnnotation _aa, Annotation[] aa_annotations, int sRes,
1260 int eRes, float min, float max, int y)
1262 if (sRes > aa_annotations.length)
1266 Font ofont = g.getFont();
1267 eRes = Math.min(eRes, aa_annotations.length);
1269 int x = 0, y1 = y, y2 = y;
1271 float range = max - min;
1275 y2 = y - (int) ((0 - min / (range)) * _aa.graphHeight);
1278 g.setColor(Color.gray);
1280 g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
1283 int aaMax = aa_annotations.length - 1;
1284 boolean renderHistogram = true, renderProfile = true, normaliseProfile = false;
1285 // if (aa.autoCalculated && aa.label.startsWith("Consensus"))
1287 // TODO: generalise this to have render styles for consensus/profile data
1288 if (_aa.groupRef != null)
1290 renderHistogram = _aa.groupRef.isShowConsensusHistogram();
1291 renderProfile = _aa.groupRef.isShowSequenceLogo();
1292 normaliseProfile = _aa.groupRef.isNormaliseSequenceLogo();
1296 renderHistogram = av_renderHistogram;
1297 renderProfile = av_renderProfile;
1298 normaliseProfile = av_normaliseProfile;
1301 while (x < eRes - sRes)
1304 if (hasHiddenColumns)
1306 column = columnSelection.adjustForHiddenColumns(column);
1314 if (aa_annotations[column] == null)
1319 if (aa_annotations[column].colour == null)
1320 g.setColor(Color.black);
1322 g.setColor(aa_annotations[column].colour);
1325 - (int) (((aa_annotations[column].value - min) / (range)) * _aa.graphHeight);
1327 if (renderHistogram)
1331 g.fillRect(x * charWidth, y2, charWidth, y1 - y2);
1335 g.fillRect(x * charWidth, y1, charWidth, y2 - y1);
1338 // draw profile if available
1342 int profl[] = getProfileFor(_aa, column);
1343 // just try to draw the logo if profl is not null
1344 if (profl != null && profl[1] != 0)
1346 float ht = normaliseProfile ? y - _aa.graphHeight : y1;
1347 double htn = normaliseProfile ? _aa.graphHeight : (y2 - y1);// aa.graphHeight;
1354 * profl.length == 74 indicates that the profile of a secondary
1355 * structure conservation row was accesed. Therefore dc gets length 2,
1356 * to have space for a basepair instead of just a single nucleotide
1358 if (profl.length == 74)
1366 LineMetrics lm = g.getFontMetrics(ofont).getLineMetrics("Q", g);
1367 double scale = 1f / (normaliseProfile ? profl[1] : 100f);
1368 float ofontHeight = 1f / lm.getAscent();// magnify to fill box
1370 for (int c = 2; c < profl[0];)
1372 dc[0] = (char) profl[c++];
1374 if (_aa.label.startsWith("StrucConsensus"))
1376 dc[1] = (char) profl[c++];
1380 wdth /= fm.charsWidth(dc, 0, dc.length);
1384 scl = htn * scale * profl[c++];
1385 lm = ofont.getLineMetrics(dc, 0, 1, g.getFontMetrics()
1386 .getFontRenderContext());
1387 g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(
1388 wdth, scl / lm.getAscent())));
1389 lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g);
1391 // Debug - render boxes around characters
1392 // g.setColor(Color.red);
1393 // g.drawRect(x*av.charWidth, (int)ht, av.charWidth,
1395 // g.setColor(profcolour.findColour(dc[0]).darker());
1396 g.setColor(profcolour.findColour(dc[0], column,null));
1398 hght = (ht + (scl - lm.getDescent() - lm.getBaselineOffsets()[lm
1399 .getBaselineIndex()]));
1401 g.drawChars(dc, 0, dc.length, x * charWidth, (int) hght);
1409 if (_aa.threshold != null)
1411 g.setColor(_aa.threshold.colour);
1412 Graphics2D g2 = (Graphics2D) g;
1413 g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE,
1414 BasicStroke.JOIN_ROUND, 3f, new float[]
1417 y2 = (int) (y - ((_aa.threshold.value - min) / range) * _aa.graphHeight);
1418 g.drawLine(0, y2, (eRes - sRes) * charWidth, y2);
1419 g2.setStroke(new BasicStroke());
1423 // used by overview window
1424 public void drawGraph(Graphics g, AlignmentAnnotation _aa, Annotation[] aa_annotations, int width,
1425 int y, int sRes, int eRes)
1427 eRes = Math.min(eRes, aa_annotations.length);
1428 g.setColor(Color.white);
1429 g.fillRect(0, 0, width, y);
1430 g.setColor(new Color(0, 0, 180));
1434 for (int j = sRes; j < eRes; j++)
1436 if (aa_annotations[j] != null)
1438 if (aa_annotations[j].colour == null)
1439 g.setColor(Color.black);
1441 g.setColor(aa_annotations[j].colour);
1443 height = (int) ((aa_annotations[j].value / _aa.graphMax) * y);
1449 g.fillRect(x, y - height, charWidth, height);
1456 Color getNotCanonicalColor(char lastss)
1470 return Color.magenta;
1474 return Color.orange;
1486 return Color.yellow;
1494 return Color.darkGray;
1502 return Color.lightGray;
1514 return Color.magenta;
1518 return Color.orange;
1526 return Color.yellow;
1546 return Color.magenta;
1550 return Color.darkGray;
1554 return Color.yellow;
1562 return Color.orange;
1566 return Color.magenta;
1577 System.out.println("This is not a interaction");