/** * Get a graphics object for the baseline. TODO -- make the line style settable by the user * * @param context * @return */ private static Graphics2D getBaselineGraphics(RenderContext context) { Graphics2D baselineGraphics; baselineGraphics = (Graphics2D) context.getGraphic2DForColor(Color.lightGray).create(); baselineGraphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); return baselineGraphics; }
/** * Render the site track (the top, summary view of the site). * * @param variant * @param bandRectangle * @param pX0 * @param dX * @param context */ public void renderSiteBand( Variant variant, Rectangle bandRectangle, int pX0, int dX, RenderContext context) { final boolean filtered = variant.isFiltered(); final Color alleleColor; final Color refColor; double percent; if (track.getColorMode() == VariantTrack.ColorMode.METHYLATION_RATE) { alleleColor = this.convertMethylationRateToColor((float) variant.getMethlationRate() / 100); percent = variant.getCoveredSampleFraction(); refColor = filtered ? colorAlleleRefAlpha : colorAlleleRef; // Gray } else { alleleColor = filtered ? colorAlleleBandAlpha : colorAlleleBand; // Red double af = variant.getAlleleFraction(); if (af < 0) { double[] afreqs = variant.getAlleleFreqs(); if (afreqs != null && afreqs.length > 0) { af = afreqs[0]; } } percent = Math.min(1, af); if (percent <= 0) { percent = 0; refColor = filtered ? colorAlleleRefAlpha : colorAlleleRef; // Gray } else { refColor = filtered ? blueAlpha : blue; // Blue } } final int bottomY = bandRectangle.y + bandRectangle.height - BOTTOM_MARGIN; final int barHeight = bandRectangle.height - TOP_MARGIN - BOTTOM_MARGIN; final int alleleBarHeight = (int) (percent * barHeight); final int remainderHeight = barHeight - alleleBarHeight; if (remainderHeight > 0) { Graphics2D g = context.getGraphic2DForColor(refColor); g.fillRect(pX0, bottomY - alleleBarHeight - remainderHeight, dX, remainderHeight); } if (alleleBarHeight > 0) { Graphics2D g = context.getGraphic2DForColor(alleleColor); g.fillRect(pX0, bottomY - alleleBarHeight, dX, alleleBarHeight); } }
public void renderGenotypeBandSNP( Variant variant, RenderContext context, Rectangle bandRectangle, int pX0, int dX, String sampleName, VariantTrack.ColorMode coloring, boolean hideFiltered) { int pY = (int) bandRectangle.getY(); int dY = (int) bandRectangle.getHeight(); int tOffset = 6; int bOffset = 8; Graphics2D g = (Graphics2D) context.getGraphics().create(); if (dX >= 10) { if (dY > 24) { Font f = FontManager.getFont(Font.BOLD, Math.min(dX, 12)); g.setFont(f); } else if (dY > 18) { Font f = FontManager.getFont(Font.BOLD, Math.min(dX, 8)); tOffset = 4; bOffset = 5; g.setFont(f); } } boolean isFiltered = variant.isFiltered() && hideFiltered; Genotype genotype = variant.getGenotype(sampleName); if (genotype == null) { log.error("Now what?"); } else { Color b1Color = Color.gray; Color b2Color = Color.gray; char b1 = ' '; char b2 = ' '; // Assign proper coloring switch (coloring) { case GENOTYPE: b1Color = getGenotypeColor(genotype, isFiltered); b2Color = b1Color; break; case ALLELE: final List<Allele> alleleList = genotype.getAlleles(); if (alleleList.size() > 0) { b1 = getFirstBase(alleleList.get(0)); b1Color = nucleotideColors.get(b1); } if (alleleList.size() > 1) { b2 = getFirstBase(alleleList.get(1)); b2Color = nucleotideColors.get(b2); } break; case METHYLATION_RATE: final double goodBaseCount = genotype.getAttributeAsDouble("GB"); b1Color = colorNoCall; b2Color = b1Color; final double value = genotype.getAttributeAsDouble("MR"); if (!Double.isNaN(goodBaseCount) && !Double.isNaN(value)) { if (goodBaseCount < VariantTrack.METHYLATION_MIN_BASE_COUNT || Double.isNaN(value)) { b1Color = colorNoCall; b2Color = b1Color; } else { float mr = (float) value; mr /= 100f; b1Color = convertMethylationRateToColor(mr); b2Color = b1Color; } } else { log.error( "GB and MR fields must be defined for all records in a VCF methylation file."); } break; default: b1Color = colorNoCall; b2Color = b1Color; } int y0 = track.getDisplayMode() == Track.DisplayMode.EXPANDED ? pY + 1 : pY; int h = Math.max(1, track.getDisplayMode() == Track.DisplayMode.EXPANDED ? dY - 2 : dY); if (coloring == VariantTrack.ColorMode.GENOTYPE) { g.setColor(b1Color); g.fillRect(pX0, y0, dX, h); } else { // Color by allele g.setColor(b1Color); g.fillRect(pX0, y0, (dX / 2), h); g.setColor(b2Color); g.fillRect(pX0 + (dX / 2), y0, (dX / 2), h); } if ((dX >= 10) && (dY >= 18)) { if (b1Color == Color.blue) { g.setColor(Color.white); } else { g.setColor(Color.black); } drawCenteredText(g, new char[] {b1}, pX0, pY - tOffset, dX, dY); drawCenteredText(g, new char[] {b2}, pX0, pY + (dY / 2) - bOffset, dX, dY); } } g.dispose(); }
/** * Render the track in the given rectangle. * * @param track * @param locusScores * @param context * @param arect */ public synchronized void renderScores( Track track, List<LocusScore> locusScores, RenderContext context, Rectangle arect) { boolean showMissingData = PreferenceManager.getInstance().getAsBoolean(PreferenceManager.SHOW_MISSING_DATA_KEY); Graphics2D noDataGraphics = context.getGraphic2DForColor(UIConstants.NO_DATA_COLOR); Graphics2D tickGraphics = context.getGraphic2DForColor(Color.BLACK); Rectangle adjustedRect = calculateDrawingRect(arect); double origin = context.getOrigin(); double locScale = context.getScale(); Color posColor = track.getColor(); Color negColor = track.getAltColor(); // Get the Y axis definition, consisting of minimum, maximum, and base value. Often // the base value is == min value which is == 0. DataRange dataRange = track.getDataRange(); float maxValue = dataRange.getMaximum(); float baseValue = dataRange.getBaseline(); float minValue = dataRange.getMinimum(); boolean isLog = dataRange.isLog(); if (isLog) { minValue = (float) (minValue == 0 ? 0 : Math.log10(minValue)); maxValue = (float) Math.log10(maxValue); } // Calculate the Y scale factor. double delta = (maxValue - minValue); double yScaleFactor = adjustedRect.getHeight() / delta; // Calculate the Y position in pixels of the base value. Clip to bounds of rectangle double baseDelta = maxValue - baseValue; int baseY = (int) (adjustedRect.getY() + baseDelta * yScaleFactor); if (baseY < adjustedRect.y) { baseY = adjustedRect.y; } else if (baseY > adjustedRect.y + adjustedRect.height) { baseY = adjustedRect.y + adjustedRect.height; } int lastPx = 0; for (LocusScore score : locusScores) { // Note -- don't cast these to an int until the range is checked. // could get an overflow. double pX = ((score.getStart() - origin) / locScale); double dx = Math.ceil((Math.max(1, score.getEnd() - score.getStart())) / locScale) + 1; if ((pX + dx < 0)) { continue; } else if (pX > adjustedRect.getMaxX()) { break; } float dataY = score.getScore(); if (isLog && dataY <= 0) { continue; } if (!Float.isNaN(dataY)) { // Compute the pixel y location. Clip to bounds of rectangle. double dy = isLog ? Math.log10(dataY) - baseValue : (dataY - baseValue); int pY = baseY - (int) (dy * yScaleFactor); if (pY < adjustedRect.y) { pY = adjustedRect.y; } else if (pY > adjustedRect.y + adjustedRect.height) { pY = adjustedRect.y + adjustedRect.height; } Color color = (dataY >= baseValue) ? posColor : negColor; drawDataPoint(color, (int) dx, (int) pX, baseY, pY, context); } if (showMissingData) { // Draw from lastPx + 1 to pX - 1; int w = (int) pX - lastPx - 4; if (w > 0) { noDataGraphics.fillRect(lastPx + 2, (int) arect.getY(), w, (int) arect.getHeight()); } } if (!Float.isNaN(dataY)) { lastPx = (int) pX + (int) dx; } } if (showMissingData) { int w = (int) arect.getMaxX() - lastPx - 4; if (w > 0) { noDataGraphics.fillRect(lastPx + 2, (int) arect.getY(), w, (int) arect.getHeight()); } } }
protected void drawDataPoint( Color graphColor, int dx, int pX, int baseY, int pY, RenderContext context) { context.getGraphic2DForColor(graphColor).fillRect(pX, pY, dx, 2); }
@Override public void renderBorder(Track track, RenderContext context, Rectangle arect) { Rectangle adjustedRect = calculateDrawingRect(arect); // Draw boundaries if there is room if (adjustedRect.getHeight() >= 10) { /// TrackProperties pros = track.getProperties(); // midline DataRange axisDefinition = track.getDataRange(); float maxValue = axisDefinition.getMaximum(); float baseValue = axisDefinition.getBaseline(); float minValue = axisDefinition.getMinimum(); double maxX = adjustedRect.getMaxX(); double x = adjustedRect.getX(); double y = adjustedRect.getY(); if ((baseValue > minValue) && (baseValue < maxValue)) { int baseY = computeYPixelValue(adjustedRect, axisDefinition, baseValue); getBaselineGraphics(context).drawLine((int) x, baseY, (int) maxX, baseY); } PreferenceManager prefs = PreferenceManager.getInstance(); Color altColor = track.getAltColor(); Color borderColor = (prefs.getAsBoolean(PreferenceManager.CHART_COLOR_BORDERS) && altColor != null && altColor.equals(track.getColor())) ? track.getColor() : Color.lightGray; Graphics2D borderGraphics = context.getGraphic2DForColor(borderColor); // Draw the baseline -- todo, this is a wig track option? double zeroValue = axisDefinition.getBaseline(); int zeroY = computeYPixelValue(adjustedRect, axisDefinition, zeroValue); borderGraphics.drawLine(adjustedRect.x, zeroY, adjustedRect.x + adjustedRect.width, zeroY); // Optionally draw "Y" line (UCSC track line option) if (track.isDrawYLine()) { Graphics2D yLineGraphics = context.getGraphic2DForColor(Color.gray); int yLine = computeYPixelValue(adjustedRect, axisDefinition, track.getYLine()); GraphicUtils.drawDashedLine( borderGraphics, adjustedRect.x, yLine, adjustedRect.x + adjustedRect.width, yLine); } // If the chart has + and - numbers draw both borders or none. This // needs documented somewhere. boolean drawBorders = true; if (minValue * maxValue < 0) { drawBorders = prefs.getAsBoolean(PreferenceManager.CHART_DRAW_BOTTOM_BORDER) && prefs.getAsBoolean(PreferenceManager.CHART_DRAW_TOP_BORDER); } if (drawBorders && prefs.getAsBoolean(PreferenceManager.CHART_DRAW_TOP_BORDER)) { borderGraphics.drawLine( adjustedRect.x, adjustedRect.y, adjustedRect.x + adjustedRect.width, adjustedRect.y); } if (drawBorders && prefs.getAsBoolean(PreferenceManager.CHART_DRAW_BOTTOM_BORDER)) { borderGraphics.drawLine( adjustedRect.x, adjustedRect.y + adjustedRect.height, adjustedRect.x + adjustedRect.width, adjustedRect.y + adjustedRect.height); } } /* (CHART_DRAW_TOP_BORDER)); prefs.setDrawBottomBorder(getBooleanPreference(CHART_DRAW_BOTTOM_BORDER)); prefs.setColorBorders(getBooleanPreference(CHART_COLOR_BORDERS)); prefs.setDrawAxis(getBooleanPreference(CHART_DRAW_Y_AXIS)); prefs.setDrawTrackName(getBooleanPreference(CHART_DRAW_TRACK_NAME)); prefs.setColorTrackName(getBooleanPreference(CHART_COLOR_TRACK_NAME)); prefs.setAutoscale(getBooleanPreference(CHART_AUTOSCALE)); prefs.setShowDataRange(getBooleanPreference(CHART_SHOW_DATA_RANGE)); */ }
/** * Method description * * @param track * @param context * @param arect */ @Override public void renderAxis(Track track, RenderContext context, Rectangle arect) { // For now disable axes for all chromosome view if (context.getChr().equals(Globals.CHR_ALL)) { return; } super.renderAxis(track, context, arect); Rectangle drawingRect = calculateDrawingRect(arect); PreferenceManager prefs = PreferenceManager.getInstance(); Color labelColor = prefs.getAsBoolean(PreferenceManager.CHART_COLOR_TRACK_NAME) ? track.getColor() : Color.black; Graphics2D labelGraphics = context.getGraphic2DForColor(labelColor); labelGraphics.setFont(FontManager.getFont(8)); if (prefs.getAsBoolean(PreferenceManager.CHART_DRAW_TRACK_NAME)) { // Only attempt if track height is > 25 pixels if (arect.getHeight() > 25) { Rectangle labelRect = new Rectangle(arect.x, arect.y + 10, arect.width, 10); labelGraphics.setFont(FontManager.getFont(10)); GraphicUtils.drawCenteredText(track.getName(), labelRect, labelGraphics); } } if (prefs.getAsBoolean(PreferenceManager.CHART_DRAW_Y_AXIS)) { Rectangle axisRect = new Rectangle(arect.x, arect.y + 1, AXIS_AREA_WIDTH, arect.height); DataRange axisDefinition = track.getDataRange(); float maxValue = axisDefinition.getMaximum(); float baseValue = axisDefinition.getBaseline(); float minValue = axisDefinition.getMinimum(); // Bottom (minimum tick mark) int pY = computeYPixelValue(drawingRect, axisDefinition, minValue); labelGraphics.drawLine( axisRect.x + AXIS_AREA_WIDTH - 10, pY, axisRect.x + AXIS_AREA_WIDTH - 5, pY); GraphicUtils.drawRightJustifiedText( formatter.format(minValue), axisRect.x + AXIS_AREA_WIDTH - 15, pY, labelGraphics); // Top (maximum tick mark) int topPY = computeYPixelValue(drawingRect, axisDefinition, maxValue); labelGraphics.drawLine( axisRect.x + AXIS_AREA_WIDTH - 10, topPY, axisRect.x + AXIS_AREA_WIDTH - 5, topPY); GraphicUtils.drawRightJustifiedText( formatter.format(maxValue), axisRect.x + AXIS_AREA_WIDTH - 15, topPY + 4, labelGraphics); // Connect top and bottom labelGraphics.drawLine( axisRect.x + AXIS_AREA_WIDTH - 10, topPY, axisRect.x + AXIS_AREA_WIDTH - 10, pY); // Middle tick mark. Draw only if room int midPY = computeYPixelValue(drawingRect, axisDefinition, baseValue); if ((midPY < pY - 15) && (midPY > topPY + 15)) { labelGraphics.drawLine( axisRect.x + AXIS_AREA_WIDTH - 10, midPY, axisRect.x + AXIS_AREA_WIDTH - 5, midPY); GraphicUtils.drawRightJustifiedText( formatter.format(baseValue), axisRect.x + AXIS_AREA_WIDTH - 15, midPY + 4, labelGraphics); } } else if (track.isShowDataRange() && arect.height > 20) { drawScale(track.getDataRange(), context, arect); } }