List of usage examples for android.graphics Paint setStyle
public void setStyle(Style style)
From source file:net.droidsolutions.droidcharts.core.renderer.AbstractCategoryItemRenderer.java
/** * Draws a marker for the range axis./* w w w. j a va 2 s . co m*/ * * @param g2 * the graphics device (not <code>null</code>). * @param plot * the plot (not <code>null</code>). * @param axis * the range axis (not <code>null</code>). * @param marker * the marker to be drawn (not <code>null</code>). * @param dataArea * the area inside the axes (not <code>null</code>). * * @see #drawDomainMarker(Graphics2D, CategoryPlot, CategoryAxis, * CategoryMarker, Rectangle2D) */ public void drawRangeMarker(Canvas g2, CategoryPlot plot, ValueAxis axis, Marker marker, Rectangle2D dataArea) { if (marker instanceof ValueMarker) { ValueMarker vm = (ValueMarker) marker; double value = vm.getValue(); Range range = axis.getRange(); if (!range.contains(value)) { return; } PlotOrientation orientation = plot.getOrientation(); double v = axis.valueToJava2D(value, dataArea, plot.getRangeAxisEdge()); Line2D line = null; if (orientation == PlotOrientation.HORIZONTAL) { line = new Line2D.Double(v, dataArea.getMinY(), v, dataArea.getMaxY()); } else if (orientation == PlotOrientation.VERTICAL) { line = new Line2D.Double(dataArea.getMinX(), v, dataArea.getMaxX(), v); } Paint p = marker.getPaint(); p.setAlpha(vm.getAlpha()); p.setStrokeWidth(marker.getStroke()); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), p); String label = marker.getLabel(); RectangleAnchor anchor = marker.getLabelAnchor(); if (label != null) { Font labelFont = marker.getLabelFont(); // g2.setFont(labelFont); Point2D coordinates = calculateRangeMarkerTextAnchorPoint(g2, orientation, dataArea, line.getBounds2D(), marker.getLabelOffset(), LengthAdjustmentType.EXPAND, anchor); TextUtilities.drawAlignedString(label, g2, (float) coordinates.getX(), (float) coordinates.getY(), marker.getLabelTextAnchor(), marker.getLabelPaint()); } // g2.setComposite(savedComposite); p.setAlpha(255); } else if (marker instanceof IntervalMarker) { IntervalMarker im = (IntervalMarker) marker; double start = im.getStartValue(); double end = im.getEndValue(); Range range = axis.getRange(); if (!(range.intersects(start, end))) { return; } double start2d = axis.valueToJava2D(start, dataArea, plot.getRangeAxisEdge()); double end2d = axis.valueToJava2D(end, dataArea, plot.getRangeAxisEdge()); double low = Math.min(start2d, end2d); double high = Math.max(start2d, end2d); PlotOrientation orientation = plot.getOrientation(); Rectangle2D rect = null; if (orientation == PlotOrientation.HORIZONTAL) { // clip left and right bounds to data area low = Math.max(low, dataArea.getMinX()); high = Math.min(high, dataArea.getMaxX()); rect = new Rectangle2D.Double(low, dataArea.getMinY(), high - low, dataArea.getHeight()); } else if (orientation == PlotOrientation.VERTICAL) { // clip top and bottom bounds to data area low = Math.max(low, dataArea.getMinY()); high = Math.min(high, dataArea.getMaxY()); rect = new Rectangle2D.Double(dataArea.getMinX(), low, dataArea.getWidth(), high - low); } Paint p = marker.getPaint(); p.setAlpha((int) marker.getAlpha() * 100);// TODO ALPHA p.setStyle(Paint.Style.FILL); g2.drawRect((float) rect.getMinX(), (float) rect.getMinY(), (float) rect.getMaxX(), (float) rect.getMinY(), p); // now draw the outlines, if visible... if (im.getOutlinePaint() != null && im.getOutlineStroke() != 0.0f) { if (orientation == PlotOrientation.VERTICAL) { Line2D line = new Line2D.Double(); double x0 = dataArea.getMinX(); double x1 = dataArea.getMaxX(); Paint paint = im.getOutlinePaint(); paint.setStrokeWidth(im.getOutlineStroke()); if (range.contains(start)) { line.setLine(x0, start2d, x1, start2d); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } if (range.contains(end)) { line.setLine(x0, end2d, x1, end2d); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } } else { // PlotOrientation.HORIZONTAL Line2D line = new Line2D.Double(); double y0 = dataArea.getMinY(); double y1 = dataArea.getMaxY(); Paint paint = im.getOutlinePaint(); paint.setStrokeWidth(im.getOutlineStroke()); if (range.contains(start)) { line.setLine(start2d, y0, start2d, y1); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } if (range.contains(end)) { line.setLine(end2d, y0, end2d, y1); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } } } String label = marker.getLabel(); RectangleAnchor anchor = marker.getLabelAnchor(); if (label != null) { Font labelFont = marker.getLabelFont(); // g2.setFont(labelFont); Paint pp = marker.getLabelPaint(); // g2.setPaint(marker.getLabelPaint()); Point2D coordinates = calculateRangeMarkerTextAnchorPoint(g2, orientation, dataArea, rect, marker.getLabelOffset(), marker.getLabelOffsetType(), anchor); TextUtilities.drawAlignedString(label, g2, (float) coordinates.getX(), (float) coordinates.getY(), marker.getLabelTextAnchor(), pp); } p.setAlpha(255); } }
From source file:de.tum.in.tumcampus.auxiliary.calendar.DayView.java
private void drawGridBackground(Rect r, Canvas canvas, Paint p) { Style savedStyle = p.getStyle(); final float stopX = computeDayLeftPosition(mNumDays); float y = 0;/*from ww w . ja v a 2 s . c o m*/ final float deltaY = mCellHeight + HOUR_GAP; int linesIndex = 0; final float startY = 0; final float stopY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP); float x = mHoursWidth; // Draw the inner horizontal grid lines p.setColor(mCalendarGridLineInnerHorizontalColor); p.setStrokeWidth(GRID_LINE_INNER_WIDTH); p.setAntiAlias(false); y = 0; linesIndex = 0; for (int hour = 0; hour <= 24; hour++) { mLines[linesIndex++] = GRID_LINE_LEFT_MARGIN; mLines[linesIndex++] = y; mLines[linesIndex++] = stopX; mLines[linesIndex++] = y; y += deltaY; } if (mCalendarGridLineInnerVerticalColor != mCalendarGridLineInnerHorizontalColor) { canvas.drawLines(mLines, 0, linesIndex, p); linesIndex = 0; p.setColor(mCalendarGridLineInnerVerticalColor); } // Draw the inner vertical grid lines for (int day = 0; day <= mNumDays; day++) { x = computeDayLeftPosition(day); mLines[linesIndex++] = x; mLines[linesIndex++] = startY; mLines[linesIndex++] = x; mLines[linesIndex++] = stopY; } canvas.drawLines(mLines, 0, linesIndex, p); // Restore the saved style. p.setStyle(savedStyle); p.setAntiAlias(true); }
From source file:net.droidsolutions.droidcharts.core.plot.XYPlot.java
/** * Draws the quadrants.// ww w. j a va 2 s . c o m * * @param g2 * the graphics device. * @param area * the area. * * @see #setQuadrantOrigin(Point2D) * @see #setQuadrantPaint(int, Paint) */ protected void drawQuadrants(Canvas g2, Rectangle2D area) { // 0 | 1 // --+-- // 2 | 3 boolean somethingToDraw = false; ValueAxis xAxis = getDomainAxis(); if (xAxis == null) { // we can't draw quadrants without a valid x-axis return; } double x = xAxis.getRange().constrain(this.quadrantOrigin.getX()); double xx = xAxis.valueToJava2D(x, area, getDomainAxisEdge()); ValueAxis yAxis = getRangeAxis(); if (yAxis == null) { // we can't draw quadrants without a valid y-axis return; } double y = yAxis.getRange().constrain(this.quadrantOrigin.getY()); double yy = yAxis.valueToJava2D(y, area, getRangeAxisEdge()); double xmin = xAxis.getLowerBound(); double xxmin = xAxis.valueToJava2D(xmin, area, getDomainAxisEdge()); double xmax = xAxis.getUpperBound(); double xxmax = xAxis.valueToJava2D(xmax, area, getDomainAxisEdge()); double ymin = yAxis.getLowerBound(); double yymin = yAxis.valueToJava2D(ymin, area, getRangeAxisEdge()); double ymax = yAxis.getUpperBound(); double yymax = yAxis.valueToJava2D(ymax, area, getRangeAxisEdge()); Rectangle2D[] r = new Rectangle2D[] { null, null, null, null }; if (this.quadrantPaint[0] != null) { if (x > xmin && y < ymax) { if (this.orientation == PlotOrientation.HORIZONTAL) { r[0] = new Rectangle2D.Double(Math.min(yymax, yy), Math.min(xxmin, xx), Math.abs(yy - yymax), Math.abs(xx - xxmin)); } else { // PlotOrientation.VERTICAL r[0] = new Rectangle2D.Double(Math.min(xxmin, xx), Math.min(yymax, yy), Math.abs(xx - xxmin), Math.abs(yy - yymax)); } somethingToDraw = true; } } if (this.quadrantPaint[1] != null) { if (x < xmax && y < ymax) { if (this.orientation == PlotOrientation.HORIZONTAL) { r[1] = new Rectangle2D.Double(Math.min(yymax, yy), Math.min(xxmax, xx), Math.abs(yy - yymax), Math.abs(xx - xxmax)); } else { // PlotOrientation.VERTICAL r[1] = new Rectangle2D.Double(Math.min(xx, xxmax), Math.min(yymax, yy), Math.abs(xx - xxmax), Math.abs(yy - yymax)); } somethingToDraw = true; } } if (this.quadrantPaint[2] != null) { if (x > xmin && y > ymin) { if (this.orientation == PlotOrientation.HORIZONTAL) { r[2] = new Rectangle2D.Double(Math.min(yymin, yy), Math.min(xxmin, xx), Math.abs(yy - yymin), Math.abs(xx - xxmin)); } else { // PlotOrientation.VERTICAL r[2] = new Rectangle2D.Double(Math.min(xxmin, xx), Math.min(yymin, yy), Math.abs(xx - xxmin), Math.abs(yy - yymin)); } somethingToDraw = true; } } if (this.quadrantPaint[3] != null) { if (x < xmax && y > ymin) { if (this.orientation == PlotOrientation.HORIZONTAL) { r[3] = new Rectangle2D.Double(Math.min(yymin, yy), Math.min(xxmax, xx), Math.abs(yy - yymin), Math.abs(xx - xxmax)); } else { // PlotOrientation.VERTICAL r[3] = new Rectangle2D.Double(Math.min(xx, xxmax), Math.min(yymin, yy), Math.abs(xx - xxmax), Math.abs(yy - yymin)); } somethingToDraw = true; } } if (somethingToDraw) { for (int i = 0; i < 4; i++) { if (this.quadrantPaint[i] != null && r[i] != null) { Paint paint = this.quadrantPaint[i]; paint.setStyle(Paint.Style.FILL); int oldAlpha = paint.getAlpha(); paint.setAlpha(getBackgroundAlpha()); g2.drawRect((float) r[i].getMinX(), (float) r[i].getMinY(), (float) r[i].getMaxX(), (float) r[i].getMaxY(), paint); paint.setAlpha(oldAlpha); } } } }
From source file:net.droidsolutions.droidcharts.core.plot.XYPlot.java
/** * Utility method for drawing a horizontal line across the data area of the * plot./*ww w . j a va2 s . c om*/ * * @param g2 * the graphics device. * @param dataArea * the data area. * @param value * the coordinate, where to draw the line. * @param stroke * the stroke to use. * @param paint * the paint to use. */ protected void drawHorizontalLine(Canvas g2, Rectangle2D dataArea, double value, Float stroke, Paint paint) { ValueAxis axis = getRangeAxis(); if (getOrientation() == PlotOrientation.HORIZONTAL) { axis = getDomainAxis(); } if (axis.getRange().contains(value)) { double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT); Line2D line = new Line2D.Double(dataArea.getMinX(), yy, dataArea.getMaxX(), yy); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(stroke); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } }
From source file:net.droidsolutions.droidcharts.core.plot.XYPlot.java
/** * Utility method for drawing a vertical line on the data area of the plot. * //from w w w. j av a 2s.c o m * @param g2 * the graphics device. * @param dataArea * the data area. * @param value * the coordinate, where to draw the line. * @param stroke * the stroke to use. * @param paint * the paint to use. */ protected void drawVerticalLine(Canvas g2, Rectangle2D dataArea, double value, Float stroke, Paint paint) { ValueAxis axis = getDomainAxis(); if (getOrientation() == PlotOrientation.HORIZONTAL) { axis = getRangeAxis(); } if (axis.getRange().contains(value)) { double xx = axis.valueToJava2D(value, dataArea, RectangleEdge.BOTTOM); Line2D line = new Line2D.Double(xx, dataArea.getMinY(), xx, dataArea.getMaxY()); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(stroke); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } }
From source file:net.droidsolutions.droidcharts.core.plot.XYPlot.java
/** * Draws a domain crosshair./* w ww .j a va 2 s . c o m*/ * * @param g2 * the graphics target. * @param dataArea * the data area. * @param orientation * the plot orientation. * @param value * the crosshair value. * @param axis * the axis against which the value is measured. * @param stroke * the stroke used to draw the crosshair line. * @param paint * the paint used to draw the crosshair line. * * @since 1.0.4 */ protected void drawDomainCrosshair(Canvas g2, Rectangle2D dataArea, PlotOrientation orientation, double value, ValueAxis axis, Float stroke, Paint paint) { if (axis.getRange().contains(value)) { Line2D line = null; if (orientation == PlotOrientation.VERTICAL) { double xx = axis.valueToJava2D(value, dataArea, RectangleEdge.BOTTOM); line = new Line2D.Double(xx, dataArea.getMinY(), xx, dataArea.getMaxY()); } else { double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT); line = new Line2D.Double(dataArea.getMinX(), yy, dataArea.getMaxX(), yy); } paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(stroke); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } }
From source file:net.droidsolutions.droidcharts.core.plot.XYPlot.java
/** * Draws a range crosshair./*ww w. java2 s . c om*/ * * @param g2 * the graphics target. * @param dataArea * the data area. * @param orientation * the plot orientation. * @param value * the crosshair value. * @param axis * the axis against which the value is measured. * @param stroke * the stroke used to draw the crosshair line. * @param paint * the paint used to draw the crosshair line. * * @since 1.0.4 */ protected void drawRangeCrosshair(Canvas g2, Rectangle2D dataArea, PlotOrientation orientation, double value, ValueAxis axis, Float stroke, Paint paint) { if (axis.getRange().contains(value)) { Line2D line = null; if (orientation == PlotOrientation.HORIZONTAL) { double xx = axis.valueToJava2D(value, dataArea, RectangleEdge.BOTTOM); line = new Line2D.Double(xx, dataArea.getMinY(), xx, dataArea.getMaxY()); } else { double yy = axis.valueToJava2D(value, dataArea, RectangleEdge.LEFT); line = new Line2D.Double(dataArea.getMinX(), yy, dataArea.getMaxX(), yy); } paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(stroke); g2.drawLine((float) line.getX1(), (float) line.getY1(), (float) line.getX2(), (float) line.getY2(), paint); } }
From source file:com.skytree.epubtest.BookViewActivity.java
@SuppressLint({ "DrawAllocation", "DrawAllocation" }) @Override/*from ww w . j a v a 2 s . co m*/ protected void onDraw(Canvas canvas) { Paint paint = new Paint(); float sl, sr, st, sb; sl = 0; sr = this.getWidth(); float ah = this.arrowHeight; // arrow Height; if (this.isArrowDown) { st = 0; sb = this.getHeight() - ah; } else { st = ah - 10; sb = this.getHeight() - 10; } Path boxPath = new Path(); boxPath.addRoundRect(new RectF(sl, st, sr, sb), 20, 20, Path.Direction.CW); if (arrowPosition <= arrowHeight * 1.5f) { arrowPosition = arrowHeight * 1.5f; } else if (arrowPosition >= this.getWidth() - arrowHeight * 1.5f) { arrowPosition = this.getWidth() - arrowHeight * 1.5f; } Path arrowPath = new Path(); if (isArrowDown) { arrowPath.moveTo(arrowPosition, sb + ah); arrowPath.lineTo((float) (arrowPosition - ah * 0.75), sb - 10); arrowPath.lineTo((float) (arrowPosition + ah * 0.75), sb - 10); arrowPath.close(); } else { arrowPath.moveTo(arrowPosition, 0); arrowPath.lineTo((float) (arrowPosition - ah * 0.75), ah + 10); arrowPath.lineTo((float) (arrowPosition + ah * 0.75), ah + 10); arrowPath.close(); } paint.setColor(this.strokeColor); paint.setStyle(Paint.Style.FILL); boxPath.addPath(arrowPath); canvas.drawPath(boxPath, paint); paint.setColor(this.boxColor); paint.setStyle(Paint.Style.FILL); boxPath.addPath(arrowPath); canvas.save(); float sf = 0.995f; float ox = (this.getWidth() - (this.getWidth() * sf)) / 2.0f; float oy = ((this.getHeight() - arrowHeight) - ((this.getHeight() - arrowHeight) * sf)) / 2.0f; canvas.translate(ox, oy); canvas.scale(sf, sf); canvas.drawPath(boxPath, paint); canvas.restore(); if (layoutChanged) { this.recalcLayout(); layoutChanged = false; } }
From source file:com.jjoe64.graphview.series.LineGraphSeries.java
/** * plots the series/*from www .j a v a 2 s . co m*/ * draws the line and the background * * @param graphView graphview * @param canvas canvas * @param isSecondScale flag if it is the second scale */ @Override public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { resetDataPoints(); // get data double maxX = graphView.getViewport().getMaxX(false); double minX = graphView.getViewport().getMinX(false); double maxY; double minY; if (isSecondScale) { maxY = graphView.getSecondScale().getMaxY(false); minY = graphView.getSecondScale().getMinY(false); } else { maxY = graphView.getViewport().getMaxY(false); minY = graphView.getViewport().getMinY(false); } Iterator<E> values = getValues(minX, maxX); // draw background double lastEndY = 0; double lastEndX = 0; // draw data mPaint.setStrokeWidth(mStyles.thickness); mPaint.setColor(getColor()); mPaintBackground.setColor(mStyles.backgroundColor); Paint paint; if (mCustomPaint != null) { paint = mCustomPaint; } else { paint = mPaint; } mPath.reset(); if (mStyles.drawBackground) { mPathBackground.reset(); } double diffY = maxY - minY; double diffX = maxX - minX; float graphHeight = graphView.getGraphContentHeight(); float graphWidth = graphView.getGraphContentWidth(); float graphLeft = graphView.getGraphContentLeft(); float graphTop = graphView.getGraphContentTop(); lastEndY = 0; lastEndX = 0; // needed to end the path for background double lastUsedEndX = 0; double lastUsedEndY = 0; float firstX = -1; float firstY = -1; float lastRenderedX = Float.NaN; int i = 0; float lastAnimationReferenceX = graphLeft; boolean sameXSkip = false; float minYOnSameX = 0f; float maxYOnSameX = 0f; while (values.hasNext()) { E value = values.next(); double valY = value.getY() - minY; double ratY = valY / diffY; double y = graphHeight * ratY; double valueX = value.getX(); double valX = valueX - minX; double ratX = valX / diffX; double x = graphWidth * ratX; double orgX = x; double orgY = y; if (i > 0) { // overdraw boolean isOverdrawY = false; boolean isOverdrawEndPoint = false; boolean skipDraw = false; if (x > graphWidth) { // end right double b = ((graphWidth - lastEndX) * (y - lastEndY) / (x - lastEndX)); y = lastEndY + b; x = graphWidth; isOverdrawEndPoint = true; } if (y < 0) { // end bottom // skip when previous and this point is out of bound if (lastEndY < 0) { skipDraw = true; } else { double b = ((0 - lastEndY) * (x - lastEndX) / (y - lastEndY)); x = lastEndX + b; } y = 0; isOverdrawY = isOverdrawEndPoint = true; } if (y > graphHeight) { // end top // skip when previous and this point is out of bound if (lastEndY > graphHeight) { skipDraw = true; } else { double b = ((graphHeight - lastEndY) * (x - lastEndX) / (y - lastEndY)); x = lastEndX + b; } y = graphHeight; isOverdrawY = isOverdrawEndPoint = true; } if (lastEndX < 0) { // start left double b = ((0 - x) * (y - lastEndY) / (lastEndX - x)); lastEndY = y - b; lastEndX = 0; } // we need to save the X before it will be corrected when overdraw y float orgStartX = (float) lastEndX + (graphLeft + 1); if (lastEndY < 0) { // start bottom if (!skipDraw) { double b = ((0 - y) * (x - lastEndX) / (lastEndY - y)); lastEndX = x - b; } lastEndY = 0; isOverdrawY = true; } if (lastEndY > graphHeight) { // start top // skip when previous and this point is out of bound if (!skipDraw) { double b = ((graphHeight - y) * (x - lastEndX) / (lastEndY - y)); lastEndX = x - b; } lastEndY = graphHeight; isOverdrawY = true; } float startX = (float) lastEndX + (graphLeft + 1); float startY = (float) (graphTop - lastEndY) + graphHeight; float endX = (float) x + (graphLeft + 1); float endY = (float) (graphTop - y) + graphHeight; float startXAnimated = startX; float endXAnimated = endX; if (endX < startX) { // dont draw from right to left skipDraw = true; } // NaN can happen when previous and current value is out of y bounds if (!skipDraw && !Float.isNaN(startY) && !Float.isNaN(endY)) { // animation if (mAnimated) { if ((Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) { long currentTime = System.currentTimeMillis(); if (mAnimationStart == 0) { // start animation mAnimationStart = currentTime; mAnimationStartFrameNo = 0; } else { // anti-lag: wait a few frames if (mAnimationStartFrameNo < 15) { // second time mAnimationStart = currentTime; mAnimationStartFrameNo++; } } float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION; float factor = mAnimationInterpolator.getInterpolation(timeFactor); if (timeFactor <= 1.0) { startXAnimated = (startX - lastAnimationReferenceX) * factor + lastAnimationReferenceX; startXAnimated = Math.max(startXAnimated, lastAnimationReferenceX); endXAnimated = (endX - lastAnimationReferenceX) * factor + lastAnimationReferenceX; ViewCompat.postInvalidateOnAnimation(graphView); } else { // animation finished mLastAnimatedValue = valueX; } } else { lastAnimationReferenceX = endX; } } // draw data point if (!isOverdrawEndPoint) { if (mStyles.drawDataPoints) { // draw first datapoint Paint.Style prevStyle = paint.getStyle(); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(endXAnimated, endY, mStyles.dataPointsRadius, paint); paint.setStyle(prevStyle); } registerDataPoint(endX, endY, value); } if (mDrawAsPath) { mPath.moveTo(startXAnimated, startY); } // performance opt. if (Float.isNaN(lastRenderedX) || Math.abs(endX - lastRenderedX) > .3f) { if (mDrawAsPath) { mPath.lineTo(endXAnimated, endY); } else { // render vertical lines that were skipped if (sameXSkip) { sameXSkip = false; renderLine(canvas, new float[] { lastRenderedX, minYOnSameX, lastRenderedX, maxYOnSameX }, paint); } renderLine(canvas, new float[] { startXAnimated, startY, endXAnimated, endY }, paint); } lastRenderedX = endX; } else { // rendering on same x position // save min+max y position and render it as line if (sameXSkip) { minYOnSameX = Math.min(minYOnSameX, endY); maxYOnSameX = Math.max(maxYOnSameX, endY); } else { // first sameXSkip = true; minYOnSameX = Math.min(startY, endY); maxYOnSameX = Math.max(startY, endY); } } } if (mStyles.drawBackground) { if (isOverdrawY) { // start draw original x if (firstX == -1) { firstX = orgStartX; firstY = startY; mPathBackground.moveTo(orgStartX, startY); } // from original start to new start mPathBackground.lineTo(startXAnimated, startY); } if (firstX == -1) { firstX = startXAnimated; firstY = startY; mPathBackground.moveTo(startXAnimated, startY); } mPathBackground.lineTo(startXAnimated, startY); mPathBackground.lineTo(endXAnimated, endY); } lastUsedEndX = endXAnimated; lastUsedEndY = endY; } else if (mStyles.drawDataPoints) { //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above) float first_X = (float) x + (graphLeft + 1); float first_Y = (float) (graphTop - y) + graphHeight; if (first_X >= graphLeft && first_Y <= (graphTop + graphHeight)) { if (mAnimated && (Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) { long currentTime = System.currentTimeMillis(); if (mAnimationStart == 0) { // start animation mAnimationStart = currentTime; } float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION; float factor = mAnimationInterpolator.getInterpolation(timeFactor); if (timeFactor <= 1.0) { first_X = (first_X - lastAnimationReferenceX) * factor + lastAnimationReferenceX; ViewCompat.postInvalidateOnAnimation(graphView); } else { // animation finished mLastAnimatedValue = valueX; } } Paint.Style prevStyle = paint.getStyle(); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(first_X, first_Y, mStyles.dataPointsRadius, paint); paint.setStyle(prevStyle); } } lastEndY = orgY; lastEndX = orgX; i++; } if (mDrawAsPath) { // draw at the end canvas.drawPath(mPath, paint); } if (mStyles.drawBackground && firstX != -1) { // end / close path if (lastUsedEndY != graphHeight + graphTop) { // dont draw line to same point, otherwise the path is completely broken mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop); } mPathBackground.lineTo(firstX, graphHeight + graphTop); if (firstY != graphHeight + graphTop) { // dont draw line to same point, otherwise the path is completely broken mPathBackground.lineTo(firstX, firstY); } //mPathBackground.close(); canvas.drawPath(mPathBackground, mPaintBackground); } }
From source file:p5e610.graphview.series.LineGraphSeries.java
/** * plots the series/* ww w .ja v a 2s . c om*/ * draws the line and the background * * @param graphView graphview * @param canvas canvas * @param isSecondScale flag if it is the second scale */ @Override public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { resetDataPoints(); // get data double maxY = Double.NEGATIVE_INFINITY; double maxX = Double.NEGATIVE_INFINITY; double minY = Double.POSITIVE_INFINITY; double minX = Double.POSITIVE_INFINITY; boolean minXSet = graphView.getViewport().getMinX(false) != null; boolean maxXSet = graphView.getViewport().getMaxX(false) != null; boolean minYSet = graphView.getViewport().getMinY(false) != null; boolean maxYSet = graphView.getViewport().getMaxY(false) != null; if (minXSet) minX = graphView.getViewport().getMinX(false); if (maxXSet) { maxX = graphView.getViewport().getMaxX(false); } if (minYSet) { minY = graphView.getViewport().getMinY(false); } if (maxYSet) { maxY = graphView.getViewport().getMaxY(false); } for (E val : mData) { double currX = val.getX(); double currY = val.getY(); if (currX > maxX && !maxXSet) maxX = currX; if (currY > maxY && !maxYSet) maxY = currY; if (currX < minX && !minXSet) minX = currX; if (currY < minY && !minYSet) minY = currY; } Iterator<E> values = getValues(minX, maxX); // draw background double lastEndY = 0; double lastEndX = 0; // draw data mPaint.setStrokeWidth(mStyles.thickness); mPaint.setColor(getColor()); mPaintBackground.setColor(mStyles.backgroundColor); Paint paint; if (mCustomPaint != null) { paint = mCustomPaint; } else { paint = mPaint; } mPath.reset(); if (mStyles.drawBackground) { mPathBackground.reset(); } double diffY = maxY - minY; double diffX = maxX - minX; float graphHeight = graphView.getGraphContentHeight(); float graphWidth = graphView.getGraphContentWidth(); float graphLeft = graphView.getGraphContentLeft(); float graphTop = graphView.getGraphContentTop(); lastEndY = 0; lastEndX = 0; // needed to end the path for background double lastUsedEndX = 0; double lastUsedEndY = 0; float firstX = -1; float firstY = -1; float lastRenderedX = Float.NaN; int i = 0; float lastAnimationReferenceX = graphLeft; boolean sameXSkip = false; float minYOnSameX = 0f; float maxYOnSameX = 0f; while (values.hasNext()) { E value = values.next(); double valY = value.getY() - minY; double ratY = valY / diffY; double y = graphHeight * ratY; double valueX = value.getX(); double valX = valueX - minX; double ratX = valX / diffX; double x = graphWidth * ratX; double orgX = x; double orgY = y; if (i > 0) { // overdraw boolean isOverdrawY = false; boolean isOverdrawEndPoint = false; boolean skipDraw = false; if (x > graphWidth) { // end right double b = ((graphWidth - lastEndX) * (y - lastEndY) / (x - lastEndX)); y = lastEndY + b; x = graphWidth; isOverdrawEndPoint = true; } if (y < 0) { // end bottom // skip when previous and this point is out of bound if (lastEndY < 0) { skipDraw = true; } else { double b = ((0 - lastEndY) * (x - lastEndX) / (y - lastEndY)); x = lastEndX + b; } y = 0; isOverdrawY = isOverdrawEndPoint = true; } if (y > graphHeight) { // end top // skip when previous and this point is out of bound if (lastEndY > graphHeight) { skipDraw = true; } else { double b = ((graphHeight - lastEndY) * (x - lastEndX) / (y - lastEndY)); x = lastEndX + b; } y = graphHeight; isOverdrawY = isOverdrawEndPoint = true; } if (lastEndX < 0) { // start left double b = ((0 - x) * (y - lastEndY) / (lastEndX - x)); lastEndY = y - b; lastEndX = 0; } // we need to save the X before it will be corrected when overdraw y float orgStartX = (float) lastEndX + (graphLeft + 1); if (lastEndY < 0) { // start bottom if (!skipDraw) { double b = ((0 - y) * (x - lastEndX) / (lastEndY - y)); lastEndX = x - b; } lastEndY = 0; isOverdrawY = true; } if (lastEndY > graphHeight) { // start top // skip when previous and this point is out of bound if (!skipDraw) { double b = ((graphHeight - y) * (x - lastEndX) / (lastEndY - y)); lastEndX = x - b; } lastEndY = graphHeight; isOverdrawY = true; } float startX = (float) lastEndX + (graphLeft + 1); float startY = (float) (graphTop - lastEndY) + graphHeight; float endX = (float) x + (graphLeft + 1); float endY = (float) (graphTop - y) + graphHeight; float startXAnimated = startX; float endXAnimated = endX; // if (endX < startX) { // // dont draw from right to left // skipDraw = true; // } // NaN can happen when previous and current value is out of y bounds if (!skipDraw && !Float.isNaN(startY) && !Float.isNaN(endY)) { // animation if (mAnimated) { if ((Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) { long currentTime = System.currentTimeMillis(); if (mAnimationStart == 0) { // start animation mAnimationStart = currentTime; mAnimationStartFrameNo = 0; } else { // anti-lag: wait a few frames if (mAnimationStartFrameNo < 15) { // second time mAnimationStart = currentTime; mAnimationStartFrameNo++; } } float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION; float factor = mAnimationInterpolator.getInterpolation(timeFactor); if (timeFactor <= 1.0) { startXAnimated = (startX - lastAnimationReferenceX) * factor + lastAnimationReferenceX; startXAnimated = Math.max(startXAnimated, lastAnimationReferenceX); endXAnimated = (endX - lastAnimationReferenceX) * factor + lastAnimationReferenceX; ViewCompat.postInvalidateOnAnimation(graphView); } else { // animation finished mLastAnimatedValue = valueX; } } else { lastAnimationReferenceX = endX; } } // draw data point if (!isOverdrawEndPoint) { if (mStyles.drawDataPoints) { // draw first datapoint Paint.Style prevStyle = paint.getStyle(); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(endXAnimated, endY, mStyles.dataPointsRadius, paint); paint.setStyle(prevStyle); } registerDataPoint(endX, endY, value); } if (mDrawAsPath) { mPath.moveTo(startXAnimated, startY); } // performance opt. if (Float.isNaN(lastRenderedX) || Math.abs(endX - lastRenderedX) > .3f) { if (mDrawAsPath) { mPath.lineTo(endXAnimated, endY); } else { // render vertical lines that were skipped if (sameXSkip) { sameXSkip = false; renderLine(canvas, new float[] { lastRenderedX, minYOnSameX, lastRenderedX, maxYOnSameX }, paint); } renderLine(canvas, new float[] { startXAnimated, startY, endXAnimated, endY }, paint); } lastRenderedX = endX; } else { // rendering on same x position // save min+max y position and render it as line if (sameXSkip) { minYOnSameX = Math.min(minYOnSameX, endY); maxYOnSameX = Math.max(maxYOnSameX, endY); } else { // first sameXSkip = true; minYOnSameX = Math.min(startY, endY); maxYOnSameX = Math.max(startY, endY); } } } if (mStyles.drawBackground) { if (isOverdrawY) { // start draw original x if (firstX == -1) { firstX = orgStartX; firstY = startY; mPathBackground.moveTo(orgStartX, startY); } // from original start to new start mPathBackground.lineTo(startXAnimated, startY); } if (firstX == -1) { firstX = startXAnimated; firstY = startY; mPathBackground.moveTo(startXAnimated, startY); } mPathBackground.lineTo(startXAnimated, startY); mPathBackground.lineTo(endXAnimated, endY); } lastUsedEndX = endXAnimated; lastUsedEndY = endY; } else if (mStyles.drawDataPoints) { //fix: last value not drawn as datapoint. Draw first point here, and then on every step the end values (above) float first_X = (float) x + (graphLeft + 1); float first_Y = (float) (graphTop - y) + graphHeight; if (first_X >= graphLeft && first_Y <= (graphTop + graphHeight)) { if (mAnimated && (Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) { long currentTime = System.currentTimeMillis(); if (mAnimationStart == 0) { // start animation mAnimationStart = currentTime; } float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION; float factor = mAnimationInterpolator.getInterpolation(timeFactor); if (timeFactor <= 1.0) { first_X = (first_X - lastAnimationReferenceX) * factor + lastAnimationReferenceX; ViewCompat.postInvalidateOnAnimation(graphView); } else { // animation finished mLastAnimatedValue = valueX; } } Paint.Style prevStyle = paint.getStyle(); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(first_X, first_Y, mStyles.dataPointsRadius, paint); paint.setStyle(prevStyle); } } lastEndY = orgY; lastEndX = orgX; i++; } if (mDrawAsPath) { // draw at the end canvas.drawPath(mPath, paint); } if (mStyles.drawBackground && firstX != -1) { // end / close path if (lastUsedEndY != graphHeight + graphTop) { // dont draw line to same point, otherwise the path is completely broken mPathBackground.lineTo((float) lastUsedEndX, graphHeight + graphTop); } mPathBackground.lineTo(firstX, graphHeight + graphTop); if (firstY != graphHeight + graphTop) { // dont draw line to same point, otherwise the path is completely broken mPathBackground.lineTo(firstX, firstY); } //mPathBackground.close(); canvas.drawPath(mPathBackground, mPaintBackground); } }