/* * Author: tdanford * Date: Sep 16, 2008 */ package org.seqcode.viz.eye; import java.awt.*; import java.lang.reflect.*; import java.util.*; import org.seqcode.genome.location.Region; import org.seqcode.gseutils.Pair; import org.seqcode.gseutils.models.Model; import org.seqcode.gseutils.models.ModelFieldAnalysis; import org.seqcode.viz.colors.Coloring; public class ModelRangeValues extends AbstractModelPaintable { public static final String boundsKey = "bounds"; public static final String colorKey = "color"; public static final String strokeKey = "stroke"; public static final String axisColorKey = "axis-color"; private String xFieldName, yFieldName; private Vector<Pair<Integer,Integer>> ranges; private Vector<Model> models; public ModelRangeValues() { xFieldName = "start"; yFieldName = "end"; ranges = new Vector<Pair<Integer,Integer>>(); models = new Vector<Model>(); Color transblue = Color.blue; transblue = Coloring.clearer(Coloring.clearer(transblue)); initProperty(new PropertyValueWrapper<Integer[]>(boundsKey, new Integer[] { 0, 1 })); initProperty(new PropertyValueWrapper<Color>(colorKey, transblue)); initProperty(new PropertyValueWrapper<Float>(strokeKey, (float)3.0)); } public ModelRangeValues(String xfield, String yfield) { this(); xFieldName = xfield; yFieldName = yfield; } public void addValue(Object value) { if (value instanceof Region) { Region r = (Region)value; int start = r.getStart(), end = r.getEnd(); models.add(new RangeModel(start, end)); addRangeValue(start, end); } else { super.addValue(value); } } public void addModel(Model m) { Class modelClass = m.getClass(); ModelFieldAnalysis analysis = new ModelFieldAnalysis(modelClass); Field xfield = analysis.findField(xFieldName); Field yfield = analysis.findField(yFieldName); if(xfield != null && yfield != null) { try { Object xvalue = xfield.get(m); Object yvalue = yfield.get(m); if(xvalue != null && yvalue != null) { Class xclass = xvalue.getClass(); Class yclass = yvalue.getClass(); if(!Model.isSubclass(xclass, Integer.class)) { throw new IllegalArgumentException("Start value must be an Integer"); } if(!Model.isSubclass(yclass, Integer.class)) { throw new IllegalArgumentException("End value must be an Integer"); } Integer xnumber = (Integer)xvalue; Integer ynumber = (Integer)yvalue; int x = xnumber.intValue(); int y = ynumber.intValue(); models.add(m); addRangeValue(x, y); } else { throw new IllegalArgumentException("location or value was null"); } } catch (IllegalAccessException e) { throw new IllegalArgumentException("location or value field was inaccessible", e); } } else { String msg = "No Fields:"; if(xfield == null) { msg += String.format(" %s", xFieldName); } if(yfield == null) { msg += String.format(" %s", yFieldName); } throw new IllegalArgumentException(msg); } } private void addRangeValue(int x, int y) { if(x > y) { throw new IllegalArgumentException(); } ModelPaintableProperty boundsProp = getProperty(boundsKey); Integer[] bounds = (Integer[])boundsProp.getValue(); ranges.add(new Pair<Integer,Integer>(x, y)); if(x < bounds[0] || y > bounds[1]) { bounds[0] = Math.min(x, bounds[0]); bounds[1] = Math.max(y, bounds[1]); setProperty(new PropertyValueWrapper<Integer[]>(boundsKey, bounds)); } dispatchChangedEvent(); } public void addModels(Iterator<? extends Model> itr) { while(itr.hasNext()) { addModel(itr.next()); } } public void clearModels() { ranges.clear(); models.clear(); dispatchChangedEvent(); } public void paintItem(Graphics g, int x1, int y1, int x2, int y2) { Integer[] bounds = getPropertyValue(boundsKey); Color color = getPropertyValue(colorKey, Color.red); float stroke = getPropertyValue(strokeKey, (float)1.0); int strokeWidth = Math.max(1, (int)Math.floor(stroke)); Color axisColor = getPropertyValue(axisColorKey, Color.black); int length = Math.max(1, bounds[1] - bounds[0] + 1); int w = x2-x1, h = y2-y1; Graphics2D g2 = (Graphics2D)g; Stroke oldStroke = g2.getStroke(); g2.setStroke(new BasicStroke(stroke)); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); /** Painting Code **/ // Axes g2.setColor(axisColor); g2.drawRect(x1, y1, w-1, h-1); int wArea = w - strokeWidth*2; // Points for(Pair<Integer,Integer> r : ranges) { int start = r.getFirst(); int end = r.getLast(); double xf = (double)(start-bounds[0]) / (double)length; double yf = (double)(end-bounds[0]+1) / (double)length; int px = x1 + (int)Math.round(xf * (double)wArea); int py = x1 + (int)Math.round(yf * (double)wArea); g2.setColor(color); g2.fillRect(px, y1, py-px, y2-y1); } g2.setStroke(oldStroke); } public static class RangeModel extends Model { public Integer start, end; public RangeModel(int s, int e) { start = s; end = e; } } }