View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2009 utgenome.org
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *--------------------------------------------------------------------------*/
16  //--------------------------------------
17  // utgb-core Project
18  //
19  // RibbonCanvas.java
20  // Since: 2009/04/27
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.graphics;
26  
27  import java.awt.Color;
28  import java.awt.Font;
29  import java.awt.FontMetrics;
30  import java.awt.Graphics2D;
31  import java.awt.RenderingHints;
32  import java.awt.image.BufferedImage;
33  import java.io.IOException;
34  import java.io.OutputStream;
35  import java.util.HashMap;
36  
37  import javax.imageio.ImageIO;
38  
39  import org.utgenome.format.silk.read.Read;
40  import org.utgenome.format.silk.read.Reference;
41  import org.utgenome.gwt.utgb.server.util.graphic.GraphicUtil;
42  
43  /**
44   * genome drawing canvas supporting indel display
45   * 
46   * @author leo
47   * 
48   */
49  public class RibbonCanvas
50  {
51  
52      private int width = 800;
53  
54      private final GenomeWindow window;
55      private BufferedImage image;
56      private Graphics2D g;
57      private int canvasWidth;
58      private int canvasHeight;
59  
60      private int yOffset = 0;
61  
62      private static final String DEFAULT_COLOR_A = "50b6e8";
63      private static final String DEFAULT_COLOR_C = "e7846e";
64      private static final String DEFAULT_COLOR_G = "84ab51";
65      private static final String DEFAULT_COLOR_T = "ffe980";
66      private static final String DEFAULT_COLOR_N = "333333";
67  
68      private String colorA = DEFAULT_COLOR_A;
69      private String colorC = DEFAULT_COLOR_C;
70      private String colorG = DEFAULT_COLOR_G;
71      private String colorT = DEFAULT_COLOR_T;
72      private String colorN = DEFAULT_COLOR_N;
73  
74      private Color UNKNOWN_BASE_COLOR = GraphicUtil.parseColor(colorN);
75  
76      private HashMap<Character, Color> colorTable = new HashMap<Character, Color>();
77  
78      public RibbonCanvas(int width, int height, GenomeWindow window)
79      {
80          this.window = window;
81          setPixelSize(width, height);
82  
83          colorTable.put('a', GraphicUtil.parseColor(colorA));
84          colorTable.put('c', GraphicUtil.parseColor(colorC));
85          colorTable.put('g', GraphicUtil.parseColor(colorG));
86          colorTable.put('t', GraphicUtil.parseColor(colorT));
87          colorTable.put('A', GraphicUtil.parseColor(colorA));
88          colorTable.put('C', GraphicUtil.parseColor(colorC));
89          colorTable.put('G', GraphicUtil.parseColor(colorG));
90          colorTable.put('T', GraphicUtil.parseColor(colorT));
91  
92      }
93  
94      public Color getBaseColor(char base)
95      {
96          Color color = colorTable.get(base);
97          if (color == null)
98              return UNKNOWN_BASE_COLOR;
99          else
100             return color;
101     }
102 
103     public void setPixelSize(int width, int height)
104     {
105         canvasWidth = width;
106         canvasHeight = height;
107 
108         image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
109         g = (Graphics2D) image.createGraphics();
110 
111         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
112     }
113 
114     public void setReference(Reference reference)
115     {
116 
117     }
118 
119     public void draw(Read read)
120     {
121         if (!window.hasOverlap(read.start, read.end))
122             return;
123 
124         if (window.getGenomeRange() <= 400)
125         {
126             drawSequence(read);
127             return;
128         }
129 
130         long start = read.start;
131         long end = read.end;
132 
133         if (start >= end)
134         {
135             // swap
136             long tmp = start;
137             start = end;
138             end = tmp;
139         }
140 
141         int x1 = window.getXPosOnWindow(start, canvasWidth);
142         int x2 = window.getXPosOnWindow(end, canvasWidth);
143 
144         if (x1 == x2)
145             x2 = x1 + 1;
146 
147         int width = x2 - x1;
148         if (width < 0)
149             width = 1;
150 
151         g.setColor(new Color(100, 100, 255, 240));
152         g.fillRect(x1, yOffset, width, 4);
153         yOffset += 5;
154 
155     }
156 
157     private void drawSequence(Read read)
158     {
159         int boxHeight = 10;
160 
161         long start = read.start;
162         long end = read.end;
163 
164         if (start >= end)
165         {
166             // swap
167             long tmp = start;
168             start = end;
169             end = tmp;
170         }
171         int width = (int) (end - start);
172 
173         int x1 = window.getXPosOnWindow(start, canvasWidth);
174         int x2 = window.getXPosOnWindow(start + 1, canvasWidth);
175 
176         int letterSize = x2 - x1;
177 
178         boolean drawBase = letterSize > 10;
179         int fontHeight = 0;
180         FontMetrics fontMetrics = g.getFontMetrics();
181         if (drawBase)
182         {
183             g.setFont(new Font("SansSerif", Font.PLAIN, boxHeight - 1));
184             fontHeight = fontMetrics.getHeight();
185         }
186 
187         String seq = read.sequence.substring((int) (start - read.start), width);
188 
189         int offset = x1;
190         for (int i = 0; i < seq.length(); ++i)
191         {
192             char ch = seq.charAt(i);
193 
194             if (ch == '-')
195             {
196                 g.setColor(GraphicUtil.parseColor("9999FF"));
197                 g.drawLine(offset, yOffset + boxHeight - 2, offset + letterSize, yOffset + boxHeight - 2);
198             }
199             else
200             {
201                 Color c = getBaseColor(ch);
202                 g.setColor(c);
203                 g.fillRect(offset, yOffset, letterSize, boxHeight - 1);
204 
205                 if (drawBase)
206                 {
207                     g.setColor(Color.DARK_GRAY);
208                     String base = String.valueOf(ch);
209                     int fontWidth = fontMetrics.stringWidth(base);
210                     int xOffset = letterSize / 2 - fontWidth / 2;
211                     g.drawString(base, offset + xOffset, yOffset + boxHeight - 2);
212                 }
213             }
214 
215             offset += letterSize;
216         }
217 
218         yOffset += boxHeight;
219 
220     }
221 
222     public void drawText(String text, long startIndexOnGenome, long endIndexOnGenome, int yOffset, int fontSize,
223             Color color)
224     {
225         int start = window.getXPosOnWindow(startIndexOnGenome, canvasWidth);
226         int end = window.getXPosOnWindow(endIndexOnGenome, canvasWidth);
227         int width = (start < end) ? end - start : 1;
228 
229         g.setFont(new Font("SansSerif", Font.PLAIN, fontSize));
230         FontMetrics fontMetrics = g.getFontMetrics();
231         int fontHeight = fontMetrics.getHeight();
232         int fontWidth = fontMetrics.stringWidth(text);
233 
234         g.setColor(color);
235         int xOffset = (width - fontWidth) / 2;
236         g.drawString(text, start + xOffset, yOffset);
237     }
238 
239     public void toPNG(OutputStream out) throws IOException
240     {
241         ImageIO.write(image, "png", out);
242     }
243 
244 }