//package org.genedb.web.gui; // //import net.sf.json.JSONString; // //import org.genedb.db.domain.objects.CompoundLocatedFeature; //import org.genedb.db.domain.objects.Exon; //import org.genedb.db.domain.objects.Gap; //import org.genedb.db.domain.objects.LocatedFeature; //import org.genedb.db.domain.objects.Transcript; //import org.genedb.db.domain.objects.TranscriptComponent; // //import org.apache.log4j.Logger; // //import java.awt.Color; //import java.awt.image.IndexColorModel; //import java.util.ArrayList; //import java.util.HashMap; //import java.util.List; //import java.util.Map; // ///** // * Renders a {@link ContextMapDiagram} as an image. // * // * The rendered diagram consists of a number of gene tracks (positive above and // * negative below). In the centre is a scale track, which shows the scale of the // * diagram. // *<p> // * Each exon is represented by an unbordered rectangle of the appropriate // * colour, centred vertically within the gene track. An intron is represented by // * a narrower rectangle of the same colour, also vertically centred and // * continuous with the exons it separates. // *<p> // * If the rendered diagram is more than 32767 pixels wide, the image will still // * be correctly generated but most decoding software will fail in one of several // * amusing ways. Therefore it is advisable to use a ContextMapDiagram // * representing fewer than 327670 bases (assuming the current default scale of // * 10 bases per pixel). Moreover, a rendered diagram even 10k pixels wide // * appears to crash at least some versions of Firefox on Linux, so we are // * currently limiting ourselves to tiles 5000 pixels wide. // * // * @author rh11 // */ //public class RenderedContextMap extends RenderedDiagram { // static final Logger logger = Logger.getLogger(RenderedContextMap.class); // // /** // * The height of the rectangle representing an exon // */ // private int exonRectHeight = 12; // /** // * The height of the rectangle representing an intron // */ // private int intronRectHeight = 2; // // /** // * The height of the rectangle representing an untranslated region // */ // private int utrRectHeight = 6; // // public RenderedContextMap(ContextMapDiagram diagram) { // // super(diagram); // setLabelBackgroundColor(new Color(0xF0, 0xF0, 0xE4)); // // for (LocatedFeature globalFeature: diagram.getGlobalFeatures()) { // if (globalFeature instanceof Gap) { // addGap((Gap) globalFeature); // } // } // calculateSizeExcludingGaps(); // } // // @Override // public ContextMapDiagram getDiagram() { // return (ContextMapDiagram) super.getDiagram(); // } // // // /** // * Get the height of the rectangles used to represent exons in this diagram. // * @return the height in pixels // */ // public int getExonRectHeight() { // return exonRectHeight; // } // // /** // * Set the height of the rectangles used to represent exons in this diagram // * @param exonRectHeight the height in pixels // */ // public void setExonRectHeight(int exonRectHeight) { // this.exonRectHeight = exonRectHeight; // } // // /** // * Get the height of the rectangles used to represent introns in this diagram. // * @return the height in pixels // */ // public int getIntronRectHeight() { // return intronRectHeight; // } // // /** // * Set the height of the rectangles used to represent introns in this diagram // * @param intronRectHeight the height in pixels // */ // public void setIntronRectHeight(int intronRectHeight) { // this.intronRectHeight = intronRectHeight; // } // // /** // * Get the height of the rectangles used to represent untranslated regions in this diagram. // * @return the height in pixels // */ // public int getUTRRectHeight() { // return utrRectHeight; // } // // /** // * Set the height of the rectangles used to represent untranslated regions in this diagram // * @param utrRectHeight the height in pixels // */ // public void setUTRRectHeight(int utrRectHeight) { // this.utrRectHeight = utrRectHeight; // } // // @Override // public RenderedContextMap asThumbnail(int maxWidth) { // super.asThumbnail(maxWidth); // setExonRectHeight(2); // setIntronRectHeight(2); // setUTRRectHeight(2); // setTickDistances(0, 0); // setScaleColor(Color.GRAY); // setBoundaryTickHeight(0); // return this; // } // // @Override // protected void drawFeature(int track, LocatedFeature subfeature, AllocatedCompoundFeature superfeature) { // if (!(subfeature instanceof Transcript)) { // logger.error(String.format("Located feature '%s' is a '%s' not a Transcript", superfeature, superfeature.getClass())); // return; // } // // renderedFeatures.add(new RenderedFeature(superfeature.getFeature(), subfeature, track, ((Transcript) subfeature).getProducts())); // // drawTranscript(track, (Transcript) subfeature); // } // // private void drawTranscript(int trackNumber, Transcript transcript) { // logger.debug(String.format("Drawing transcript %s (%d..%d) on track %d", transcript // .getUniqueName(), transcript.getFmin(), transcript.getFmax(), trackNumber)); // // Color color = ArtemisColours.getColour(transcript.getColourId()); // graf.setColor(color); // // int currentPos = transcript.getFmin(); // for (TranscriptComponent component : transcript.getComponents()) { // drawIntron(trackNumber, currentPos, component.getStart()); // drawComponent(trackNumber, component); // currentPos = component.getEnd(); // } // drawIntron(trackNumber, currentPos, transcript.getFmax()); // } // // private void drawComponent(int trackNumber, TranscriptComponent component) { // int start = component.getStart(), end = component.getEnd(); // if (end <= start) { // logger.warn("Drawing nothing: empty or negative"); // return; // } // // int x = xCoordinate(component.getStart()); // int width = pixelWidth(component); // // if (component instanceof Exon) { // drawExon(trackNumber, x, width); // } else { // drawUTR(trackNumber, x, width); // } // } // // /** // * Calculate the width in pixels of a transcript component. // * // * @param transcriptComponent the transcript component // * @return the width in pixels // */ // private int pixelWidth(TranscriptComponent transcriptComponent) { // return pixelWidth(transcriptComponent.getStart(), transcriptComponent.getEnd()); // } // // private void drawIntron(int trackNumber, int start, int end) { // if (end <= start) { // return; // } // int x = xCoordinate(start), y = topOfIntron(trackNumber); // int width = pixelWidth(start, end); // graf.fillRect(x, y, width, intronRectHeight); // } // // private void drawExon(int trackNumber, int x, int width) { // /* // * Always draw exons at least 1 pixel wide, otherwise it // * looks confusing. See the P. falciparum gene PF14_0177 // * for example. // */ // if (width < 1) // width = 1; // // int y = topOfExon(trackNumber); // graf.fillRect(x, y, width, exonRectHeight); // } // // private void drawUTR(int trackNumber, int x, int width) { // int y = topOfUTR(trackNumber); // graf.fillRect(x, y, width, utrRectHeight); // } // // // private int topOfIntron(int trackNumber) { // return topOfTrack(trackNumber) + (getTrackHeight() - intronRectHeight) / 2; // } // // private int topOfExon(int trackNumber) { // return topOfTrack(trackNumber) + (getTrackHeight() - exonRectHeight) / 2; // } // // private int topOfUTR(int trackNumber) { // return topOfTrack(trackNumber) + (getTrackHeight() - utrRectHeight) / 2; // } // // private List<String> products = new ArrayList<String>(); // private Map<String,Integer> productIndexByName = new HashMap<String,Integer>(); // // private List<RenderedFeature> renderedFeatures; // private int productIndex(String productName) { // if (productIndexByName.containsKey(productName)) // return productIndexByName.get(productName); // else { // products.add(productName); // int indexOfProduct = products.size() - 1; // productIndexByName.put(productName, indexOfProduct); // return indexOfProduct; // } // } // // public List<String> getProducts() { // return products; // } // // /** // * Represents a located feature that has been rendered, // * and stores its position on the rendered diagram. // * // * @author rh11 // */ // public class RenderedFeature implements JSONString { // private String uniqueName, compoundUniqueName = "", compoundName = ""; // private int track, pixelX, pixelWidth; // private List<Integer> productIndices = new ArrayList<Integer>(); // public RenderedFeature (CompoundLocatedFeature compoundFeature, LocatedFeature subfeature, int track, List<String> productNames) { // this(subfeature.getUniqueName(), compoundFeature.getUniqueName(), // compoundFeature.getName(), track, // xCoordinate(subfeature.getFmin()), pixelWidth(subfeature)); // // if (productNames != null) { // for (String productName: productNames) // productIndices.add(productIndex(productName)); // } // } // public RenderedFeature(String uniqueName, int track, int pixelX, int pixelWidth) { // this.uniqueName = uniqueName; // this.track = track; // this.pixelX = pixelX; // this.pixelWidth = pixelWidth; // } // private RenderedFeature(String uniqueName, String compoundUniqueName, String compoundName, int track, int pixelX, int pixelWidth) { // this(uniqueName, track, pixelX, pixelWidth); // // if (compoundUniqueName != null) // this.compoundUniqueName = compoundUniqueName; // // if (compoundName != null) // this.compoundName = compoundName; // } // private String getProductIndicesAsJSONString() { // StringBuilder sb = new StringBuilder(); // boolean first = true; // for (int productIndex: productIndices) { // if (first) // first = false; // else // sb.append(','); // sb.append(productIndex); // } // return "[" + sb.toString() + "]"; // } // public String toJSONString() { // return String.format("[\"%s\",\"%s\",\"%s\",%d,%d,%d,%s]", // uniqueName, compoundUniqueName, compoundName, track, pixelX, pixelWidth, getProductIndicesAsJSONString()); // } // } // // @Override // protected void beforeRender() throws ImageCreationException { // super.beforeRender(); // // renderedFeatures = new ArrayList<RenderedFeature>(); // // for (Gap gap: getGaps()) { // renderedFeatures.add(new RenderedFeature( // String.format("gap: %d-%d", gap.getFmin()+1, gap.getFmax()), // /*track*/ 0, xCoordinate(gap.getFmin()), getAxisBreakGap())); // } // } // // @Override // protected IndexColorModel byteIndexedColorModel() { // return ArtemisColours.colorModel(getLabelBackgroundColor()); // } // // @Override // public String getKey() { // return getKeyForTile(1, getStart(), getEnd() - getStart()); // } // // @Override // public String getKeyForTile(int index, int start, int width) { // return String.format("%s^^%s:%s:%d:%09d-%09ds%.0f.%s", // getDiagram().getChromosomeFeatureId(), // thumbNailMode ? "thumbnail": "context", // getDiagram().getOrganism(), // index, // start, // width, // getBasesPerPixel(), // FILE_EXT); // } // // /** // * Once the diagram has been rendered, this method will return a list of // * all the rendered features with their locations on the rendered image. // * // * @return // */ // public List<RenderedFeature> getRenderedFeatures() { // return renderedFeatures; // } // //}