001/* 002 * Copyright (c) 2004-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.sdm.spa.actors.piw.viz; 031 032import java.awt.AlphaComposite; 033import java.awt.Color; 034import java.awt.Component; 035import java.awt.Dimension; 036import java.awt.Font; 037import java.awt.Graphics2D; 038import java.awt.event.ActionEvent; 039import java.awt.event.ActionListener; 040import java.awt.event.ComponentAdapter; 041import java.awt.event.ComponentEvent; 042 043import diva.canvas.CompositeFigure; 044import diva.canvas.FigureLayer; 045import diva.canvas.GraphicsPane; 046import diva.canvas.JCanvas; 047import diva.canvas.toolbox.BasicRectangle; 048import diva.canvas.toolbox.LabelFigure; 049 050public class DetailPanel extends JCanvas { 051 052 private static final long serialVersionUID = 3257288028421894961L; 053 private int _startViewPort; 054 private int _sizeViewPort; 055 056 private final SequenceCollection _sequenceCollection; 057 private final SiteCollection _siteCollection; 058 059 public DetailPanel(SequenceCollection sequenceCollection, 060 SiteCollection siteCollection, ActionListener listenerViewPortSize) { 061 062 // Set default view port parameters. 063 _sizeViewPort = 100; 064 _startViewPort = 0; 065 066 this._sequenceCollection = sequenceCollection; 067 this._siteCollection = siteCollection; 068 069 this.addComponentListener(new ListenerComponent(listenerViewPortSize)); 070 } 071 072 public void drawSequences() { 073 drawSequences(_startViewPort); 074 } 075 076 public void drawSequences(int startViewPort) { 077 this._startViewPort = startViewPort; 078 079 this.clear(); 080 081 FigureLayer layer = ((GraphicsPane) this.getCanvasPane()) 082 .getForegroundLayer(); 083 084 // Draw consensus sequence. 085 SequenceFigure sequenceFigure = new SequenceFigure(new Sequence("", 086 "consensus", _sequenceCollection.getConsensus(), 087 new TranscriptionFactorBindingSite[] {}), _startViewPort, 088 _sizeViewPort, _sequenceCollection.getConsensus()); 089 090 sequenceFigure.translate(0, 50); 091 layer.add(sequenceFigure); 092 093 for (int i = 0; i < _sequenceCollection.size(); i++) { 094 Sequence sequence = _sequenceCollection.getSequence(i); 095 096 sequenceFigure = new SequenceFigure(sequence, _startViewPort, 097 _sizeViewPort, _sequenceCollection.getConsensus()); 098 099 // Draw the sequence. 100 sequenceFigure.translate(0, (i + 2) * 50); 101 layer.add(sequenceFigure); 102 } 103 104 // Set preferred size. 105 this.setPreferredSize(new Dimension(_sizeViewPort + 200, 106 (_sequenceCollection.size() + 2) * 50)); 107 } 108 109 public void clear() { 110 ((GraphicsPane) this.getCanvasPane()).getForegroundLayer().clear(); 111 } 112 113 private class ListenerComponent extends ComponentAdapter { 114 private final ActionListener _listener; 115 116 protected ListenerComponent(ActionListener listener) { 117 _listener = listener; 118 } 119 120 public void componentResized(ComponentEvent e) { 121 Component component = e.getComponent(); 122 123 _sizeViewPort = (component.getWidth() - 200) / 7; 124 125 if (null != _listener) { 126 _listener.actionPerformed(new ActionEvent(this, _sizeViewPort, 127 "")); 128 } 129 } 130 } 131 132 private class SequenceFigure extends CompositeFigure { 133 134 public SequenceFigure(Sequence sequence, int startViewPort, 135 int sizeViewPort, String strConsensus) { 136 137 // Add the gene ID label. 138 LabelFigure label = new LabelFigure(sequence.geneID, "SansSerif", 139 Font.ITALIC, 14); 140 label.translate(20, 0); 141 this.add(label); 142 143 CompositeFigure compositeFigure = new CompositeFigure(); 144 shadeConsensus(compositeFigure, startViewPort, sizeViewPort, 145 strConsensus); 146 147 // Draw all the transcription factor binding sites. 148 for (int i = 0; i < sequence.arrTFBSs.length; i++) { 149 150 final TranscriptionFactorBindingSite tfbs = sequence.arrTFBSs[i]; 151 final SiteCollection.Site site = _siteCollection 152 .getSite(tfbs.name); 153 154 // If not visible, then don't paint. 155 if (!site.selected) { 156 continue; 157 } 158 159 // Count of non-hyphens. 160 int count = 0; 161 for (int j = sequence.getActualIndex(Math.abs(tfbs.location));; j++) { 162 // If we're past the end of the sequence, then stop. 163 if (j >= sequence.alignedSequence.length() 164 + sequence.offset) { 165 break; 166 } 167 168 // If we're past the end of the viewport, then stop. 169 if (j >= startViewPort + sizeViewPort) { 170 break; 171 } 172 173 // If we see a gap, then go on to the next one. 174 if ('-' == sequence.alignedSequence.charAt(j 175 - sequence.offset)) { 176 continue; 177 } 178 179 count++; 180 181 // If we're in the view port, then add. 182 if (j >= startViewPort) { 183 compositeFigure.add(new BasicRectangle( 184 (j - startViewPort) * 7, -10, 7, 15) { 185 public void paint(Graphics2D g) { 186 AlphaComposite c = AlphaComposite.getInstance( 187 AlphaComposite.SRC_OVER, 0.2f); 188 g.setComposite(c); 189 g.setPaint(site.color); 190 g.fill(this.getShape()); 191 g.setComposite(AlphaComposite.SrcOver); 192 } 193 }); 194 } 195 196 if (10 == count) { 197 break; 198 } 199 } 200 } 201 202 // Draw the actual sequence. 203 compositeFigure 204 .add(new LabelFigure(sequence.subsequence(startViewPort, 205 sizeViewPort), "Monospaced", Font.PLAIN, 12)); 206 207 // Add that composite figure to this. 208 compositeFigure.translate(150, 0); 209 this.add(compositeFigure); 210 } 211 212 private void shadeConsensus(CompositeFigure compositeFigure, 213 int startViewPort, int sizeViewPort, String strConsensus) { 214 215 if (startViewPort >= strConsensus.length()) { 216 return; 217 } 218 219 strConsensus = strConsensus.substring(startViewPort); 220 int i = 0; 221 while (i < sizeViewPort && 0 < strConsensus.length()) { 222 // If not consensus, then jump ahead. 223 if ('-' == strConsensus.charAt(0)) { 224 String next = strConsensus.replaceFirst("-+", ""); 225 i += strConsensus.length() - next.length(); 226 strConsensus = next; 227 continue; 228 } 229 230 // If the consensus sequence isn't long enough, then don't 231 // shade. 232 String oldconsensus = strConsensus; 233 int oldi = i; 234 strConsensus = strConsensus.replaceFirst("[^-]+", ""); 235 int length = oldconsensus.length() - strConsensus.length(); 236 i += length; 237 238 if (length < _sequenceCollection.getMinimumConsensusLength()) { 239 continue; 240 } 241 242 if (i >= sizeViewPort) { 243 length = sizeViewPort - oldi; 244 } 245 246 compositeFigure.add(new BasicRectangle(oldi * 7, -10, 247 7 * length, 15) { 248 public void paint(Graphics2D g) { 249 AlphaComposite c = AlphaComposite.getInstance( 250 AlphaComposite.SRC_OVER, 0.3f); 251 g.setComposite(c); 252 g.setPaint(new Color(175, 175, 175)); 253 g.fill(this.getShape()); 254 g.setComposite(AlphaComposite.SrcOver); 255 } 256 }); 257 } 258 } 259 260 } 261}