/// <summary> /// Draws the LimitLines associated with this axis to the screen. /// </summary> /// <param name="c"></param> public virtual void RenderLimitLines(SKCanvas c) { var limitLines = XAxis.LimitLines; if (limitLines == null || limitLines.Count <= 0) { return; } for (int i = 0; i < limitLines.Count; i++) { LimitLine l = limitLines[i]; if (!l.IsEnabled) { continue; } int clipRestoreCount = c.Save(); c.ClipRect(ViewPortHandler.ContentRect.InsetHorizontally(l.LineWidth)); var position = Trasformer.PointValueToPixel(l.Limit, 0.0f); RenderLimitLineLine(c, l, position); RenderLimitLineLabel(c, l, position, 2.0f + l.YOffset); c.RestoreToCount(clipRestoreCount); } }
protected override void DrawLabels(SKCanvas c, float pos, SKPoint anchor) { float labelRotationAngleDegrees = XAxis.LabelRotationAngle; var centeringEnabled = XAxis.IsCenterAxisLabelsEnabled; SKPoint[] positions = new SKPoint[XAxis.entryCount]; for (int i = 0; i < positions.Length; i++) { // only fill x values if (centeringEnabled) { positions[i].Y = XAxis.centeredEntries[i]; } else { positions[i].Y = XAxis.entries[i]; } } positions = Trasformer.PointValuesToPixel(positions); for (int i = 0; i < positions.Length; i++) { float y = positions[i].Y; if (ViewPortHandler.IsInBoundsY(y)) { DrawLabel(c, XAxis.ValueFormatter.GetFormattedValue(XAxis.entries[i], XAxis), pos, y, anchor, labelRotationAngleDegrees); } } }
/// <summary> /// draws the x-labels on the specified y-position /// </summary> protected virtual void DrawLabels(SKCanvas c, float pos, SKPoint anchor) { float labelRotationAngleDegrees = XAxis.LabelRotationAngle; var centeringEnabled = XAxis.IsCenterAxisLabelsEnabled; SKPoint[] positions = new SKPoint[XAxis.entryCount]; for (int i = 0; i < positions.Length; i++) { // only fill x values if (centeringEnabled) { positions[i].X = XAxis.centeredEntries[i]; } else { positions[i].X = XAxis.entries[i]; } } positions = Trasformer.PointValuesToPixel(positions); for (int i = 0; i < positions.Length; i++) { float x = positions[i].X; if (ViewPortHandler.IsInBoundsX(x)) { var label = XAxis.ValueFormatter.GetFormattedValue(XAxis.entries[i], XAxis); if (XAxis.AvoidFirstLastClipping) { // avoid clipping of the last if (i == XAxis.entryCount - 1 && XAxis.entryCount > 1) { float width = AxisLabelPaint.MeasureWidth(label); if (width > ViewPortHandler.OffsetRight * 2 && x + width > ViewPortHandler.ChartWidth) { x -= width / 2; } // avoid clipping of the first } else if (i == 0) { float width = AxisLabelPaint.MeasureWidth(label); x += width / 2; } } DrawLabel(c, label, x, pos, anchor, labelRotationAngleDegrees); } } }
/// <summary> /// Transforms the values contained in the axis entries to screen pixels and returns them in form of a float array /// of x- and y-coordinates. /// </summary> /// <returns></returns> protected virtual SKPoint[] GetTransformedPositions() { if (TransformedPositionsBuffer.Length != YAxis.entryCount) { TransformedPositionsBuffer = new SKPoint[YAxis.entryCount]; } SKPoint[] positions = TransformedPositionsBuffer; for (int i = 0; i < positions.Length; i++) { // only fill y values, x values are not needed for y-labels positions[i].Y = YAxis.entries[i]; } return(Trasformer.PointValuesToPixel(positions)); }
public void RenderGridLines(SKCanvas c) { if (!this.XAxis.IsDrawGridLinesEnabled || !this.XAxis.IsEnabled) { return; } int clipRestoreCount = c.Save(); c.ClipRect(GetGridClippingRect()); if (RenderGridLinesBuffer.Length != Axis.entryCount) { RenderGridLinesBuffer = new SKPoint[XAxis.entryCount]; } var positions = RenderGridLinesBuffer; for (int i = 0; i < positions.Length; i++) { float entry = (float)Axis.entries[i]; positions[i] = new SKPoint(entry, entry); } positions = Trasformer.PointValuesToPixel(positions); SetupGridPaint(); var gridLinePath = RenderGridLinesPath; gridLinePath.Reset(); foreach (SKPoint pos in positions) { DrawGridLine(c, pos, gridLinePath); } c.RestoreToCount(clipRestoreCount); }
public override void ComputeAxis(float min, float max, bool inverted) { // calculate the starting and entry point of the y-labels (depending on // zoom / contentrect bounds) if (ViewPortHandler.ContentWidth > 10 && !ViewPortHandler.IsFullyZoomedOutX) { var p1 = Trasformer.ValueByTouchPoint(ViewPortHandler.ContentLeft, ViewPortHandler.ContentTop); var p2 = Trasformer.ValueByTouchPoint(ViewPortHandler.ContentRight, ViewPortHandler.ContentTop); if (inverted) { min = (float)p2.X; max = (float)p1.X; } else { min = (float)p1.X; max = (float)p2.X; } } ComputeAxisValues(min, max); }
/// <summary> /// Draws the zero line. /// </summary> protected virtual void DrawZeroLine(SKCanvas c) { int clipRestoreCount = c.Save(); c.ClipRect(ViewPortHandler.ContentRect.InsetVertically(YAxis.ZeroLineWidth)); // draw zero line SKPoint pos = Trasformer.PixelsToValue(0f, 0f); ZeroLinePaint.Color = YAxis.ZeroLineColor; ZeroLinePaint.StrokeWidth = YAxis.ZeroLineWidth; SKPath zeroLinePath = DrawZeroLinePath; zeroLinePath.Reset(); zeroLinePath.MoveTo(ViewPortHandler.ContentLeft, (float)pos.Y); zeroLinePath.LineTo(ViewPortHandler.ContentRight, (float)pos.Y); // draw a path because lines don't support dashing on lower android versions c.DrawPath(zeroLinePath, ZeroLinePaint); c.RestoreToCount(clipRestoreCount); }
public virtual void RenderLimitLines(SKCanvas c) { IList <LimitLine> limitLines = YAxis.LimitLines; if (limitLines == null || limitLines.Count <= 0) { return; } SKPath limitLinePath = RenderLimitLinesPath; limitLinePath.Reset(); foreach (LimitLine l in limitLines) { if (!l.IsEnabled) { continue; } int clipRestoreCount = c.Save(); SKRect limitLineClippingRect = ViewPortHandler.ContentRect.InsetVertically(l.LineWidth); c.ClipRect(limitLineClippingRect); LimitLinePaint.Style = SKPaintStyle.Stroke; LimitLinePaint.Color = l.LineColor; LimitLinePaint.StrokeWidth = l.LineWidth; LimitLinePaint.PathEffect = l.DashPathEffect; SKPoint pt = Trasformer.PointValueToPixel(0f, l.Limit); limitLinePath.MoveTo(ViewPortHandler.ContentLeft, pt.Y); limitLinePath.LineTo(ViewPortHandler.ContentRight, pt.Y); c.DrawPath(limitLinePath, LimitLinePaint); limitLinePath.Reset(); // c.drawLines(pts, mLimitLinePaint); string label = l.Label; // if drawing the limit-value label is enabled if (string.IsNullOrEmpty(label) == false) { LimitLinePaint.Style = l.TextStyle; LimitLinePaint.PathEffect = null; LimitLinePaint.Typeface = l.Typeface; LimitLinePaint.Color = l.TextColor; LimitLinePaint.StrokeWidth = 0.5f; LimitLinePaint.TextSize = l.TextSize; float labelLineHeight = LimitLinePaint.MeasureHeight(label); float xOffset = 4f.DpToPixel() + l.XOffset; float yOffset = l.LineWidth + labelLineHeight + l.YOffset; LimitLine.LimitLabelPosition position = l.LabelPosition; if (position == LimitLine.LimitLabelPosition.RightTop) { LimitLinePaint.TextAlign = SKTextAlign.Right; c.DrawText(label, ViewPortHandler.ContentRight - xOffset, pt.Y - yOffset + labelLineHeight, LimitLinePaint); } else if (position == LimitLine.LimitLabelPosition.RightBottom) { LimitLinePaint.TextAlign = SKTextAlign.Right; c.DrawText(label, ViewPortHandler.ContentRight - xOffset, pt.Y + yOffset, LimitLinePaint); } else if (position == LimitLine.LimitLabelPosition.LeftTop) { LimitLinePaint.TextAlign = SKTextAlign.Left; c.DrawText(label, ViewPortHandler.ContentLeft + xOffset, pt.Y - yOffset + labelLineHeight, LimitLinePaint); } else { LimitLinePaint.TextAlign = SKTextAlign.Left; c.DrawText(label, ViewPortHandler.OffsetLeft + xOffset, pt.Y + yOffset, LimitLinePaint); } } c.RestoreToCount(clipRestoreCount); } }