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  // GWTGraphCanvas.java
20  // Since: 2010/05/28
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.client.canvas;
26  
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.List;
30  
31  import org.utgenome.gwt.utgb.client.UTGBEntryPointBase;
32  import org.utgenome.gwt.utgb.client.bio.CompactWIGData;
33  import org.utgenome.gwt.utgb.client.canvas.GWTGenomeCanvas.DragPoint;
34  import org.utgenome.gwt.utgb.client.track.TrackConfig;
35  import org.utgenome.gwt.utgb.client.track.TrackWindow;
36  import org.utgenome.gwt.utgb.client.util.Optional;
37  import org.utgenome.gwt.widget.client.Style;
38  
39  import com.google.gwt.core.client.GWT;
40  import com.google.gwt.core.client.JavaScriptException;
41  import com.google.gwt.user.client.DOM;
42  import com.google.gwt.user.client.Event;
43  import com.google.gwt.user.client.Window;
44  import com.google.gwt.user.client.ui.AbsolutePanel;
45  import com.google.gwt.user.client.ui.Composite;
46  import com.google.gwt.user.client.ui.Label;
47  import com.google.gwt.widgetideas.graphics.client.Color;
48  import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
49  
50  /**
51   * GWT Canvas for drawing bar graph, heat map, etc.
52   * 
53   * @author yoshimura
54   * @author leo
55   * 
56   */
57  public class GWTGraphCanvas extends Composite {
58  	// widget
59  
60  	private GWTCanvas frameCanvas = new GWTCanvas();
61  	private AbsolutePanel panel = new AbsolutePanel();
62  	private TrackWindow viewWindow;
63  
64  	private final HashMap<TrackWindow, GraphCanvas> canvasMap = new HashMap<TrackWindow, GraphCanvas>();
65  
66  	/**
67  	 * Holder of a canvas and its corresponding track window
68  	 * 
69  	 * @author leo
70  	 * 
71  	 */
72  	private static class GraphCanvas {
73  		public TrackWindow window;
74  		public final List<CompactWIGData> graphData;
75  		public final GWTCanvas canvas = new GWTCanvas();
76  		public final int span;
77  		private int height;
78  		private boolean toDelete = false;
79  
80  		public GraphCanvas(TrackWindow window, List<CompactWIGData> graphData, int height) {
81  			this.window = window;
82  			this.graphData = graphData;
83  
84  			int maxSpan = 1;
85  			for (CompactWIGData each : graphData) {
86  				int span = each.getSpan();
87  				if (span > maxSpan)
88  					maxSpan = span;
89  			}
90  			this.span = maxSpan;
91  			this.height = height;
92  
93  			setPixelHeight(height);
94  		}
95  
96  		public void setToDelete() {
97  			this.toDelete = true;
98  		}
99  
100 		public boolean isToDelete() {
101 			return toDelete;
102 		}
103 
104 		public void updatePixelWidth(int newPixelWidth) {
105 			window = window.newPixelWidthWindow(newPixelWidth);
106 			setPixelHeight(height);
107 		}
108 
109 		public void clearCanvas() {
110 			canvas.clear();
111 		}
112 
113 		public void setPixelHeight(int height) {
114 			this.height = height;
115 
116 			int pixelWidthWithSpan = window.convertToPixelLength(window.getSequenceLength() + this.span - 1);
117 
118 			canvas.setCoordSize(pixelWidthWithSpan, height);
119 			canvas.setPixelSize(pixelWidthWithSpan, height);
120 		}
121 
122 		@Override
123 		public String toString() {
124 			return window.toString();
125 		}
126 
127 	}
128 
129 	/**
130 	 * Graph Drawing Configurations
131 	 * 
132 	 * @author leo
133 	 * 
134 	 */
135 	public static class GraphStyle {
136 		public int windowHeight = 100;
137 		public float maxValue = 20.0f;
138 		public float minValue = 0.0f;
139 		public float autoScaledMax = 20.0f;
140 		public float autoScaledMin = 0.0f;
141 
142 		public boolean autoScale = false;
143 		public boolean logScale = false;
144 		public boolean drawZeroValue = false;
145 		public boolean drawScale = true;
146 		public boolean showScaleLabel = true;
147 		public Optional<String> color = new Optional<String>();
148 		public float logBase = 2.0f;
149 
150 		public final static String CONFIG_TRACK_HEIGHT = "trackHeight";
151 		private final static String CONFIG_MAX_VALUE = "maxValue";
152 		private final static String CONFIG_MIN_VALUE = "minValue";
153 		private final static String CONFIG_AUTO_SCALE = "autoScale";
154 		private final static String CONFIG_LOG_SCALE = "logScale";
155 		private final static String CONFIG_LOG_BASE = "log base";
156 		private final static String CONFIG_SHOW_ZERO_VALUE = "showZero";
157 		private final static String CONFIG_DRAW_SCALE = "drawScale";
158 		private final static String CONFIG_SHOW_SCALE_LABEL = "showScaleLabel";
159 		private final static String CONFIG_COLOR = "color";
160 
161 		public float getDefaultMinValue() {
162 			return minValue;
163 		}
164 
165 		public float getDefaultMaxValue() {
166 			return maxValue;
167 		}
168 
169 		public boolean isReverseYAxis() {
170 			return minValue > maxValue;
171 		}
172 
173 		/**
174 		 * Load the parameter values from the configuration panel
175 		 * 
176 		 * @param config
177 		 */
178 		public void load(TrackConfig config) {
179 			maxValue = config.getFloat(CONFIG_MAX_VALUE, maxValue);
180 			minValue = config.getFloat(CONFIG_MIN_VALUE, minValue);
181 			autoScale = config.getBoolean(CONFIG_AUTO_SCALE, autoScale);
182 			logScale = config.getBoolean(CONFIG_LOG_SCALE, logScale);
183 			logBase = config.getFloat(CONFIG_LOG_BASE, logBase);
184 			drawZeroValue = config.getBoolean(CONFIG_SHOW_ZERO_VALUE, drawZeroValue);
185 			drawScale = config.getBoolean(CONFIG_DRAW_SCALE, drawScale);
186 			showScaleLabel = config.getBoolean(CONFIG_SHOW_SCALE_LABEL, showScaleLabel);
187 			windowHeight = config.getInt(CONFIG_TRACK_HEIGHT, windowHeight);
188 			if (windowHeight <= 0)
189 				windowHeight = 100;
190 			String colorStr = config.getString(CONFIG_COLOR, "");
191 			if (colorStr != null && colorStr.length() > 0)
192 				color.set(colorStr);
193 			else
194 				color.reset();
195 		}
196 
197 		/**
198 		 * Set up the configuration panel
199 		 * 
200 		 * @param config
201 		 */
202 		public void setup(TrackConfig config) {
203 			config.addConfigDouble("Y Max", CONFIG_MAX_VALUE, maxValue);
204 			config.addConfigDouble("Y Min", CONFIG_MIN_VALUE, minValue);
205 			config.addConfigBoolean("Auto Scale", CONFIG_AUTO_SCALE, autoScale);
206 			config.addConfigBoolean("Log Scale", CONFIG_LOG_SCALE, logScale);
207 			config.addConfigDouble("Log Base", CONFIG_LOG_BASE, logBase);
208 			config.addConfigBoolean("Show Zero Value", CONFIG_SHOW_ZERO_VALUE, drawZeroValue);
209 			config.addConfigBoolean("Draw Scale", CONFIG_DRAW_SCALE, drawScale);
210 			config.addConfigBoolean("Show Scale Label", CONFIG_SHOW_SCALE_LABEL, showScaleLabel);
211 			config.addConfigString("Graph Color", CONFIG_COLOR, "");
212 		}
213 
214 	}
215 
216 	private GraphStyle style = new GraphStyle();
217 
218 	public GWTGraphCanvas() {
219 
220 		init();
221 	}
222 
223 	private void init() {
224 
225 		Style.padding(panel, 0);
226 		Style.margin(panel, 0);
227 
228 		panel.add(frameCanvas, 0, 0);
229 		//panel.add(canvas, 0, 0);
230 		initWidget(panel);
231 
232 		sinkEvents(Event.ONMOUSEMOVE | Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEDOWN | Event.ONMOUSEUP);
233 	}
234 
235 	private Optional<DragPoint> dragStartPoint = new Optional<DragPoint>();
236 
237 	@Override
238 	public void onBrowserEvent(Event event) {
239 		super.onBrowserEvent(event);
240 
241 		int type = DOM.eventGetType(event);
242 		switch (type) {
243 		case Event.ONMOUSEOVER:
244 
245 			break;
246 		case Event.ONMOUSEMOVE: {
247 			// show readLabels 
248 
249 			if (dragStartPoint.isDefined()) {
250 				// scroll the canvas
251 				int clientX = DOM.eventGetClientX(event) + Window.getScrollLeft();
252 				//int clientY = DOM.eventGetClientY(event) + Window.getScrollTop();
253 
254 				DragPoint p = dragStartPoint.get();
255 				int xDiff = clientX - p.x;
256 				//int yDiff = clientY - p.y;
257 				//panel.setWidgetPosition(canvas, xDiff, 0);
258 			}
259 			else {
260 				//Style.cursor(canvas, Style.CURSOR_AUTO);
261 			}
262 
263 			break;
264 		}
265 		case Event.ONMOUSEOUT: {
266 			resetDrag(event);
267 			break;
268 		}
269 		case Event.ONMOUSEDOWN: {
270 			// invoke a click event 
271 			int clientX = DOM.eventGetClientX(event) + Window.getScrollLeft();
272 			int clientY = DOM.eventGetClientY(event) + Window.getScrollTop();
273 
274 			if (dragStartPoint.isUndefined()) {
275 				dragStartPoint.set(new DragPoint(clientX, clientY));
276 				//Style.cursor(canvas, Style.CURSOR_RESIZE_E);
277 				event.preventDefault();
278 			}
279 
280 			break;
281 		}
282 		case Event.ONMOUSEUP: {
283 
284 			resetDrag(event);
285 			break;
286 		}
287 		}
288 	}
289 
290 	private void resetDrag(Event event) {
291 
292 		int clientX = DOM.eventGetClientX(event) + Window.getScrollLeft();
293 		//int clientY = DOM.eventGetClientY(event) + Window.getScrollTop();
294 
295 		//		if (dragStartPoint.isDefined() && trackWindow != null) {
296 		//			DragPoint p = dragStartPoint.get();
297 		//			int startDiff = trackWindow.convertToGenomePosition(clientX) - trackWindow.convertToGenomePosition(p.x);
298 		//			if (startDiff != 0) {
299 		//				int newStart = trackWindow.getStartOnGenome() - startDiff;
300 		//				if (newStart < 1)
301 		//					newStart = 1;
302 		//				int newEnd = newStart + trackWindow.getSequenceLength();
303 		//				TrackWindow newWindow = trackWindow.newWindow(newStart, newEnd);
304 		//				if (trackGroup != null)
305 		//					trackGroup.setTrackWindow(newWindow);
306 		//			}
307 		//		}
308 
309 		dragStartPoint.reset();
310 
311 		//Style.cursor(canvas, Style.CURSOR_AUTO);
312 	}
313 
314 	public void clear() {
315 		clearCanvas();
316 		clearScale();
317 	}
318 
319 	public void clearCanvas() {
320 		for (GraphCanvas each : canvasMap.values()) {
321 			each.canvas.removeFromParent();
322 		}
323 		canvasMap.clear();
324 	}
325 
326 	public void clearScale() {
327 		frameCanvas.clear();
328 
329 		for (Label each : graphLabels) {
330 			each.removeFromParent();
331 		}
332 		graphLabels.clear();
333 	}
334 
335 	/**
336 	 * Get a canvas for a given TrackWindow
337 	 * 
338 	 * @param w
339 	 * @return
340 	 */
341 	private GraphCanvas getCanvas(TrackWindow w, List<CompactWIGData> data) {
342 		GraphCanvas graphCanvas = canvasMap.get(w);
343 		if (graphCanvas == null) {
344 			// create a new graph canvas
345 			graphCanvas = new GraphCanvas(w, data, style.windowHeight);
346 			canvasMap.put(w, graphCanvas);
347 			int x = viewWindow.convertToPixelX(w.getStartOnGenome());
348 			panel.add(graphCanvas.canvas, 0, 0);
349 			panel.setWidgetPosition(graphCanvas.canvas, x, 0);
350 		}
351 
352 		return graphCanvas;
353 	}
354 
355 	private final String DEFAULT_COLOR = "rgba(12,106,193,0.7)";
356 
357 	public void redrawWigGraph() {
358 		for (GraphCanvas each : canvasMap.values()) {
359 			each.clearCanvas();
360 			each.setPixelHeight(style.windowHeight);
361 			drawWigGraph(each);
362 		}
363 	}
364 
365 	public void drawWigGraph(List<CompactWIGData> data, TrackWindow w) {
366 		if (data == null)
367 			return;
368 
369 		GraphCanvas canvas = getCanvas(w, data);
370 		drawWigGraph(canvas);
371 	}
372 
373 	protected void drawWigGraph(GraphCanvas graphCanvas) {
374 
375 		for (CompactWIGData data : graphCanvas.graphData) {
376 
377 			// get graph color
378 			Color graphColor = new Color(DEFAULT_COLOR);
379 			if (style.color.isDefined()) {
380 				graphColor = new Color(style.color.get());
381 			}
382 			else if (data.getTrack().containsKey("color")) {
383 				String colorStr = data.getTrack().get("color");
384 				String c[] = colorStr.split(",");
385 				if (c.length == 3)
386 					graphColor = new Color(Integer.valueOf(c[0]), Integer.valueOf(c[1]), Integer.valueOf(c[2]));
387 			}
388 
389 			// draw graph
390 			GWTCanvas canvas = graphCanvas.canvas;
391 
392 			canvas.saveContext();
393 			canvas.setLineWidth(1.0f);
394 			canvas.setStrokeStyle(graphColor);
395 
396 			//canvas.scale(viewWindow.convertToPixelLength(graphCanvas.window.getSequenceLength()) / (double) data.getPixelSize(), 1.0f);
397 
398 			float y2 = getYPosition(0.0f);
399 
400 			// draw data graph
401 			final boolean isReverse = graphCanvas.window.isReverseStrand();
402 			final int pixelWidth = data.getData().length;
403 
404 			float min = style.autoScale ? autoScaledMinValue : style.minValue;
405 			float max = style.autoScale ? autoScaledMaxValue : style.maxValue;
406 
407 			for (int i = 0; i < pixelWidth; ++i) {
408 				float value = data.getData()[i];
409 				float y1;
410 				if (value == 0.0f) {
411 					if (!style.drawZeroValue)
412 						continue;
413 					else {
414 						y1 = y2 + ((min < max) ? -0.5f : 0.5f);
415 					}
416 				}
417 				else {
418 					y1 = getYPosition(value);
419 				}
420 
421 				int x = i;
422 				if (isReverse) {
423 					x = pixelWidth - x - 1;
424 				}
425 
426 				canvas.saveContext();
427 				canvas.beginPath();
428 				canvas.translate(x + 0.5f, 0);
429 				canvas.moveTo(0, y1);
430 				canvas.lineTo(0, y2);
431 				canvas.stroke();
432 				canvas.restoreContext();
433 			}
434 			canvas.restoreContext();
435 		}
436 
437 	}
438 
439 	public void clearOutSideOf(TrackWindow globalWindow) {
440 		ArrayList<GraphCanvas> out = new ArrayList<GraphCanvas>();
441 		for (GraphCanvas each : canvasMap.values()) {
442 
443 			if (!globalWindow.overlapWith(each.window) || each.isToDelete()) {
444 				out.add(each);
445 			}
446 		}
447 		for (GraphCanvas each : out) {
448 			each.canvas.clear();
449 			each.canvas.removeFromParent();
450 			canvasMap.remove(each);
451 		}
452 	}
453 
454 	private List<Label> graphLabels = new ArrayList<Label>();
455 
456 	public void drawFrame() {
457 
458 		if (!style.drawScale)
459 			return;
460 
461 		// draw frame
462 		frameCanvas.saveContext();
463 		frameCanvas.setStrokeStyle(new Color(0, 0, 0, 0.5f));
464 		frameCanvas.setLineWidth(1.0f);
465 		frameCanvas.beginPath();
466 		frameCanvas.rect(0, 0, viewWindow.getPixelWidth(), style.windowHeight);
467 		frameCanvas.stroke();
468 		frameCanvas.restoreContext();
469 
470 		// draw indent line & label
471 		Indent indent = createIndent();
472 
473 		frameCanvas.saveContext();
474 		frameCanvas.setStrokeStyle(Color.BLACK);
475 		frameCanvas.setGlobalAlpha(0.2f);
476 		frameCanvas.setLineWidth(0.5f);
477 		for (int i = 0; i <= indent.nSteps; i++) {
478 			float value = indent.getIndentValue(i);
479 			// draw indent line
480 			frameCanvas.saveContext();
481 			frameCanvas.beginPath();
482 			frameCanvas.translate(0, getYPosition(value) + 0.5d);
483 			frameCanvas.moveTo(0d, 0d);
484 			frameCanvas.lineTo(viewWindow.getPixelWidth(), 0);
485 			frameCanvas.stroke();
486 			frameCanvas.restoreContext();
487 		}
488 		{
489 			// draw zero line
490 			frameCanvas.saveContext();
491 			frameCanvas.beginPath();
492 			frameCanvas.translate(0, getYPosition(0f));
493 			frameCanvas.moveTo(0, 0);
494 			frameCanvas.lineTo(viewWindow.getPixelWidth(), 0);
495 			frameCanvas.stroke();
496 			frameCanvas.restoreContext();
497 		}
498 
499 		frameCanvas.restoreContext();
500 
501 	}
502 
503 	public void drawScaleLabel() {
504 
505 		if (!style.showScaleLabel)
506 			return;
507 
508 		Indent indent = createIndent();
509 		int fontHeight = 10;
510 
511 		for (int i = 0; i <= indent.nSteps; i++) {
512 			float value = indent.getIndentValue(i);
513 			String labelString = indent.getIndentString(i);
514 			Label label = new Label(labelString);
515 			label.setTitle(labelString);
516 			Style.fontSize(label, fontHeight);
517 			Style.textAlign(label, "left");
518 			Style.fontColor(label, "#003366");
519 
520 			int labelX = 1;
521 			int labelY = (int) (getYPosition(value) - (fontHeight / 2.0f) - 1);
522 
523 			if (labelY < 0 && labelY > -fontHeight)
524 				labelY = -1;
525 
526 			if (labelY > style.windowHeight - fontHeight) {
527 				labelY = style.windowHeight - fontHeight;
528 			}
529 
530 			//			if (labelY > style.windowHeight) {
531 			//				continue;
532 			//			}
533 
534 			graphLabels.add(label);
535 			panel.add(label, labelX, labelY);
536 
537 		}
538 	}
539 
540 	private Indent createIndent() {
541 		if (style.autoScale) {
542 			return new Indent(autoScaledMinValue, autoScaledMaxValue, style);
543 		}
544 		else {
545 			return new Indent(style.minValue, style.maxValue, style);
546 		}
547 	}
548 
549 	public static class Indent {
550 		public int exponent = 0;
551 		public long fraction = 0;
552 
553 		public int nSteps = 0;
554 
555 		public float min = 0.0f;
556 		public float max = 0.0f;
557 
558 		private GraphStyle style;
559 
560 		public Indent(float minValue, float maxValue, GraphStyle style) {
561 			this.style = style;
562 
563 			final int indentHeight = 10;
564 
565 			min = minValue < maxValue ? minValue : maxValue;
566 			max = minValue > maxValue ? minValue : maxValue;
567 
568 			if (style.logScale) {
569 				min = getLogValue(min, style.logBase);
570 				max = getLogValue(max, style.logBase);
571 			}
572 
573 			try {
574 				double tempIndentValue = (max - min) / style.windowHeight * indentHeight;
575 
576 				if (style.logScale && tempIndentValue < 1.0)
577 					tempIndentValue = 1.0;
578 
579 				fraction = (long) Math.floor(Math.log10(tempIndentValue));
580 				exponent = (int) Math.ceil(Math.round(tempIndentValue / Math.pow(10, fraction - 3)) / 1000.0);
581 
582 				if (exponent <= 5)
583 					;
584 				//			else if(exponent <= 7)
585 				//				exponent = 5;
586 				else {
587 					exponent = 1;
588 					fraction++;
589 				}
590 				double stepSize = exponent * Math.pow(10, fraction);
591 				max = (float) (Math.floor(max / stepSize) * stepSize);
592 				min = (float) (Math.ceil(min / stepSize) * stepSize);
593 
594 				nSteps = (int) Math.abs((max - min) / stepSize);
595 			}
596 			catch (JavaScriptException e) {
597 				UTGBEntryPointBase.showErrorMessage(e.getMessage());
598 			}
599 
600 		}
601 
602 		public float getIndentValue(int step) {
603 			double indentValue = min + (step * exponent * Math.pow(10, fraction));
604 
605 			if (!style.logScale)
606 				return (float) indentValue;
607 			else if (indentValue == 0.0f)
608 				return 0.0f;
609 			else if (indentValue >= 0.0f)
610 				return (float) Math.pow(2, indentValue - 1);
611 			else
612 				return (float) -Math.pow(2, -indentValue - 1);
613 		}
614 
615 		public String getIndentString(int step) {
616 			float indentValue = getIndentValue(step);
617 
618 			if (indentValue == (int) indentValue)
619 				return String.valueOf((int) indentValue);
620 			else {
621 				int exponent_tmp = (int) Math.ceil(Math.round(indentValue / Math.pow(10, fraction - 3)) / 1000.0);
622 				int endIndex = String.valueOf(exponent_tmp).length() + 1;
623 				if (fraction < 0)
624 					endIndex -= fraction;
625 				endIndex = Math.min(String.valueOf(indentValue).length(), endIndex);
626 
627 				return String.valueOf(indentValue).substring(0, endIndex);
628 			}
629 		}
630 	}
631 
632 	public float getYPosition(float value) {
633 
634 		float min = style.minValue;
635 		float max = style.maxValue;
636 
637 		if (style.autoScale) {
638 			min = autoScaledMinValue;
639 			max = autoScaledMaxValue;
640 		}
641 
642 		if (min == max)
643 			return 0.0f;
644 
645 		float tempMin = max < min ? max : min;
646 		float tempMax = max > min ? max : min;
647 
648 		if (style.logScale) {
649 			value = getLogValue(value, style.logBase);
650 			tempMax = getLogValue(tempMax, style.logBase);
651 			tempMin = getLogValue(tempMin, style.logBase);
652 		}
653 		float valueHeight = (value - tempMin) / (tempMax - tempMin) * style.windowHeight;
654 
655 		if (style.isReverseYAxis())
656 			return valueHeight;
657 		else
658 			return style.windowHeight - valueHeight;
659 	}
660 
661 	public static float getLogValue(float value, float logBase) {
662 		if (Math.log(logBase) == 0.0)
663 			return value;
664 
665 		float temp = 0.0f;
666 		if (value > 0.0f) {
667 			temp = (float) (Math.log(value) / Math.log(logBase) + 1.0);
668 			if (temp < 0.0f)
669 				temp = 0.0f;
670 		}
671 		else if (value < 0.0f) {
672 			temp = (float) (Math.log(-value) / Math.log(logBase) + 1.0);
673 			if (temp < 0.0f)
674 				temp = 0.0f;
675 			temp *= -1.0f;
676 		}
677 		return temp;
678 	}
679 
680 	private float autoScaledMinValue = 0.0f;
681 	private float autoScaledMaxValue = 0.0f;
682 
683 	public void setViewWindow(final TrackWindow view) {
684 
685 		if (viewWindow != null) {
686 			if (viewWindow.hasSameScaleWith(view)) {
687 				float tempMinValue = autoScaledMinValue;
688 				float tempMaxValue = autoScaledMaxValue;
689 
690 				if (style.autoScale) {
691 					autoScaledMinValue = 0.0f;
692 					autoScaledMaxValue = 0.0f;
693 				}
694 
695 				for (GraphCanvas each : canvasMap.values()) {
696 					int start = each.window.getStartOnGenome();
697 					int s = view.convertToPixelX(start);
698 					panel.add(each.canvas, s, 0);
699 					//panel.setWidgetPosition(each.canvas, s, 0);
700 
701 					// Auto Scale
702 					if (style.autoScale) {
703 
704 						int pw = view.getPixelWidth();
705 						int pw_e = each.window.getPixelWidth();
706 
707 						for (CompactWIGData wigData : each.graphData) {
708 							float data[] = wigData.getData();
709 
710 							int loopStart, loopEnd;
711 							if (!view.isReverseStrand()) {
712 								loopStart = Math.max(-s, 0);
713 								loopEnd = Math.min(pw - s, pw_e);
714 							}
715 							else {
716 								loopStart = Math.max(s - pw, 0);
717 								loopEnd = Math.min(s, pw_e);
718 							}
719 
720 							for (int pos = loopStart; pos < loopEnd; pos++) {
721 								autoScaledMinValue = Math.min(autoScaledMinValue, data[pos]);
722 								autoScaledMaxValue = Math.max(autoScaledMaxValue, data[pos]);
723 							}
724 						}
725 						GWT.log("scale: " + autoScaledMinValue + " - " + autoScaledMaxValue);
726 					}
727 				}
728 
729 				if (autoScaledMinValue == autoScaledMaxValue) {
730 					autoScaledMinValue = style.minValue;
731 					autoScaledMaxValue = style.maxValue;
732 				}
733 
734 				if (style.autoScale && (autoScaledMinValue != tempMinValue || autoScaledMaxValue != tempMaxValue)) {
735 					redrawWigGraph();
736 				}
737 
738 			}
739 			else {
740 				// zoom in/out
741 				for (GraphCanvas each : canvasMap.values()) {
742 					int newPixelWidth = view.convertToPixelLength(each.window.getSequenceLength());
743 					//each.updatePixelWidth(newPixelWidth);
744 					each.setToDelete();
745 
746 					//					int start = each.window.getStartOnGenome();
747 					//					int s = view.convertToPixelX(start);
748 					//					panel.add(each.canvas, s, 0);
749 					//					//panel.setWidgetPosition(each.canvas, s, 0);
750 				}
751 				redrawWigGraph();
752 			}
753 
754 		}
755 
756 		viewWindow = view;
757 	}
758 
759 	public TrackWindow getViewWindow() {
760 		return viewWindow;
761 	}
762 
763 	public void setStyle(GraphStyle style) {
764 		this.style = style;
765 		setPixelSize(viewWindow.getPixelWidth(), style.windowHeight);
766 
767 		clearScale();
768 		drawFrame();
769 		drawScaleLabel();
770 
771 		redrawWigGraph();
772 	}
773 
774 	public GraphStyle getStyle() {
775 		return style;
776 	}
777 
778 	@Override
779 	public void setPixelSize(int width, int height) {
780 
781 		for (GraphCanvas each : canvasMap.values()) {
782 			each.setPixelHeight(height);
783 		}
784 
785 		frameCanvas.setCoordSize(width, height);
786 		frameCanvas.setPixelWidth(width);
787 		frameCanvas.setPixelHeight(height);
788 
789 		panel.setPixelSize(width, height);
790 	}
791 
792 }