View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2010 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  // GraphScale.java
20  // Since: 2010/09/28
21  //
22  //--------------------------------------
23  package org.utgenome.gwt.utgb.client.canvas;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.utgenome.gwt.utgb.client.UTGBEntryPointBase;
29  import org.utgenome.gwt.utgb.client.canvas.GWTGraphCanvas.GraphStyle;
30  import org.utgenome.gwt.utgb.client.track.TrackWindow;
31  import org.utgenome.gwt.widget.client.Style;
32  
33  import com.google.gwt.core.client.JavaScriptException;
34  import com.google.gwt.user.client.ui.AbsolutePanel;
35  import com.google.gwt.user.client.ui.Composite;
36  import com.google.gwt.user.client.ui.Label;
37  import com.google.gwt.user.client.ui.Widget;
38  import com.google.gwt.widgetideas.graphics.client.Color;
39  import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
40  
41  /**
42   * Scale for graph data
43   * 
44   * @author leo
45   * 
46   */
47  public class GraphScale extends Composite {
48  
49  	private AbsolutePanel panel = new AbsolutePanel();
50  	private GWTCanvas frameCanvas = new GWTCanvas();
51  	private List<Widget> graphLabels = new ArrayList<Widget>();
52  
53  	public GraphScale() {
54  		panel.add(frameCanvas, 0, 0);
55  		initWidget(panel);
56  	}
57  
58  	public void clearScaleBar() {
59  		frameCanvas.clear();
60  	}
61  
62  	public void clearScaleLabel() {
63  		for (Widget each : graphLabels) {
64  			each.removeFromParent();
65  		}
66  		graphLabels.clear();
67  	}
68  
69  	public void clear() {
70  		clearScaleBar();
71  		clearScaleLabel();
72  	}
73  
74  	public void draw(GraphStyle style, TrackWindow viewWindow) {
75  
76  		// set pixel width & size
77  		int width = viewWindow.getPixelWidth();
78  		int height = style.windowHeight;
79  		panel.setPixelSize(width, height);
80  		frameCanvas.setPixelSize(width, height);
81  		frameCanvas.setCoordSize(width, height);
82  
83  		ScalePainter scalePainter = new ScalePainter(style, viewWindow);
84  		scalePainter.draw();
85  
86  	}
87  
88  	class ScalePainter {
89  		private GraphStyle style;
90  		private TrackWindow viewWindow;
91  		private final Scale scale;
92  		private final Indent indent;
93  
94  		public ScalePainter(GraphStyle style, TrackWindow window) {
95  			this.style = style;
96  			this.viewWindow = window;
97  			scale = new Scale(style);
98  			indent = createIndent();
99  		}
100 
101 		public void draw() {
102 			clear();
103 			if (style.drawScale)
104 				drawScale();
105 
106 			if (style.showScaleLabel)
107 				drawScaleLabel();
108 		}
109 
110 		public void drawScale() {
111 
112 			// draw frame
113 			frameCanvas.saveContext();
114 			frameCanvas.setStrokeStyle(new Color(0, 0, 0, 0.5f));
115 			frameCanvas.setLineWidth(1.0f);
116 			frameCanvas.beginPath();
117 			frameCanvas.rect(0, 0, viewWindow.getPixelWidth(), style.windowHeight);
118 			frameCanvas.stroke();
119 			frameCanvas.restoreContext();
120 
121 			// draw indent line & label
122 			frameCanvas.saveContext();
123 			frameCanvas.setStrokeStyle(Color.BLACK);
124 			frameCanvas.setGlobalAlpha(0.2f);
125 			frameCanvas.setLineWidth(0.5f);
126 			for (int i = 0; i <= indent.nSteps; i++) {
127 				float value = indent.getIndentValue(i);
128 				// draw indent line
129 				frameCanvas.saveContext();
130 				frameCanvas.beginPath();
131 				frameCanvas.translate(0, scale.getYPosition(value) + 0.5d);
132 				frameCanvas.moveTo(0d, 0d);
133 				frameCanvas.lineTo(viewWindow.getPixelWidth(), 0);
134 				frameCanvas.stroke();
135 				frameCanvas.restoreContext();
136 			}
137 			{
138 				// draw zero line
139 				frameCanvas.saveContext();
140 				frameCanvas.beginPath();
141 				frameCanvas.translate(0, scale.getYPosition(0f));
142 				frameCanvas.moveTo(0, 0);
143 				frameCanvas.lineTo(viewWindow.getPixelWidth(), 0);
144 				frameCanvas.stroke();
145 				frameCanvas.restoreContext();
146 			}
147 
148 			frameCanvas.restoreContext();
149 		}
150 
151 		public Indent createIndent() {
152 			return new Indent(scale.getMin(), scale.getMax(), style);
153 		}
154 
155 		public void drawScaleLabel() {
156 
157 			int fontHeight = 10;
158 
159 			for (int i = 0; i <= indent.nSteps; i++) {
160 				float value = indent.getIndentValue(i);
161 				String labelString = indent.getIndentString(i);
162 				Label label = new Label(labelString);
163 				label.setTitle(labelString);
164 				Style.fontSize(label, fontHeight);
165 				Style.textAlign(label, "left");
166 				Style.fontColor(label, "#003366");
167 
168 				int labelX = 1;
169 				int labelY = (int) (scale.getYPosition(value) - (fontHeight / 2.0f) - 1);
170 
171 				if (labelY < 0 && labelY > -fontHeight)
172 					labelY = -1;
173 
174 				if (labelY > style.windowHeight - fontHeight) {
175 					labelY = style.windowHeight - fontHeight;
176 				}
177 
178 				graphLabels.add(label);
179 				panel.add(label, labelX, labelY);
180 			}
181 		}
182 
183 		public class Indent {
184 			public int exponent = 0;
185 			public long fraction = 0;
186 
187 			public int nSteps = 0;
188 
189 			public float min = 0.0f;
190 			public float max = 0.0f;
191 
192 			private GraphStyle style;
193 
194 			public Indent(float minValue, float maxValue, GraphStyle style) {
195 				this.style = style;
196 
197 				final int indentHeight = 10;
198 
199 				min = minValue < maxValue ? minValue : maxValue;
200 				max = minValue > maxValue ? minValue : maxValue;
201 
202 				if (style.logScale) {
203 					min = scale.getLogValue(min);
204 					max = scale.getLogValue(max);
205 				}
206 
207 				try {
208 					double tempIndentValue = (max - min) / style.windowHeight * indentHeight;
209 
210 					if (style.logScale && tempIndentValue < 1.0)
211 						tempIndentValue = 1.0;
212 
213 					fraction = (long) Math.floor(Math.log10(tempIndentValue));
214 					exponent = (int) Math.ceil(Math.round(tempIndentValue / Math.pow(10, fraction - 3)) / 1000.0);
215 
216 					if (exponent <= 5)
217 						;
218 					//			else if(exponent <= 7)
219 					//				exponent = 5;
220 					else {
221 						exponent = 1;
222 						fraction++;
223 					}
224 					double stepSize = exponent * Math.pow(10, fraction);
225 					max = (float) (Math.floor(max / stepSize) * stepSize);
226 					min = (float) (Math.ceil(min / stepSize) * stepSize);
227 
228 					nSteps = (int) Math.abs((max - min) / stepSize);
229 				}
230 				catch (JavaScriptException e) {
231 					UTGBEntryPointBase.showErrorMessage(e.getMessage());
232 				}
233 
234 			}
235 
236 			public float getIndentValue(int step) {
237 				double indentValue = min + (step * exponent * Math.pow(10, fraction));
238 
239 				if (!style.logScale)
240 					return (float) indentValue;
241 				else if (indentValue == 0.0f)
242 					return 0.0f;
243 				else if (indentValue >= 0.0f)
244 					return (float) Math.pow(2, indentValue - 1);
245 				else
246 					return (float) -Math.pow(2, -indentValue - 1);
247 			}
248 
249 			public String getIndentString(int step) {
250 				float indentValue = getIndentValue(step);
251 
252 				if (indentValue == (int) indentValue)
253 					return String.valueOf((int) indentValue);
254 				else {
255 					int exponent_tmp = (int) Math.ceil(Math.round(indentValue / Math.pow(10, fraction - 3)) / 1000.0);
256 					int endIndex = String.valueOf(exponent_tmp).length() + 1;
257 					if (fraction < 0)
258 						endIndex -= fraction;
259 					endIndex = Math.min(String.valueOf(indentValue).length(), endIndex);
260 
261 					return String.valueOf(indentValue).substring(0, endIndex);
262 				}
263 			}
264 		}
265 
266 	}
267 
268 }