/// <summary> /// Renders major tick text /// </summary> /// <param name="axis">The axis.</param> /// <param name="x">The x-value.</param> /// <param name="angleAxis">The angle axis.</param> private void RenderTickText(Axis axis, double x, Axis angleAxis) { var actualAngle = GetActualAngle(axis, angleAxis); var dx = axis.AxisTickToLabelDistance * Math.Sin(actualAngle); var dy = -axis.AxisTickToLabelDistance * Math.Cos(actualAngle); HorizontalAlignment ha; VerticalAlignment va; GetTickTextAligment(actualAngle, out ha, out va); var pt = axis.Transform(x, angleAxis.Angle, angleAxis); pt = new ScreenPoint(pt.X + dx, pt.Y + dy); string text = axis.FormatValue(x); this.RenderContext.DrawMathText( pt, text, axis.ActualTextColor, axis.ActualFont, axis.ActualFontSize, axis.ActualFontWeight, axis.Angle, ha, va); }
/// <summary> /// Renders the major items. /// </summary> /// <param name="axis">The axis.</param> /// <param name="axisPosition">The axis position.</param> /// <param name="titlePosition">The title position.</param> /// <param name="drawAxisLine">Draw the axis line if set to <c>true</c>.</param> protected virtual void RenderMajorItems(Axis axis, double axisPosition, double titlePosition, bool drawAxisLine) { double eps = axis.ActualMinorStep * 1e-3; double actualMinimum = axis.ActualMinimum; double actualMaximum = axis.ActualMaximum; double plotAreaLeft = this.Plot.PlotArea.Left; double plotAreaRight = this.Plot.PlotArea.Right; double plotAreaTop = this.Plot.PlotArea.Top; double plotAreaBottom = this.Plot.PlotArea.Bottom; bool isHorizontal = axis.IsHorizontal(); double a0; double a1; var majorSegments = new List<ScreenPoint>(); var majorTickSegments = new List<ScreenPoint>(); this.GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1); foreach (double value in this.MajorTickValues) { if (value < actualMinimum - eps || value > actualMaximum + eps) { continue; } if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps) { continue; } double transformedValue = axis.Transform(value); if (isHorizontal) { SnapTo(plotAreaLeft, ref transformedValue); SnapTo(plotAreaRight, ref transformedValue); } else { SnapTo(plotAreaTop, ref transformedValue); SnapTo(plotAreaBottom, ref transformedValue); } if (this.MajorPen != null) { if (isHorizontal) { majorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop)); majorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom)); } else { majorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue)); majorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue)); } } if (axis.TickStyle != TickStyle.None && axis.MajorTickSize > 0) { if (isHorizontal) { majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0)); majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1)); } else { majorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue)); majorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue)); } } } // Render the axis labels (numbers or category names) foreach (double value in this.MajorLabelValues) { if (value < actualMinimum - eps || value > actualMaximum + eps) { continue; } if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps) { continue; } double transformedValue = axis.Transform(value); if (isHorizontal) { SnapTo(plotAreaLeft, ref transformedValue); SnapTo(plotAreaRight, ref transformedValue); } else { SnapTo(plotAreaTop, ref transformedValue); SnapTo(plotAreaBottom, ref transformedValue); } var pt = new ScreenPoint(); var ha = HorizontalAlignment.Right; var va = VerticalAlignment.Middle; switch (axis.Position) { case AxisPosition.Left: pt = new ScreenPoint(axisPosition + a1 - axis.AxisTickToLabelDistance, transformedValue); this.GetRotatedAlignments( axis.Angle, HorizontalAlignment.Right, VerticalAlignment.Middle, out ha, out va); break; case AxisPosition.Right: pt = new ScreenPoint(axisPosition + a1 + axis.AxisTickToLabelDistance, transformedValue); this.GetRotatedAlignments( axis.Angle, HorizontalAlignment.Left, VerticalAlignment.Middle, out ha, out va); break; case AxisPosition.Top: pt = new ScreenPoint(transformedValue, axisPosition + a1 - axis.AxisTickToLabelDistance); this.GetRotatedAlignments( axis.Angle, HorizontalAlignment.Center, VerticalAlignment.Bottom, out ha, out va); break; case AxisPosition.Bottom: pt = new ScreenPoint(transformedValue, axisPosition + a1 + axis.AxisTickToLabelDistance); this.GetRotatedAlignments( axis.Angle, HorizontalAlignment.Center, VerticalAlignment.Top, out ha, out va); break; } string text = axis.FormatValue(value); this.RenderContext.DrawMathText( pt, text, axis.ActualTextColor, axis.ActualFont, axis.ActualFontSize, axis.ActualFontWeight, axis.Angle, ha, va); } // Draw the zero crossing line if (axis.PositionAtZeroCrossing && this.ZeroPen != null && this.IsWithin(0, actualMinimum, actualMaximum)) { double t0 = axis.Transform(0); if (isHorizontal) { this.RenderContext.DrawLine(t0, plotAreaTop, t0, plotAreaBottom, this.ZeroPen); } else { this.RenderContext.DrawLine(plotAreaLeft, t0, plotAreaRight, t0, this.ZeroPen); } } // Draw extra grid lines if (axis.ExtraGridlines != null && this.ExtraPen != null) { foreach (double value in axis.ExtraGridlines) { if (!this.IsWithin(value, actualMinimum, actualMaximum)) { continue; } double transformedValue = axis.Transform(value); if (isHorizontal) { this.RenderContext.DrawLine( transformedValue, plotAreaTop, transformedValue, plotAreaBottom, this.ExtraPen); } else { this.RenderContext.DrawLine( plotAreaLeft, transformedValue, plotAreaRight, transformedValue, this.ExtraPen); } } } if (drawAxisLine) { // Draw the axis line (across the tick marks) if (isHorizontal) { this.RenderContext.DrawLine( axis.Transform(actualMinimum), axisPosition, axis.Transform(actualMaximum), axisPosition, this.AxislinePen); } else { this.RenderContext.DrawLine( axisPosition, axis.Transform(actualMinimum), axisPosition, axis.Transform(actualMaximum), this.AxislinePen); } } if (this.MajorPen != null) { this.RenderContext.DrawLineSegments(majorSegments, this.MajorPen); } if (this.MajorTickPen != null) { this.RenderContext.DrawLineSegments(majorTickSegments, this.MajorTickPen); } }
/// <summary> /// Renders the specified axis. /// </summary> /// <param name="axis">The axis.</param> /// <param name="pass">The render pass.</param> /// <exception cref="System.InvalidOperationException">Magnitude axis not defined.</exception> public override void Render(Axis axis, int pass) { var angleAxis = (AngleAxis)axis; base.Render(axis, pass); var magnitudeAxis = this.Plot.DefaultMagnitudeAxis; if (magnitudeAxis == null) { throw new InvalidOperationException("Magnitude axis not defined."); } var scaledStartAngle = angleAxis.StartAngle / angleAxis.Scale; var scaledEndAngle = angleAxis.EndAngle / angleAxis.Scale; var axisLength = Math.Abs(scaledEndAngle - scaledStartAngle); var eps = axis.MinorStep * 1e-3; if (this.MinorPen != null) { var tickCount = Math.Abs((int)(axisLength / axis.ActualMinorStep)); var screenPoints = this.MinorTickValues .Where(x => x > Math.Min(scaledStartAngle, scaledEndAngle) - eps && x < Math.Max(scaledStartAngle, scaledEndAngle) + eps && !this.MajorTickValues.Contains(x)) .Take(tickCount + 1) .Select(x => magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, x, axis)); foreach (var screenPoint in screenPoints) { this.RenderContext.DrawLine(magnitudeAxis.MidPoint.x, magnitudeAxis.MidPoint.y, screenPoint.x, screenPoint.y, this.MinorPen, false); } } var isFullCircle = Math.Abs(Math.Abs(Math.Max(angleAxis.EndAngle, angleAxis.StartAngle) - Math.Min(angleAxis.StartAngle, angleAxis.EndAngle)) - 360) < 1e-3; var majorTickCount = (int)(axisLength / axis.ActualMajorStep); if (!isFullCircle) { majorTickCount++; } if (this.MajorPen != null) { var screenPoints = this.MajorTickValues .Where(x => x > Math.Min(scaledStartAngle, scaledEndAngle) - eps && x < Math.Max(scaledStartAngle, scaledEndAngle) + eps) .Take(majorTickCount) .Select(x => magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, x, axis)) .ToArray(); foreach (var point in screenPoints) { this.RenderContext.DrawLine(magnitudeAxis.MidPoint.x, magnitudeAxis.MidPoint.y, point.x, point.y, this.MajorPen, false); } } foreach (var value in this.MajorLabelValues.Take(majorTickCount)) { var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, value, axis); var angle = Math.Atan2(pt.y - magnitudeAxis.MidPoint.y, pt.x - magnitudeAxis.MidPoint.x); // add some margin pt.x += Math.Cos(angle) * axis.AxisTickToLabelDistance; pt.y += Math.Sin(angle) * axis.AxisTickToLabelDistance; // Convert to degrees angle *= 180 / Math.PI; var text = axis.FormatValue(value); var ha = HorizontalAlignment.Left; var va = VerticalAlignment.Middle; if (Math.Abs(Math.Abs(angle) - 90) < 10) { ha = HorizontalAlignment.Center; va = angle >= 90 ? VerticalAlignment.Top : VerticalAlignment.Bottom; angle = 0; } else if (angle > 90 || angle < -90) { angle -= 180; ha = HorizontalAlignment.Right; } this.RenderContext.DrawMathText( pt, text, axis.ActualTextColor, axis.ActualFont, axis.ActualFontSize, axis.ActualFontWeight, angle, ha, va); } }