1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
45
46
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
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
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 }