Annotations.Graph can be bargraph, linegraph
[jalview.git] / src / jalview / gui / AnnotationPanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import java.awt.*;\r
24 import java.awt.event.*;\r
25 import java.awt.image.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 import javax.swing.*;\r
30 \r
31 \r
32 /**\r
33  * DOCUMENT ME!\r
34  *\r
35  * @author $author$\r
36  * @version $Revision$\r
37  */\r
38 public class AnnotationPanel extends JPanel implements MouseListener,\r
39     MouseMotionListener, ActionListener, AdjustmentListener\r
40 {\r
41     static String HELIX = "Helix";\r
42     static String SHEET = "Sheet";\r
43     static String LABEL = "Label";\r
44     static String REMOVE = "Remove Annotation";\r
45     static String COLOUR = "Colour";\r
46     static Color HELIX_COLOUR = Color.red.darker();\r
47     static Color SHEET_COLOUR = Color.green.darker().darker();\r
48 \r
49     /** DOCUMENT ME!! */\r
50     public static int GRAPH_HEIGHT = 40;\r
51     AlignViewport av;\r
52     AlignmentPanel ap;\r
53     int activeRow = -1;\r
54     Vector activeRes;\r
55     BufferedImage image;\r
56     Graphics2D gg;\r
57     FontMetrics fm;\r
58     int imgWidth = 0;\r
59     boolean fastPaint = false;\r
60 \r
61     /**\r
62      * Creates a new AnnotationPanel object.\r
63      *\r
64      * @param ap DOCUMENT ME!\r
65      */\r
66     public AnnotationPanel(AlignmentPanel ap)\r
67     {\r
68         ToolTipManager.sharedInstance().registerComponent(this);\r
69         ToolTipManager.sharedInstance().setInitialDelay(0);\r
70         ToolTipManager.sharedInstance().setDismissDelay(10000);\r
71         this.ap = ap;\r
72         av = ap.av;\r
73         this.setLayout(null);\r
74         addMouseListener(this);\r
75         addMouseMotionListener(this);\r
76         ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener(this);\r
77     }\r
78 \r
79     public AnnotationPanel(AlignViewport av)\r
80     {\r
81       this.av = av;\r
82     }\r
83 \r
84 \r
85     /**\r
86      * DOCUMENT ME!\r
87      *\r
88      * @param evt DOCUMENT ME!\r
89      */\r
90     public void adjustmentValueChanged(AdjustmentEvent evt)\r
91     {\r
92         ap.alabels.setScrollOffset(-evt.getValue());\r
93     }\r
94 \r
95     /**\r
96      * DOCUMENT ME!\r
97      */\r
98     public int adjustPanelHeight()\r
99     {\r
100         // setHeight of panels\r
101         image = null;\r
102         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
103         int height = 0;\r
104 \r
105         if (aa != null)\r
106         {\r
107             for (int i = 0; i < aa.length; i++)\r
108             {\r
109                 if (!aa[i].visible)\r
110                 {\r
111                     continue;\r
112                 }\r
113 \r
114                 aa[i].height = 0;\r
115 \r
116                 if (aa[i].hasText)\r
117                 {\r
118                     aa[i].height += av.charHeight;\r
119                 }\r
120 \r
121                 if (aa[i].hasIcons)\r
122                 {\r
123                     aa[i].height += 16;\r
124                 }\r
125 \r
126                 if (aa[i].graph>0)\r
127                 {\r
128                     aa[i].height += GRAPH_HEIGHT;\r
129                 }\r
130 \r
131                 if (aa[i].height == 0)\r
132                 {\r
133                     aa[i].height = 20;\r
134                 }\r
135 \r
136                 height += aa[i].height;\r
137             }\r
138         }\r
139         else\r
140         {\r
141             height = 20;\r
142         }\r
143 \r
144         this.setPreferredSize(new Dimension(1, height));\r
145 \r
146         return height;\r
147     }\r
148 \r
149     /**\r
150      * DOCUMENT ME!\r
151      *\r
152      * @param col DOCUMENT ME!\r
153      */\r
154     public void removeEditableColumn(int col)\r
155     {\r
156         if (activeRow == -1)\r
157         {\r
158             AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
159             if(aa==null)\r
160               return;\r
161 \r
162             for (int j = 0; j < aa.length; j++)\r
163             {\r
164                 if (aa[j].editable)\r
165                 {\r
166                     activeRow = j;\r
167 \r
168                     break;\r
169                 }\r
170             }\r
171         }\r
172 \r
173         if ((activeRes != null) && activeRes.contains(String.valueOf(col)))\r
174         {\r
175             activeRes.removeElement(String.valueOf(col));\r
176         }\r
177 \r
178         repaint();\r
179     }\r
180 \r
181     /**\r
182      * DOCUMENT ME!\r
183      *\r
184      * @param col DOCUMENT ME!\r
185      */\r
186     public void addEditableColumn(int col)\r
187     {\r
188         if (activeRow == -1)\r
189         {\r
190             AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
191             if(aa==null)\r
192               return;\r
193 \r
194             for (int j = 0; j < aa.length; j++)\r
195             {\r
196                 if (aa[j].editable)\r
197                 {\r
198                     activeRow = j;\r
199 \r
200                     break;\r
201                 }\r
202             }\r
203         }\r
204 \r
205         if (activeRes == null)\r
206         {\r
207             activeRes = new Vector();\r
208         }\r
209 \r
210         if (!activeRes.contains(String.valueOf(col)))\r
211         {\r
212             activeRes.addElement(String.valueOf(col));\r
213         }\r
214 \r
215         repaint();\r
216     }\r
217 \r
218     /**\r
219      * DOCUMENT ME!\r
220      *\r
221      * @param evt DOCUMENT ME!\r
222      */\r
223     public void actionPerformed(ActionEvent evt)\r
224     {\r
225         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
226         Annotation[] anot = aa[activeRow].annotations;\r
227 \r
228         if (evt.getActionCommand().equals(REMOVE))\r
229         {\r
230             for (int i = 0; i < activeRes.size(); i++)\r
231             {\r
232                 anot[Integer.parseInt(activeRes.get(i).toString())] = null;\r
233                 anot[Integer.parseInt(activeRes.get(i).toString())] = null;\r
234             }\r
235         }\r
236         else if (evt.getActionCommand().equals(LABEL))\r
237         {\r
238             String label = JOptionPane.showInputDialog(this, "Enter Label ",\r
239                     "Enter label", JOptionPane.QUESTION_MESSAGE);\r
240 \r
241             if (label == null)\r
242             {\r
243                 return;\r
244             }\r
245 \r
246             if ((label.length() > 0) && !aa[activeRow].hasText)\r
247             {\r
248                 aa[activeRow].hasText = true;\r
249             }\r
250 \r
251             for (int i = 0; i < activeRes.size(); i++)\r
252             {\r
253                 int index = Integer.parseInt(activeRes.get(i).toString());\r
254 \r
255                 if (anot[index] == null)\r
256                 {\r
257                     anot[index] = new Annotation(label, "", ' ', 0);\r
258                 }\r
259 \r
260                 anot[index].displayCharacter = label;\r
261             }\r
262         }\r
263         else if (evt.getActionCommand().equals(COLOUR))\r
264         {\r
265             Color col = JColorChooser.showDialog(this,\r
266                     "Choose foreground colour", Color.black);\r
267 \r
268             for (int i = 0; i < activeRes.size(); i++)\r
269             {\r
270                 int index = Integer.parseInt(activeRes.get(i).toString());\r
271 \r
272                 if (anot[index] == null)\r
273                 {\r
274                     anot[index] = new Annotation("", "", ' ', 0);\r
275                 }\r
276 \r
277                 anot[index].colour = col;\r
278             }\r
279         }\r
280         else // HELIX OR SHEET\r
281         {\r
282             char type = 0;\r
283             String symbol = "\u03B1";\r
284 \r
285             if (evt.getActionCommand().equals(HELIX))\r
286             {\r
287                 type = 'H';\r
288             }\r
289             else if (evt.getActionCommand().equals(SHEET))\r
290             {\r
291                 type = 'E';\r
292                 symbol = "\u03B2";\r
293             }\r
294 \r
295             if (!aa[activeRow].hasIcons)\r
296             {\r
297                 aa[activeRow].hasIcons = true;\r
298             }\r
299 \r
300             String label = JOptionPane.showInputDialog("Enter a label for the structure?",\r
301                     symbol);\r
302 \r
303             if (label == null)\r
304             {\r
305                 return;\r
306             }\r
307 \r
308             if ((label.length() > 0) && !aa[activeRow].hasText)\r
309             {\r
310                 aa[activeRow].hasText = true;\r
311             }\r
312 \r
313             for (int i = 0; i < activeRes.size(); i++)\r
314             {\r
315                 int index = Integer.parseInt(activeRes.get(i).toString());\r
316 \r
317                 if (anot[index] == null)\r
318                 {\r
319                     anot[index] = new Annotation(label, "", type, 0);\r
320                 }\r
321 \r
322                 anot[index].secondaryStructure = type;\r
323                 anot[index].displayCharacter = label;\r
324             }\r
325         }\r
326 \r
327         adjustPanelHeight();\r
328         activeRes = null;\r
329         repaint();\r
330 \r
331         return;\r
332     }\r
333 \r
334     /**\r
335      * DOCUMENT ME!\r
336      *\r
337      * @param evt DOCUMENT ME!\r
338      */\r
339     public void mousePressed(MouseEvent evt)\r
340     {\r
341         int height = 0;\r
342         activeRow = -1;\r
343 \r
344         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
345 \r
346         for (int i = 0; i < aa.length; i++)\r
347         {\r
348             if (aa[i].visible)\r
349             {\r
350               height += aa[i].height;\r
351             }\r
352 \r
353             if (evt.getY() < height)\r
354             {\r
355                 if (aa[i].editable)\r
356                 {\r
357                     activeRow = i;\r
358                 }\r
359                 else\r
360                 {\r
361                     activeRes = null;\r
362                 }\r
363 \r
364                 break;\r
365             }\r
366         }\r
367 \r
368         if (SwingUtilities.isRightMouseButton(evt))\r
369         {\r
370             if (activeRes == null)\r
371             {\r
372                 return;\r
373             }\r
374 \r
375             JPopupMenu pop = new JPopupMenu("Structure type");\r
376             JMenuItem item = new JMenuItem(HELIX);\r
377             item.addActionListener(this);\r
378             pop.add(item);\r
379             item = new JMenuItem(SHEET);\r
380             item.addActionListener(this);\r
381             pop.add(item);\r
382             item = new JMenuItem(LABEL);\r
383             item.addActionListener(this);\r
384             pop.add(item);\r
385             item = new JMenuItem(COLOUR);\r
386             item.addActionListener(this);\r
387             pop.add(item);\r
388             item = new JMenuItem(REMOVE);\r
389             item.addActionListener(this);\r
390             pop.add(item);\r
391             pop.show(this, evt.getX(), evt.getY());\r
392 \r
393             return;\r
394         }\r
395 \r
396         if (aa == null)\r
397         {\r
398             return;\r
399         }\r
400 \r
401         int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
402 \r
403         if (evt.isControlDown() || evt.isAltDown())\r
404         {\r
405             addEditableColumn(res);\r
406         }\r
407         else if (evt.isShiftDown())\r
408         {\r
409             if (activeRes == null)\r
410             {\r
411                 activeRes = new Vector();\r
412             }\r
413             else\r
414             {\r
415                 int start = Integer.parseInt(activeRes.get(activeRes.size() -\r
416                             1).toString());\r
417                 int end = res;\r
418 \r
419                 if (end < start)\r
420                 {\r
421                     int temp = end;\r
422                     end = start;\r
423                     start = temp;\r
424                 }\r
425 \r
426                 for (int n = start; n <= end; n++)\r
427                 {\r
428                     addEditableColumn(n);\r
429                 }\r
430             }\r
431         }\r
432         else\r
433         {\r
434             activeRes = new Vector();\r
435             activeRes.addElement(String.valueOf(res));\r
436         }\r
437 \r
438         repaint();\r
439     }\r
440 \r
441     /**\r
442      * DOCUMENT ME!\r
443      *\r
444      * @param evt DOCUMENT ME!\r
445      */\r
446     public void mouseReleased(MouseEvent evt)\r
447     {\r
448     }\r
449 \r
450     /**\r
451      * DOCUMENT ME!\r
452      *\r
453      * @param evt DOCUMENT ME!\r
454      */\r
455     public void mouseEntered(MouseEvent evt)\r
456     {\r
457     }\r
458 \r
459     /**\r
460      * DOCUMENT ME!\r
461      *\r
462      * @param evt DOCUMENT ME!\r
463      */\r
464     public void mouseExited(MouseEvent evt)\r
465     {\r
466     }\r
467 \r
468     /**\r
469      * DOCUMENT ME!\r
470      *\r
471      * @param evt DOCUMENT ME!\r
472      */\r
473     public void mouseDragged(MouseEvent evt)\r
474     {\r
475     }\r
476 \r
477     /**\r
478      * DOCUMENT ME!\r
479      *\r
480      * @param evt DOCUMENT ME!\r
481      */\r
482     public void mouseMoved(MouseEvent evt)\r
483     {\r
484         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
485 \r
486         if (aa == null)\r
487         {\r
488             return;\r
489         }\r
490 \r
491         int row = -1;\r
492         int height = 0;\r
493 \r
494         for (int i = 0; i < aa.length; i++)\r
495         {\r
496             if (aa[i].visible)\r
497             {\r
498                 height += aa[i].height;\r
499             }\r
500 \r
501             if (evt.getY() < height)\r
502             {\r
503                 row = i;\r
504 \r
505                 break;\r
506             }\r
507         }\r
508 \r
509         int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
510 \r
511         if ((row > -1) && (res < aa[row].annotations.length) &&\r
512                 (aa[row].annotations[res] != null))\r
513         {\r
514             this.setToolTipText(aa[row].annotations[res].description);\r
515 \r
516             StringBuffer text = new StringBuffer("Sequence position " +\r
517                     (res + 1) + "  " + aa[row].annotations[res].description);\r
518             ap.alignFrame.statusBar.setText(text.toString());\r
519         }\r
520     }\r
521 \r
522     /**\r
523      * DOCUMENT ME!\r
524      *\r
525      * @param evt DOCUMENT ME!\r
526      */\r
527     public void mouseClicked(MouseEvent evt)\r
528     {\r
529     }\r
530 \r
531     /**\r
532      * DOCUMENT ME!\r
533      *\r
534      * @param g DOCUMENT ME!\r
535      */\r
536     public void paintComponent(Graphics g)\r
537     {\r
538       g.setColor(Color.white);\r
539       g.fillRect(0, 0, getWidth(), getHeight());\r
540 \r
541       if (fastPaint && image!=null)\r
542       {\r
543         g.drawImage(image, 0, 0, this);\r
544         fastPaint = false;\r
545         return;\r
546       }\r
547 \r
548       imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;\r
549 \r
550       if (image == null || imgWidth != image.getWidth())\r
551       {\r
552         image = new BufferedImage(imgWidth, ap.annotationPanel.getHeight(),\r
553                                   BufferedImage.TYPE_INT_RGB);\r
554         gg = (Graphics2D) image.getGraphics();\r
555         gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
556                             RenderingHints.VALUE_ANTIALIAS_ON);\r
557 \r
558         gg.setFont(av.getFont());\r
559         fm = gg.getFontMetrics();\r
560       }\r
561 \r
562       drawComponent(gg, av.startRes, av.endRes + 1);\r
563       g.drawImage(image, 0, 0, this);\r
564     }\r
565 \r
566     /**\r
567      * DOCUMENT ME!\r
568      *\r
569      * @param horizontal DOCUMENT ME!\r
570      */\r
571     public void fastPaint(int horizontal)\r
572     {\r
573         if ((horizontal == 0) ||\r
574                 (av.alignment.getAlignmentAnnotation() == null) ||\r
575                 (av.alignment.getAlignmentAnnotation().length < 1))\r
576         {\r
577             repaint();\r
578 \r
579             return;\r
580         }\r
581 \r
582         gg.copyArea(0, 0, imgWidth, getHeight(), -horizontal * av.charWidth, 0);\r
583 \r
584         int sr = av.startRes;\r
585         int er = av.endRes + 1;\r
586         int transX = 0;\r
587 \r
588         if (horizontal > 0) // scrollbar pulled right, image to the left\r
589         {\r
590             transX = (er - sr - horizontal) * av.charWidth;\r
591             sr = er - horizontal;\r
592         }\r
593         else if (horizontal < 0)\r
594         {\r
595             er = sr - horizontal;\r
596         }\r
597 \r
598         gg.translate(transX, 0);\r
599 \r
600         drawComponent(gg, sr, er);\r
601 \r
602         gg.translate(-transX, 0);\r
603 \r
604         fastPaint = true;\r
605 \r
606         repaint();\r
607 \r
608     }\r
609 \r
610     /**\r
611      * DOCUMENT ME!\r
612      *\r
613      * @param g DOCUMENT ME!\r
614      * @param startRes DOCUMENT ME!\r
615      * @param endRes DOCUMENT ME!\r
616      */\r
617     public void drawComponent(Graphics g, int startRes, int endRes)\r
618     {\r
619       g.setFont(av.getFont());\r
620 \r
621       if (fm == null)\r
622         fm = g.getFontMetrics();\r
623 \r
624 \r
625         g.setColor(Color.white);\r
626         g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getHeight());\r
627 \r
628         if ((av.alignment.getAlignmentAnnotation() == null) ||\r
629                 (av.alignment.getAlignmentAnnotation().length < 1))\r
630         {\r
631             g.setColor(Color.white);\r
632             g.fillRect(0, 0, getWidth(), getHeight());\r
633             g.setColor(Color.black);\r
634             g.drawString("Alignment has no annotations", 20, 15);\r
635 \r
636             return;\r
637         }\r
638 \r
639         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
640 \r
641         int j;\r
642         int x = 0;\r
643         int y = 0;\r
644         char[] lastSS = new char[aa.length];\r
645         int[] lastSSX = new int[aa.length];\r
646         int iconOffset = av.charHeight / 2;\r
647         boolean validRes = false;\r
648 \r
649         //\u03B2 \u03B1\r
650         for (int i = 0; i < aa.length; i++)\r
651         {\r
652             AlignmentAnnotation row = aa[i];\r
653 \r
654             if (!row.visible)\r
655             {\r
656                 continue;\r
657             }\r
658 \r
659 \r
660             if (row.graph>0)\r
661             {\r
662                 // this is so that we draw the characters below the graph\r
663                 y += row.height;\r
664 \r
665                 if (row.hasText)\r
666                 {\r
667                     y -= av.charHeight;\r
668                 }\r
669             }\r
670 \r
671             if (row.hasText)\r
672             {\r
673                 iconOffset = av.charHeight / 2;\r
674             }\r
675             else\r
676             {\r
677                 iconOffset = 0;\r
678             }\r
679 \r
680             for (j = startRes; j < endRes; j++)\r
681             {\r
682                 if ((row.annotations.length <= j) ||\r
683                         (row.annotations[j] == null))\r
684                 {\r
685                     validRes = false;\r
686                 }\r
687                 else\r
688                 {\r
689                     validRes = true;\r
690                 }\r
691 \r
692                 x = (j - startRes) * av.charWidth;\r
693 \r
694                 if (activeRow == i)\r
695                 {\r
696                     g.setColor(Color.red);\r
697 \r
698                     if (activeRes != null)\r
699                     {\r
700                         for (int n = 0; n < activeRes.size(); n++)\r
701                         {\r
702                             int v = Integer.parseInt(activeRes.get(n).toString());\r
703 \r
704                             if (v == j)\r
705                             {\r
706                                 g.fillRect((j - startRes) * av.charWidth, y,\r
707                                     av.charWidth, row.height);\r
708                             }\r
709                         }\r
710                     }\r
711                 }\r
712 \r
713                 if (validRes &&\r
714                         (row.annotations[j].displayCharacter.length() > 0))\r
715                 {\r
716 \r
717                     int charOffset = (av.charWidth -\r
718                         fm.charWidth(row.annotations[j].displayCharacter.charAt(\r
719                                 0))) / 2;\r
720                     g.setColor(row.annotations[j].colour);\r
721 \r
722                     if (j == 0 || row.graph>0)\r
723                     {\r
724                         g.drawString(row.annotations[j].displayCharacter, x+charOffset,\r
725                             y + iconOffset + 3);\r
726                     }\r
727                     else if (((row.annotations[j - 1] == null) ||\r
728                             (row.annotations[j].displayCharacter != row.annotations[j -\r
729                             1].displayCharacter)))\r
730                     {\r
731                         g.drawString(row.annotations[j].displayCharacter, x+charOffset,\r
732                             y + iconOffset + 3);\r
733                     }\r
734                 }\r
735 \r
736                 if (row.hasIcons)\r
737                 {\r
738                     if (!validRes ||\r
739                             (row.annotations[j].secondaryStructure != lastSS[i]))\r
740                     {\r
741                         switch (lastSS[i])\r
742                         {\r
743                         case 'H':\r
744                             g.setColor(HELIX_COLOUR);\r
745                             g.fillRoundRect(lastSSX[i], y + 4 + iconOffset,\r
746                                 x - lastSSX[i], 7, 8, 8);\r
747 \r
748                             break;\r
749 \r
750                         case 'E':\r
751                             g.setColor(SHEET_COLOUR);\r
752                             g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
753                                 x - lastSSX[i] - 4, 7);\r
754                             g.fillPolygon(new int[] { x - 4, x - 4, x },\r
755                                 new int[]\r
756                                 {\r
757                                     y + iconOffset, y + 14 + iconOffset,\r
758                                     y + 8 + iconOffset\r
759                                 }, 3);\r
760 \r
761                             break;\r
762 \r
763                         case 'C':\r
764                             break;\r
765 \r
766                         default:\r
767                             g.setColor(Color.gray);\r
768                             g.fillRect(lastSSX[i], y + 6 + iconOffset,\r
769                                 x - lastSSX[i], 2);\r
770 \r
771                             break;\r
772                         }\r
773 \r
774                         if (validRes)\r
775                         {\r
776                             lastSS[i] = row.annotations[j].secondaryStructure;\r
777                         }\r
778                         else\r
779                         {\r
780                             lastSS[i] = ' ';\r
781                         }\r
782 \r
783                         lastSSX[i] = x;\r
784                     }\r
785                 }\r
786 \r
787                 if (validRes && row.graph>0)\r
788                 {\r
789                     ///g.setColor(new Color(0, 0, 180));\r
790 \r
791                     if(row.graph== AlignmentAnnotation.LINE_GRAPH )\r
792                         drawLineGraph(g, row, j, j+1, x, y);\r
793                     else if(row.graph == AlignmentAnnotation.BAR_GRAPH )\r
794                        drawBarGraph(g, row, j, j+1, x, y);\r
795 \r
796                     //int height = (int) ((row.annotations[j].value / row.graphMax) * GRAPH_HEIGHT);\r
797 \r
798                    // g.setColor(row.annotations[j].colour);\r
799                    // g.fillRect(x, y - height, av.charWidth, height);\r
800                 }\r
801             }\r
802 \r
803             x += av.charWidth;\r
804 \r
805             if (row.hasIcons)\r
806             {\r
807                 switch (lastSS[i])\r
808                 {\r
809                 case 'H':\r
810                     g.setColor(HELIX_COLOUR);\r
811                     g.fillRoundRect(lastSSX[i], y + 4 + iconOffset,\r
812                         x - lastSSX[i], 7, 8, 8);\r
813 \r
814                     break;\r
815 \r
816                 case 'E':\r
817                     g.setColor(SHEET_COLOUR);\r
818                     g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
819                         x - lastSSX[i] - 4, 7);\r
820                     g.fillPolygon(new int[] { x - 4, x - 4, x },\r
821                         new int[]\r
822                         {\r
823                             y + iconOffset, y + 14 + iconOffset,\r
824                             y + 7 + iconOffset\r
825                         }, 3);\r
826 \r
827                     break;\r
828 \r
829                 case 'C':\r
830                     break;\r
831 \r
832                 default:\r
833                     g.setColor(Color.gray);\r
834                     g.fillRect(lastSSX[i], y + 6 + iconOffset, x - lastSSX[i], 2);\r
835 \r
836                     break;\r
837                 }\r
838             }\r
839 \r
840             if (row.graph>0 && row.hasText)\r
841             {\r
842                 y += av.charHeight;\r
843             }\r
844 \r
845             if (row.graph==0)\r
846             {\r
847                 y += aa[i].height;\r
848             }\r
849         }\r
850     }\r
851 \r
852     public void drawLineGraph(Graphics g, AlignmentAnnotation aa, int sRes, int eRes, int x, int y)\r
853     {\r
854       g.setColor(new Color(0, 0, 0));\r
855       if(sRes==0)\r
856         sRes++;\r
857 \r
858       int y1=y, y2=y;\r
859       for (int j = sRes; j < eRes; j++)\r
860       {\r
861           if(aa.annotations[j-1]!=null)\r
862             y1 = y - (int) ((aa.annotations[j-1].value / aa.graphMax) * GRAPH_HEIGHT);\r
863 \r
864           if(aa.annotations[j]!=null)\r
865           y2 = y - (int) ((aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT);\r
866 \r
867           g.drawLine(x-av.charWidth/2, y1, x+av.charWidth/2, y2);\r
868 \r
869           x += av.charWidth;\r
870         }\r
871     }\r
872 \r
873     public void drawBarGraph(Graphics g, AlignmentAnnotation aa, int sRes, int eRes, int x, int y)\r
874     {\r
875       g.setColor(new Color(0, 0, 180));\r
876       int j, height=0;\r
877       for (j = sRes; j < eRes; j++)\r
878       {\r
879           g.setColor(aa.annotations[j].colour);\r
880           height = (int) ((aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT);\r
881 \r
882           g.fillRect(x, y - height, av.charWidth, height);\r
883           x += av.charWidth;\r
884         }\r
885     }\r
886 \r
887     // used by overview window\r
888     public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)\r
889     {\r
890       g.setColor(Color.white);\r
891       g.fillRect(0, 0, width, y);\r
892       g.setColor(new Color(0, 0, 180));\r
893 \r
894       int x = 0, height;\r
895 \r
896       for (int j = sRes; j < eRes; j++)\r
897       {\r
898           g.setColor(new Color(0, 0, 180));\r
899 \r
900           height = (int) ((aa.annotations[j].value / aa.graphMax) * y);\r
901           if(height>y)\r
902             height = y;\r
903 \r
904           g.fillRect(x, y - height, av.charWidth, height);\r
905           x += av.charWidth;\r
906       }\r
907     }\r
908 \r
909 }\r