stop flickering annotationPanel
[jalview.git] / src / jalview / appletgui / AnnotationPanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 \r
24 import java.awt.*;\r
25 import java.awt.event.*;\r
26 \r
27 import jalview.datamodel.*;\r
28 \r
29 public class AnnotationPanel\r
30     extends Panel implements AdjustmentListener\r
31 {\r
32   AlignViewport av;\r
33   AlignmentPanel ap;\r
34   int activeRow = -1;\r
35 \r
36   Vector activeRes;\r
37   static String HELIX = "Helix";\r
38   static String SHEET = "Sheet";\r
39   static String LABEL = "Label";\r
40   static String REMOVE = "Remove Annotation";\r
41   static String COLOUR = "Colour";\r
42   static Color HELIX_COLOUR = Color.red.darker();\r
43   static Color SHEET_COLOUR = Color.green.darker().darker();\r
44 \r
45   Image image;\r
46   Graphics gg;\r
47   FontMetrics fm;\r
48   int imgWidth = 0;\r
49 \r
50   boolean fastPaint = false;\r
51 \r
52   public static int GRAPH_HEIGHT = 40;\r
53 \r
54   boolean MAC = false;\r
55 \r
56   public AnnotationPanel(AlignmentPanel ap)\r
57   {\r
58     if (System.getProperty("os.name").startsWith("Mac"))\r
59       MAC = true;\r
60 \r
61     this.ap = ap;\r
62     av = ap.av;\r
63     setLayout(null);\r
64     adjustPanelHeight();\r
65 \r
66     addMouseMotionListener(new MouseMotionAdapter()\r
67     {\r
68       public void mouseMoved(MouseEvent evt)\r
69       {\r
70         doMouseMoved(evt);\r
71       }\r
72     });\r
73 \r
74     // ap.annotationScroller.getVAdjustable().addAdjustmentListener( this );\r
75   }\r
76 \r
77 \r
78   public AnnotationPanel(AlignViewport av)\r
79   {\r
80     this.av = av;\r
81   }\r
82 \r
83 \r
84   public void adjustmentValueChanged(AdjustmentEvent evt)\r
85   {\r
86     ap.alabels.setScrollOffset( -evt.getValue());\r
87   }\r
88 \r
89   public int adjustPanelHeight()\r
90   {\r
91     // setHeight of panels\r
92     AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
93 \r
94 \r
95     int height = 0;\r
96     if (aa != null)\r
97     {\r
98       for (int i = 0; i < aa.length; i++)\r
99       {\r
100         if (!aa[i].visible)\r
101         {\r
102           continue;\r
103         }\r
104 \r
105         aa[i].height = 0;\r
106 \r
107         if (aa[i].hasText)\r
108         {\r
109           aa[i].height += av.charHeight;\r
110         }\r
111         if (aa[i].hasIcons)\r
112         {\r
113           aa[i].height += 16;\r
114         }\r
115 \r
116         if (aa[i].graph>0)\r
117         {\r
118           aa[i].height += GRAPH_HEIGHT;\r
119         }\r
120 \r
121         if (aa[i].height == 0)\r
122         {\r
123           aa[i].height = 20;\r
124         }\r
125         height += aa[i].height;\r
126       }\r
127     }\r
128     else\r
129     {\r
130       height = 20;\r
131     }\r
132 \r
133     this.setSize(getSize().width, height);\r
134 \r
135     repaint();\r
136 \r
137     return height;\r
138 \r
139   }\r
140 \r
141   public void addEditableColumn(int i)\r
142   {\r
143     if (activeRow == -1)\r
144     {\r
145       AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
146       if(aa ==null)\r
147         return;\r
148 \r
149       for (int j = 0; j < aa.length; j++)\r
150       {\r
151         if (aa[j].editable)\r
152         {\r
153           activeRow = j;\r
154           break;\r
155         }\r
156       }\r
157     }\r
158 \r
159     if (activeRes == null)\r
160     {\r
161       activeRes = new Vector();\r
162       activeRes.addElement(String.valueOf(i));\r
163       return;\r
164     }\r
165 \r
166     activeRes.addElement(String.valueOf(i));\r
167   }\r
168 \r
169   public void doMouseMoved(MouseEvent evt)\r
170   {\r
171     AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
172     if (aa == null)\r
173     {\r
174       return;\r
175     }\r
176 \r
177     int row = -1;\r
178     int height = 0;\r
179     for (int i = 0; i < aa.length; i++)\r
180     {\r
181 \r
182       if (aa[i].visible)\r
183       {\r
184         height += aa[i].height;\r
185       }\r
186 \r
187       if (evt.getY() < height)\r
188       {\r
189         row = i;\r
190         break;\r
191       }\r
192     }\r
193 \r
194     int res = evt.getX() / av.getCharWidth() + av.getStartRes();\r
195 \r
196     if(av.hasHiddenColumns)\r
197           res = av.getColumnSelection().adjustForHiddenColumns(res);\r
198 \r
199         if (row > -1 && res < aa[row].annotations.length && aa[row].annotations[res] != null)\r
200         {\r
201           StringBuffer text = new StringBuffer("Sequence position " + (res + 1));\r
202           if (aa[row].annotations[res].description != null)\r
203             text.append("  " + aa[row].annotations[res].description);\r
204           ap.alignFrame.statusBar.setText(text.toString());\r
205         }\r
206   }\r
207 \r
208   public void update(Graphics g)\r
209   {\r
210     paint(g);\r
211   }\r
212 \r
213   public void paint(Graphics g)\r
214   {\r
215 \r
216     imgWidth = getSize().width;\r
217         //(av.endRes - av.startRes + 1) * av.charWidth;\r
218 \r
219     if (image == null || imgWidth != image.getWidth(this))\r
220     {\r
221       image = createImage(imgWidth, ap.annotationPanel.getSize().height);\r
222       gg = image.getGraphics();\r
223       gg.setFont(av.getFont());\r
224       fm = gg.getFontMetrics();\r
225       fastPaint = false;\r
226     }\r
227 \r
228 \r
229     if (fastPaint)\r
230     {\r
231       g.drawImage(image, 0, 0, this);\r
232       fastPaint = false;\r
233       return;\r
234     }\r
235 \r
236     gg.setColor(Color.white);\r
237     gg.fillRect(0, 0, getSize().width, getSize().height);\r
238     drawComponent(gg, av.startRes, av.endRes + 1);\r
239 \r
240 \r
241     g.drawImage(image, 0, 0, this);\r
242   }\r
243 \r
244   public void fastPaint(int horizontal)\r
245   {\r
246     if (horizontal == 0\r
247         || av.alignment.getAlignmentAnnotation() == null\r
248         || av.alignment.getAlignmentAnnotation().length < 1\r
249         )\r
250     {\r
251       repaint();\r
252       return;\r
253     }\r
254 \r
255     gg.copyArea(0, 0, imgWidth, getSize().height, -horizontal * av.charWidth, 0);\r
256     int sr = av.startRes, er = av.endRes + 1, transX = 0;\r
257 \r
258     if (horizontal > 0) // scrollbar pulled right, image to the left\r
259     {\r
260       transX = (er - sr - horizontal) * av.charWidth;\r
261       sr = er - horizontal;\r
262     }\r
263     else if (horizontal < 0)\r
264     {\r
265       er = sr - horizontal;\r
266     }\r
267 \r
268     gg.translate(transX, 0);\r
269 \r
270     drawComponent(gg, sr, er);\r
271 \r
272     gg.translate( -transX, 0);\r
273 \r
274     fastPaint = true;\r
275     repaint();\r
276   }\r
277 \r
278   /**\r
279    * DOCUMENT ME!\r
280    *\r
281    * @param g DOCUMENT ME!\r
282    * @param startRes DOCUMENT ME!\r
283    * @param endRes DOCUMENT ME!\r
284    */\r
285   public void drawComponent(Graphics g, int startRes, int endRes)\r
286   {\r
287     g.setFont(av.getFont());\r
288 \r
289 \r
290     g.setColor(Color.white);\r
291     g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getSize().height);\r
292 \r
293 \r
294     if (fm == null)\r
295       fm = g.getFontMetrics();\r
296 \r
297 \r
298       if ((av.alignment.getAlignmentAnnotation() == null) ||\r
299               (av.alignment.getAlignmentAnnotation().length < 1))\r
300       {\r
301           g.setColor(Color.white);\r
302           g.fillRect(0, 0, getSize().width, getSize().height);\r
303           g.setColor(Color.black);\r
304           if(av.validCharWidth)\r
305             g.drawString("Alignment has no annotations", 20, 15);\r
306 \r
307           return;\r
308       }\r
309 \r
310       AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
311 \r
312       int x = 0;\r
313       int y = 0;\r
314       int column=0;\r
315       char lastSS;\r
316       int lastSSX;\r
317       int iconOffset = av.charHeight / 2;\r
318       boolean validRes = false;\r
319 \r
320       boolean [] graphGroupDrawn = new boolean[aa.length];\r
321 \r
322 \r
323       //\u03B2 \u03B1\r
324       for (int i = 0; i < aa.length; i++)\r
325       {\r
326           AlignmentAnnotation row = aa[i];\r
327 \r
328           if (!row.visible)\r
329           {\r
330               continue;\r
331           }\r
332 \r
333           lastSS = ' ';\r
334           lastSSX = 0;\r
335 \r
336           if (row.graph>0)\r
337           {\r
338               if(row.graphGroup>-1 && graphGroupDrawn[ row.graphGroup ] )\r
339                 continue;\r
340 \r
341               // this is so that we draw the characters below the graph\r
342               y += row.height;\r
343 \r
344               if (row.hasText)\r
345               {\r
346                   y -= av.charHeight;\r
347               }\r
348           }\r
349 \r
350           if (row.hasText)\r
351           {\r
352               iconOffset = av.charHeight / 2;\r
353           }\r
354           else\r
355           {\r
356               iconOffset = 0;\r
357           }\r
358 \r
359            x = 0;\r
360           while(x < endRes-startRes)\r
361           {\r
362             if (av.hasHiddenColumns)\r
363             {\r
364               column = av.getColumnSelection().adjustForHiddenColumns(startRes+x);\r
365               if (column > row.annotations.length-1)\r
366               {\r
367                 break;\r
368               }\r
369             }\r
370             else\r
371                 column = startRes+x;\r
372 \r
373               if ( (row.annotations.length <= column) ||\r
374                   (row.annotations[column] == null))\r
375               {\r
376                 validRes = false;\r
377               }\r
378               else\r
379               {\r
380                 validRes = true;\r
381               }\r
382 \r
383 \r
384               if (av.validCharWidth && validRes &&\r
385                         (row.annotations[column].displayCharacter.length() > 0))\r
386               {\r
387                 int charOffset = (av.charWidth -\r
388                     fm.charWidth(row.annotations[column].displayCharacter.charAt(\r
389                             0))) / 2;\r
390                 g.setColor(row.annotations[column].colour);\r
391 \r
392                 if (column == 0 || row.graph>0)\r
393                 {\r
394                     g.drawString(row.annotations[column].displayCharacter,\r
395                                 (x*av.charWidth)+charOffset,\r
396                         y + iconOffset + 3);\r
397                 }\r
398                 else if (\r
399                     row.annotations[column - 1] == null\r
400                     ||(!row.annotations[column].displayCharacter.equals(\r
401                         row.annotations[column - 1].displayCharacter)\r
402                     ||\r
403               (row.annotations[column].displayCharacter.length() <2 &&\r
404                row.annotations[column].secondaryStructure==' ')))\r
405                 {\r
406                     g.drawString(row.annotations[column].displayCharacter,\r
407                        (x*av.charWidth)+charOffset,\r
408                         y + iconOffset + 3);\r
409                     }\r
410               }\r
411 \r
412               if (row.hasIcons)\r
413               {\r
414                   if (!validRes ||\r
415                           (row.annotations[column].secondaryStructure != lastSS))\r
416                   {\r
417                       switch (lastSS)\r
418                       {\r
419                       case 'H':\r
420                         g.setColor(HELIX_COLOUR);\r
421                         if (MAC)\r
422                         {\r
423                           //Off by 1 offset when drawing rects and ovals\r
424                           //to offscreen image on the MAC\r
425                           g.fillRoundRect(lastSSX, y + 4 + iconOffset,\r
426                                           (x*av.charWidth) - lastSSX, 7, 8, 8);\r
427                           break;\r
428                         }\r
429 \r
430                         int sCol = (lastSSX / av.charWidth) + startRes;\r
431                         int x1 = lastSSX;\r
432                         int x2 = (x*av.charWidth);\r
433 \r
434                        if(sCol==0 ||\r
435                           row.annotations[sCol-1]==null ||\r
436                           row.annotations[sCol-1].secondaryStructure!='H')\r
437                        {\r
438                          g.fillArc(lastSSX, y+4+iconOffset, av.charWidth, 8, 90,180) ;\r
439                          x1 += av.charWidth/2;\r
440                        }\r
441 \r
442                         if(row.annotations[column]==null ||\r
443                            row.annotations[column].secondaryStructure!='H')\r
444                         {\r
445                           g.fillArc((x*av.charWidth)-av.charWidth,\r
446                                     y+4+iconOffset, av.charWidth, 8, 270,180);\r
447                           x2 -= av.charWidth/2;\r
448                         }\r
449 \r
450                         g.fillRect(x1, y+4+iconOffset, x2-x1, 8);\r
451                             break;\r
452 \r
453                       case 'E':\r
454                           g.setColor(SHEET_COLOUR);\r
455                           g.fillRect(lastSSX, y + 4 + iconOffset,\r
456                               (x*av.charWidth) - lastSSX - 4, 7);\r
457                           g.fillPolygon(new int[] { (x*av.charWidth) - 4,\r
458                                         (x*av.charWidth) - 4,\r
459                                         (x*av.charWidth) },\r
460                               new int[]\r
461                               {\r
462                                   y + iconOffset, y + 14 + iconOffset,\r
463                                   y + 8 + iconOffset\r
464                               }, 3);\r
465 \r
466                           break;\r
467 \r
468 \r
469                       default:\r
470                           g.setColor(Color.gray);\r
471                           g.fillRect(lastSSX, y + 6 + iconOffset,\r
472                               (x*av.charWidth) - lastSSX, 2);\r
473 \r
474                           break;\r
475                       }\r
476 \r
477                       if (validRes)\r
478                       {\r
479                           lastSS = row.annotations[column].secondaryStructure;\r
480                       }\r
481                       else\r
482                       {\r
483                           lastSS = ' ';\r
484                       }\r
485 \r
486                       lastSSX = (x*av.charWidth);\r
487                   }\r
488               }\r
489 \r
490 \r
491           column++;\r
492           x++;\r
493           }\r
494 \r
495           if(column>=row.annotations.length)\r
496               column = row.annotations.length-1;\r
497 \r
498         //  x ++;\r
499 \r
500           if (row.hasIcons)\r
501           {\r
502             switch (lastSS)\r
503             {\r
504               case 'H':\r
505                 g.setColor(HELIX_COLOUR);\r
506                 if (MAC)\r
507                 {\r
508                   //Off by 1 offset when drawing rects and ovals\r
509                   //to offscreen image on the MAC\r
510                   g.fillRoundRect(lastSSX, y + 4 + iconOffset,\r
511                                   (x*av.charWidth) - lastSSX, 7, 8, 8);\r
512                   break;\r
513                 }\r
514 \r
515                 int sCol = (lastSSX / av.charWidth) + startRes;\r
516                 int x1 = lastSSX;\r
517                 int x2 = (x*av.charWidth);\r
518 \r
519                 if (sCol == 0 ||\r
520                     row.annotations[sCol - 1] == null ||\r
521                     row.annotations[sCol - 1].secondaryStructure != 'H')\r
522                 {\r
523                   g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90, 180);\r
524                   x1 += av.charWidth / 2;\r
525                 }\r
526 \r
527                 if (row.annotations[column] == null ||\r
528                     row.annotations[column].secondaryStructure != 'H')\r
529                 {\r
530                   g.fillArc((x*av.charWidth) - av.charWidth,\r
531                             y + 4 + iconOffset, av.charWidth, 8, 270,\r
532                             180);\r
533                   x2 -= av.charWidth / 2;\r
534                 }\r
535 \r
536                 g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);\r
537 \r
538                 break;\r
539 \r
540               case 'E':\r
541                 g.setColor(SHEET_COLOUR);\r
542 \r
543                 if (row.annotations[endRes] == null\r
544                     || row.annotations[endRes].secondaryStructure != 'E')\r
545                 {\r
546                   g.fillRect(lastSSX, y + 4 + iconOffset,\r
547                              (x*av.charWidth) - lastSSX - 4, 7);\r
548                   g.fillPolygon(new int[]\r
549                                 {(x*av.charWidth) - 4,\r
550                                 (x*av.charWidth) - 4,\r
551                                (x*av.charWidth)},\r
552                                 new int[]\r
553                                 {\r
554                                 y + iconOffset, y + 14 + iconOffset,\r
555                                 y + 7 + iconOffset\r
556                   }, 3);\r
557                 }\r
558                 else\r
559                  {\r
560                    g.fillRect(lastSSX, y + 4 + iconOffset,\r
561                               x * av.charWidth - lastSSX, 7);\r
562                  }\r
563                 break;\r
564 \r
565               default:\r
566                 g.setColor(Color.gray);\r
567                 if(!av.wrapAlignment || endRes==av.endRes)\r
568                 g.fillRect(lastSSX, y + 6 + iconOffset,\r
569                            (x*av.charWidth) - lastSSX, 2);\r
570 \r
571                 break;\r
572             }\r
573           }\r
574 \r
575           if (row.graph>0)\r
576           {\r
577               if(row.graph == AlignmentAnnotation.LINE_GRAPH )\r
578               {\r
579                 if(row.graphGroup>-1 && !graphGroupDrawn[row.graphGroup])\r
580                  {\r
581                    float groupmax=-999999, groupmin=9999999;\r
582                    for(int gg=0; gg<aa.length; gg++)\r
583                    {\r
584                      if(aa[gg].graphGroup!=row.graphGroup)\r
585                        continue;\r
586 \r
587                      if(aa[gg]!=row)\r
588                        aa[gg].visible = false;\r
589 \r
590                      if(aa[gg].graphMax>groupmax)\r
591                        groupmax = aa[gg].graphMax;\r
592                      if(aa[gg].graphMin<groupmin)\r
593                        groupmin = aa[gg].graphMin;\r
594                    }\r
595 \r
596                    for (int gg = 0; gg < aa.length; gg++)\r
597                    {\r
598                      if (aa[gg].graphGroup == row.graphGroup)\r
599                      {\r
600                        drawLineGraph(g, aa[gg], startRes, endRes, y,\r
601                                      groupmin, groupmax,\r
602                                      row.graphHeight);\r
603                      }\r
604                    }\r
605 \r
606                    graphGroupDrawn[ row.graphGroup ] = true;\r
607                  }\r
608                  else\r
609                    drawLineGraph(g, row, startRes, endRes,\r
610                                  y, row.graphMin, row.graphMax, row.graphHeight  );\r
611               }\r
612               else if(row.graph == AlignmentAnnotation.BAR_GRAPH )\r
613                  drawBarGraph(g, row, startRes, endRes,\r
614                               row.graphMin, row.graphMax, y);\r
615           }\r
616 \r
617           if (row.graph>0 && row.hasText)\r
618           {\r
619               y += av.charHeight;\r
620           }\r
621 \r
622           if (row.graph==0)\r
623           {\r
624               y += aa[i].height;\r
625           }\r
626       }\r
627   }\r
628 \r
629   public void drawLineGraph(Graphics g, AlignmentAnnotation aa,\r
630                             int sRes, int eRes,\r
631                             int y,\r
632                             float min, float max,\r
633                             int graphHeight)\r
634   {\r
635     if(sRes>aa.annotations.length)\r
636       return;\r
637 \r
638 \r
639 \r
640     int x = 0;\r
641 \r
642     //Adjustment for fastpaint to left\r
643     if(eRes<av.endRes)\r
644       eRes++;\r
645 \r
646     eRes = Math.min(eRes, aa.annotations.length);\r
647 \r
648 \r
649     if(sRes==0)\r
650     {\r
651       sRes++;\r
652       x+=av.charWidth;\r
653     }\r
654 \r
655     int y1=y, y2=y;\r
656     float range = max - min;\r
657 \r
658     ////Draw origin\r
659     if(min<0)\r
660       y2 = y - (int)((0-min / range)*graphHeight);\r
661 \r
662     g.setColor(Color.gray);\r
663     g.drawLine(x-av.charWidth,y2,(eRes-sRes)*av.charWidth,y2);\r
664 \r
665     eRes = Math.min(eRes, aa.annotations.length);\r
666 \r
667     int column;\r
668     int aaMax = aa.annotations.length-1;\r
669 \r
670     while( x < eRes - sRes )\r
671     {\r
672       column = sRes + x;\r
673       if(av.hasHiddenColumns)\r
674       {\r
675         column = av.getColumnSelection().adjustForHiddenColumns(column);\r
676       }\r
677 \r
678       if (column > aaMax)\r
679       {\r
680         break;\r
681       }\r
682 \r
683       if(aa.annotations[column]==null || aa.annotations[column-1]==null)\r
684       {\r
685         x++;\r
686         continue;\r
687       }\r
688 \r
689         g.setColor(aa.annotations[column].colour);\r
690         y1 = y - (int) (((aa.annotations[column-1].value-min) / range) * graphHeight);\r
691         y2 = y - (int) (((aa.annotations[column].value-min) / range) * graphHeight);\r
692 \r
693         g.drawLine(x*av.charWidth-av.charWidth/2, y1, x*av.charWidth+av.charWidth/2, y2);\r
694         x ++;\r
695      }\r
696 \r
697      if(aa.threshold!=null)\r
698      {\r
699          g.setColor(aa.threshold.colour);\r
700 \r
701          y2 = (int)(y - ((aa.threshold.value-min) / range)*graphHeight);\r
702          g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);\r
703     }\r
704   }\r
705 \r
706   public void drawBarGraph(Graphics g, AlignmentAnnotation aa,\r
707                            int sRes, int eRes,\r
708                            float min, float max,\r
709                            int y)\r
710   {\r
711     if(sRes>aa.annotations.length)\r
712       return;\r
713 \r
714     eRes = Math.min(eRes, aa.annotations.length);\r
715 \r
716     int x=0, y1=y, y2=y;\r
717 \r
718     float range = max - min;\r
719 \r
720     if(min<0)\r
721       y2 = y - (int)((0-min / (range))*aa.graphHeight);\r
722 \r
723     g.setColor(Color.gray);\r
724 \r
725     g.drawLine(x,y2,(eRes-sRes)*av.charWidth,y2);\r
726 \r
727     int column;\r
728     int aaMax = aa.annotations.length-1;\r
729 \r
730     while( x < eRes-sRes )\r
731     {\r
732       column = sRes + x;\r
733       if(av.hasHiddenColumns)\r
734       {\r
735         column = av.getColumnSelection().adjustForHiddenColumns(column);\r
736       }\r
737 \r
738       if(column > aaMax)\r
739       {\r
740           break;\r
741       }\r
742 \r
743       if (aa.annotations[column] == null)\r
744       {\r
745         x ++;\r
746         continue;\r
747       }\r
748 \r
749         g.setColor(aa.annotations[column].colour);\r
750         y1 = y - (int) (((aa.annotations[column].value-min) / (range)) * aa.graphHeight);\r
751 \r
752         if(y1-y2>0)\r
753           g.fillRect(x*av.charWidth, y2, av.charWidth, y1-y2 );\r
754         else\r
755           g.fillRect(x*av.charWidth, y1, av.charWidth, y2-y1 );\r
756 \r
757         x ++ ;\r
758 \r
759     }\r
760     if(aa.threshold!=null)\r
761     {\r
762         g.setColor(aa.threshold.colour);\r
763         y2 = (int)(y - ((aa.threshold.value-min) / range)*aa.graphHeight);\r
764         g.drawLine(0,y2,(eRes-sRes)*av.charWidth,y2);\r
765       }\r
766   }\r
767 \r
768   // used by overview window\r
769   public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)\r
770   {\r
771       g.setColor(Color.white);\r
772       g.fillRect(0, 0, width, y);\r
773       g.setColor(new Color(0, 0, 180));\r
774 \r
775       int x = 0, height;\r
776 \r
777       for (int j = sRes; j < eRes; j++)\r
778       {\r
779           g.setColor(aa.annotations[j].colour);\r
780 \r
781           height = (int) ((aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT);\r
782           if(height>y)\r
783               height = y;\r
784           g.fillRect(x, y - height, av.charWidth, height);\r
785           x += av.charWidth;\r
786       }\r
787     }\r
788 }\r