public void Render(Axis axis) { if (axis == null) return; axis.GetTickValues(out majorTickValues, out minorTickValues); CreatePens(axis); if (axis.IsHorizontal()) { RenderHorizontalAxis(axis, Plot.DefaultYAxis); } if (axis.IsVertical()) { RenderVerticalAxis(axis, Plot.DefaultXAxis); } if (axis.Position == AxisPosition.Angle) { RenderAngleAxis(axis, Plot.DefaultMagnitudeAxis); } if (axis.Position == AxisPosition.Magnitude) { RenderMagnitudeAxis(axis, Plot.DefaultAngleAxis); } }
/// <summary> /// The render. /// </summary> /// <param name="axis"> /// The axis. /// </param> /// <param name="pass"> /// The render pass. /// </param> public override void Render(Axis axis, int pass) { base.Render(axis, pass); double totalShift = axis.PositionTierMinShift; double tierSize = axis.PositionTierSize - this.Plot.AxisTierDistance; // store properties locally for performance double plotAreaLeft = this.Plot.PlotArea.Left; double plotAreaRight = this.Plot.PlotArea.Right; double plotAreaTop = this.Plot.PlotArea.Top; double plotAreaBottom = this.Plot.PlotArea.Bottom; // Axis position (x or y screen coordinate) double axisPosition = 0; double titlePosition = 0; switch (axis.Position) { case AxisPosition.Left: axisPosition = plotAreaLeft - totalShift; titlePosition = axisPosition - tierSize; break; case AxisPosition.Right: axisPosition = plotAreaRight + totalShift; titlePosition = axisPosition + tierSize; break; case AxisPosition.Top: axisPosition = plotAreaTop - totalShift; titlePosition = axisPosition - tierSize; break; case AxisPosition.Bottom: axisPosition = plotAreaBottom + totalShift; titlePosition = axisPosition + tierSize; break; } if (axis.PositionAtZeroCrossing) { var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis; axisPosition = perpendicularAxis.Transform(0); } if (pass == 0) { this.RenderMinorItems(axis, axisPosition); } if (pass == 1) { this.RenderMajorItems(axis, axisPosition, titlePosition); } }
/// <summary> /// The get tick positions. /// </summary> /// <param name="axis"> /// The axis. /// </param> /// <param name="glt"> /// The glt. /// </param> /// <param name="ticksize"> /// The ticksize. /// </param> /// <param name="position"> /// The position. /// </param> /// <param name="x0"> /// The x 0. /// </param> /// <param name="x1"> /// The x 1. /// </param> protected void GetTickPositions( Axis axis, TickStyle glt, double ticksize, AxisPosition position, out double x0, out double x1) { x0 = 0; x1 = 0; bool isTopOrLeft = position == AxisPosition.Top || position == AxisPosition.Left; double sign = isTopOrLeft ? -1 : 1; switch (glt) { case TickStyle.Crossing: x0 = -ticksize * sign * 0.75; x1 = ticksize * sign * 0.75; break; case TickStyle.Inside: x0 = -ticksize * sign; break; case TickStyle.Outside: x1 = ticksize * sign; break; } }
/// <summary> /// The render. /// </summary> /// <param name="axis">The axis.</param> /// <param name="pass">The render pass.</param> public virtual void Render(Axis axis, int pass) { if (axis == null) { return; } axis.GetTickValues(out this.MajorLabelValues, out this.MajorTickValues, out this.MinorTickValues); this.CreatePens(axis); }
/// <summary> /// Checks if the specified value is valid. /// </summary> /// <param name="v"> /// The value. /// </param> /// <param name="yaxis"> /// The y axis. /// </param> /// <returns> /// True if the value is valid. /// </returns> public virtual bool IsValidPoint(double v, Axis yaxis) { return !double.IsNaN(v) && !double.IsInfinity(v); }
/// <summary> /// Transforms the specified point to screen coordinates. /// </summary> /// <param name="p"> /// The point. /// </param> /// <param name="xaxis"> /// The x axis. /// </param> /// <param name="yaxis"> /// The y axis. /// </param> /// <returns> /// The transformed point. /// </returns> public static ScreenPoint Transform(IDataPoint p, Axis xaxis, Axis yaxis) { return xaxis.Transform(p.X, p.Y, yaxis); }
/// <summary> /// Transforms the specified point to screen coordinates. /// </summary> /// <param name="x"> /// The x value (for the current axis). /// </param> /// <param name="y"> /// The y value. /// </param> /// <param name="yaxis"> /// The y axis. /// </param> /// <returns> /// The transformed point. /// </returns> public virtual ScreenPoint Transform(double x, double y, Axis yaxis) { if (yaxis == null) { throw new NullReferenceException("Y axis should not be null when transforming."); } return new ScreenPoint(this.Transform(x), yaxis.Transform(y)); }
/// <summary> /// Gets the axis for the specified key. /// </summary> /// <param name="key">The key.</param> /// <param name="defaultAxis">The default axis.</param> /// <returns>The axis, or the defaultAxis if the key is not found.</returns> public Axis GetAxisOrDefault(string key, Axis defaultAxis) { if (key != null) { return this.Axes.FirstOrDefault(a => a.Key == key) ?? defaultAxis; } return defaultAxis; }
/// <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> private void RenderMajorItems(Axis axis, double axisPosition, double titlePosition) { 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) { 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 = HorizontalTextAlign.Right; var va = VerticalTextAlign.Middle; switch (axis.Position) { case AxisPosition.Left: pt = new ScreenPoint(axisPosition + a1 - axis.AxisTickToLabelDistance, transformedValue); this.GetRotatedAlignments( axis.Angle, HorizontalTextAlign.Right, VerticalTextAlign.Middle, out ha, out va); break; case AxisPosition.Right: pt = new ScreenPoint(axisPosition + a1 + axis.AxisTickToLabelDistance, transformedValue); this.GetRotatedAlignments( axis.Angle, HorizontalTextAlign.Left, VerticalTextAlign.Middle, out ha, out va); break; case AxisPosition.Top: pt = new ScreenPoint(transformedValue, axisPosition + a1 - axis.AxisTickToLabelDistance); this.GetRotatedAlignments( axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Bottom, out ha, out va); break; case AxisPosition.Bottom: pt = new ScreenPoint(transformedValue, axisPosition + a1 + axis.AxisTickToLabelDistance); this.GetRotatedAlignments( axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Top, out ha, out va); break; } string text = axis.FormatValue(value); this.rc.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) { double t0 = axis.Transform(0); if (isHorizontal) { this.rc.DrawLine(t0, plotAreaTop, t0, plotAreaBottom, this.ZeroPen); } else { this.rc.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.rc.DrawLine(transformedValue, plotAreaTop, transformedValue, plotAreaBottom, this.ExtraPen); } else { this.rc.DrawLine(plotAreaLeft, transformedValue, plotAreaRight, transformedValue, this.ExtraPen); } } } // Draw the axis line (across the tick marks) if (isHorizontal) { this.rc.DrawLine( axis.Transform(actualMinimum), axisPosition, axis.Transform(actualMaximum), axisPosition, this.AxislinePen); } else { this.rc.DrawLine( axisPosition, axis.Transform(actualMinimum), axisPosition, axis.Transform(actualMaximum), this.AxislinePen); } // Draw the axis title if (!string.IsNullOrEmpty(axis.ActualTitle)) { this.RenderAxisTitle(axis, titlePosition); } if (this.MajorPen != null) { this.rc.DrawLineSegments(majorSegments, this.MajorPen); } if (this.MajorTickPen != null) { this.rc.DrawLineSegments(majorTickSegments, this.MajorTickPen); } }
/// <summary> /// Renders the axis title. /// </summary> /// <param name="axis"> /// The axis. /// </param> /// <param name="titlePosition"> /// The title position. /// </param> private void RenderAxisTitle(Axis axis, double titlePosition) { bool isHorizontal = axis.IsHorizontal(); OxySize? maxSize = null; if (axis.ClipTitle) { // Calculate the title clipping dimensions double screenLength = isHorizontal ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X) : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y); maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue); } double angle = -90; var halign = HorizontalTextAlign.Center; var valign = VerticalTextAlign.Top; var lpt = this.GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign); this.rc.SetToolTip(axis.ToolTip); this.rc.DrawText( lpt, axis.ActualTitle, axis.ActualTitleColor, axis.ActualTitleFont, axis.ActualTitleFontSize, axis.ActualTitleFontWeight, angle, halign, valign, maxSize); this.rc.SetToolTip(null); }
/// <summary> /// Gets the axis title position, rotation and alignment. /// </summary> /// <param name="axis"> /// The axis. /// </param> /// <param name="titlePosition"> /// The title position. /// </param> /// <param name="angle"> /// The angle. /// </param> /// <param name="halign"> /// The horizontal alignment. /// </param> /// <param name="valign"> /// The vertical alignment. /// </param> /// <returns> /// The <see cref="ScreenPoint"/>. /// </returns> protected virtual ScreenPoint GetAxisTitlePositionAndAlignment( Axis axis, double titlePosition, ref double angle, ref HorizontalTextAlign halign, ref VerticalTextAlign valign) { double middle = axis.IsHorizontal() ? Lerp(axis.ScreenMin.X, axis.ScreenMax.X, axis.TitlePosition) : Lerp(axis.ScreenMax.Y, axis.ScreenMin.Y, axis.TitlePosition); if (axis.PositionAtZeroCrossing) { var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis; middle = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum); } switch (axis.Position) { case AxisPosition.Left: return new ScreenPoint(titlePosition, middle); case AxisPosition.Right: valign = VerticalTextAlign.Bottom; return new ScreenPoint(titlePosition, middle); case AxisPosition.Top: halign = HorizontalTextAlign.Center; valign = VerticalTextAlign.Top; angle = 0; return new ScreenPoint(middle, titlePosition); case AxisPosition.Bottom: halign = HorizontalTextAlign.Center; valign = VerticalTextAlign.Bottom; angle = 0; return new ScreenPoint(middle, titlePosition); default: throw new ArgumentOutOfRangeException("axis"); } }
/// <summary> /// Determines whether the specified point is valid. /// </summary> /// <param name="pt"> /// The pointt. /// </param> /// <param name="xaxis"> /// The x axis. /// </param> /// <param name="yaxis"> /// The y axis. /// </param> /// <returns> /// <c>true</c> if the point is valid; otherwise, <c>false</c> . /// </returns> protected virtual bool IsValidPoint(IDataPoint pt, Axis xaxis, Axis yaxis) { return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.Y) && !double.IsInfinity(pt.Y) && (xaxis != null && xaxis.IsValidValue(pt.X)) && (yaxis != null && yaxis.IsValidValue(pt.Y)); }
/// <summary> /// Check if the data series is using the specified axis. /// </summary> /// <param name="axis"> /// An axis. /// </param> /// <returns> /// True if the axis is in use. /// </returns> protected internal override bool IsUsing(Axis axis) { return false; }
public override void Render(Axis axis) { base.Render(axis); var perpendicularAxis = Plot.DefaultXAxis; bool isHorizontal = true; // Axis position (x or y screen coordinate) double apos = 0; switch (axis.Position) { case AxisPosition.Left: apos = Plot.PlotArea.Left; isHorizontal = false; break; case AxisPosition.Right: apos = Plot.PlotArea.Right; isHorizontal = false; break; case AxisPosition.Top: apos = Plot.PlotArea.Top; perpendicularAxis = Plot.DefaultYAxis; break; case AxisPosition.Bottom: apos = Plot.PlotArea.Bottom; perpendicularAxis = Plot.DefaultYAxis; break; } if (axis.PositionAtZeroCrossing) { apos = perpendicularAxis.Transform(0); } double a0, a1; if (axis.ShowMinorTicks) { GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1); foreach (double value in MinorTickValues) { if (value < axis.ActualMinimum || value > axis.ActualMaximum) { continue; } if (MajorTickValues.Contains(value)) { continue; } double transformedValue = axis.Transform(value); if (MinorPen != null) { if (isHorizontal) { rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MinorPen); } else { rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MinorPen); } } if (isHorizontal) { rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MinorTickPen); } else { rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MinorTickPen); } } } GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1); double maxWidth = 0; double maxHeight = 0; foreach (double value in MajorTickValues) { if (value < axis.ActualMinimum || value > axis.ActualMaximum) continue; double transformedValue = axis.Transform(value); if (MajorPen != null) { if (isHorizontal) { rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MajorPen); } else { rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MajorPen); } } if (isHorizontal) { rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MajorTickPen); } else { rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MajorTickPen); } if (value == 0 && axis.PositionAtZeroCrossing) continue; var pt = new ScreenPoint(); var ha = HorizontalTextAlign.Right; var va = VerticalTextAlign.Middle; switch (axis.Position) { case AxisPosition.Left: pt = new ScreenPoint(apos + a1 - TICK_DIST, transformedValue); GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Right, VerticalTextAlign.Middle, out ha, out va); break; case AxisPosition.Right: pt = new ScreenPoint(apos + a1 + TICK_DIST, transformedValue); GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Left, VerticalTextAlign.Middle, out ha, out va); break; case AxisPosition.Top: pt = new ScreenPoint(transformedValue, apos + a1 - TICK_DIST); GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Bottom, out ha, out va); break; case AxisPosition.Bottom: pt = new ScreenPoint(transformedValue, apos + a1 + TICK_DIST); GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Top, out ha, out va); break; } string text = axis.FormatValue(value); var size = rc.DrawMathText(pt, text, Plot.TextColor, axis.FontFamily, axis.FontSize, axis.FontWeight, axis.Angle, ha, va); maxWidth = Math.Max(maxWidth, size.Width); maxHeight = Math.Max(maxHeight, size.Height); } if (axis.PositionAtZeroCrossing) { double t0 = axis.Transform(0); if (isHorizontal) { rc.DrawLine(t0, Plot.PlotArea.Top, t0, Plot.PlotArea.Bottom, ZeroPen); } else { rc.DrawLine(Plot.PlotArea.Left, t0, Plot.PlotArea.Right, t0, ZeroPen); } } if (axis.ExtraGridlines != null) { foreach (double value in axis.ExtraGridlines) { if (!IsWithin(value, axis.ActualMinimum, axis.ActualMaximum)) continue; double transformedValue = axis.Transform(value); if (isHorizontal) { rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, ExtraPen); } else { rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, ExtraPen); } } } if (isHorizontal) { rc.DrawLine(Plot.PlotArea.Left, apos, Plot.PlotArea.Right, apos, MajorPen); } else { rc.DrawLine(apos, Plot.PlotArea.Top, apos, Plot.PlotArea.Bottom, MajorPen); } if (!String.IsNullOrWhiteSpace(axis.Title)) { // Axis legend double ymid = axis.Transform((axis.ActualMinimum + axis.ActualMaximum) / 2); double angle = -90; var lpt = new ScreenPoint(); var halign = HorizontalTextAlign.Center; var valign = VerticalTextAlign.Top; if (axis.PositionAtZeroCrossing) { ymid = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum); // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom; } switch (axis.Position) { case AxisPosition.Left: lpt = new ScreenPoint(AXIS_LEGEND_DIST, ymid); break; case AxisPosition.Right: lpt = new ScreenPoint(rc.Width - AXIS_LEGEND_DIST, ymid); valign = VerticalTextAlign.Bottom; break; case AxisPosition.Top: lpt = new ScreenPoint(ymid, AXIS_LEGEND_DIST); halign = HorizontalTextAlign.Center; valign = VerticalTextAlign.Top; angle = 0; break; case AxisPosition.Bottom: lpt = new ScreenPoint(ymid, rc.Height - AXIS_LEGEND_DIST); halign = HorizontalTextAlign.Center; valign = VerticalTextAlign.Bottom; angle = 0; break; } rc.DrawText(lpt, axis.Title, Plot.TextColor, axis.FontFamily, axis.FontSize, axis.FontWeight, angle, halign, valign); } }
public virtual Point InverseTransform(double x, double y, Axis yAxis) { Debug.Assert(yAxis != null); if (IsPolar) { x -= MidPoint.X; y -= MidPoint.Y; double th = Math.Atan2(y, x); double r = Math.Sqrt(x * x + y * y); x = r / Scale + Offset; y = yAxis != null ? th / yAxis.Scale + yAxis.Offset : double.NaN; return new Point(x, y); } return new Point(InverseTransformX(x), yAxis.InverseTransformX(y)); }
private void RenderVerticalAxis(Axis axis, Axis perpendicularAxis) { double x = Plot.Bounds.Left; switch (axis.Position) { case AxisPosition.Left: x = Plot.Bounds.Left; break; case AxisPosition.Right: x = Plot.Bounds.Right; break; } if (axis.PositionAtZeroCrossing) x = perpendicularAxis.TransformX(0); double x0, x1; if (axis.ShowMinorTicks) { GetHorizontalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out x0, out x1); foreach (double yValue in minorTickValues) { if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum) { continue; } if (majorTickValues.Contains(yValue)) { continue; } double y = axis.TransformX(yValue); if (minorPen != null) { RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, minorPen); } RenderLine(x + x0, y, x + x1, y, minorTickPen); } } GetHorizontalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out x0, out x1); double maxw = 0; bool isleft = axis.Position == AxisPosition.Left; foreach (double yValue in majorTickValues) { if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum) continue; double y = axis.TransformX(yValue); if (majorPen != null) { RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen); } RenderLine(x + x0, y, x + x1, y, majorTickPen); if (yValue == 0 && axis.PositionAtZeroCrossing) continue; var pt = new ScreenPoint(isleft ? x + x1 - TICK_DIST : x + x1 + TICK_DIST, y); string text = axis.FormatValue(yValue); double w = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height; rc.DrawText(pt, text, Plot.TextColor, axis.FontFamily, axis.FontSize, axis.FontWeight, axis.Angle, isleft ? HorizontalTextAlign.Right : HorizontalTextAlign.Left, VerticalTextAlign.Middle); maxw = Math.Max(maxw, w); } if (axis.PositionAtZeroCrossing) { double y = axis.TransformX(0); RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, zeroPen); } if (axis.ExtraGridlines != null) foreach (double y in axis.ExtraGridlines) { if (!IsWithin(y, axis.ActualMinimum, axis.ActualMaximum)) continue; double sy = axis.TransformX(y); RenderLine(Plot.Bounds.Left, sy, Plot.Bounds.Right, sy, extraPen); } RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen); double ymid = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2); HorizontalTextAlign halign = HorizontalTextAlign.Center; VerticalTextAlign valign = VerticalTextAlign.Top; if (axis.PositionAtZeroCrossing) { ymid = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum); // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom; } if (isleft) { x = AXIS_LEGEND_DIST; } else { x = rc.Width - AXIS_LEGEND_DIST; valign = VerticalTextAlign.Bottom; } rc.DrawText(new ScreenPoint(x, ymid), axis.Title, Plot.TextColor, axis.FontFamily, axis.FontSize, axis.FontWeight, -90, halign, valign); }
/// <summary> /// Renders the minor items. /// </summary> /// <param name="axis"> /// The axis. /// </param> /// <param name="axisPosition"> /// The axis position. /// </param> private void RenderMinorItems(Axis axis, double axisPosition) { 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 minorSegments = new List<ScreenPoint>(); var minorTickSegments = new List<ScreenPoint>(); this.GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1); foreach (double value in this.MinorTickValues) { if (value < actualMinimum - eps || value > actualMaximum + eps) { continue; } if (this.MajorTickValues.Contains(value)) { 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); } // Draw the minor grid line if (this.MinorPen != null) { if (isHorizontal) { minorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop)); minorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom)); } else { if (transformedValue < plotAreaTop || transformedValue > plotAreaBottom) { } minorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue)); minorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue)); } } // Draw the minor tick if (axis.TickStyle != TickStyle.None) { if (isHorizontal) { minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0)); minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1)); } else { minorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue)); minorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue)); } } } // Draw all the line segments); if (this.MinorPen != null) { this.rc.DrawLineSegments(minorSegments, this.MinorPen); } if (this.MinorTickPen != null) { this.rc.DrawLineSegments(minorTickSegments, this.MinorTickPen); } }
private void RenderMagnitudeAxis(Axis axis, Axis angleAxis) { if (axis.RelatedAxis != null) angleAxis = axis.RelatedAxis; if (axis.ShowMinorTicks) { // GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1); foreach (double xValue in minorTickValues) { if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum) { continue; } if (majorTickValues.Contains(xValue)) { continue; } var pts = new List<ScreenPoint>(); for (double th = angleAxis.ActualMinimum; th <= angleAxis.ActualMaximum; th += angleAxis.MinorStep*0.1) { pts.Add(axis.Transform(xValue, th, angleAxis)); } if (minorPen != null) { rc.DrawLine(pts, minorPen.Color, minorPen.Thickness, minorPen.DashArray); } // RenderGridline(x, y + y0, x, y + y1, minorTickPen); } } // GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1); foreach (double xValue in majorTickValues) { if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum) { continue; } var pts = new List<ScreenPoint>(); for (double th = angleAxis.ActualMinimum; th <= angleAxis.ActualMaximum; th += angleAxis.MinorStep*0.1) { pts.Add(axis.Transform(xValue, th, angleAxis)); } if (majorPen != null) { rc.DrawLine(pts, majorPen.Color, majorPen.Thickness, majorPen.DashArray); } // RenderGridline(x, y + y0, x, y + y1, majorTickPen); //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST); //string text = axis.FormatValue(xValue); //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height; //rc.DrawText(pt, text, plot.TextColor, // axis.FontFamily, axis.FontSize, axis.FontWeight, // axis.Angle, // HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top); //maxh = Math.Max(maxh, h); } }
/// <summary> /// Check if the data series is using the specified axis. /// </summary> /// <param name="axis"> /// An axis which should be checked if used /// </param> /// <returns> /// True if the axis is in use. /// </returns> protected internal abstract bool IsUsing(Axis axis);
/// <summary> /// Gets the first axes that covers the area of the specified point. /// </summary> /// <param name="pt"> /// The point. /// </param> /// <param name="xaxis"> /// The xaxis. /// </param> /// <param name="yaxis"> /// The yaxis. /// </param> public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis) { xaxis = yaxis = null; // Get the axis position of the given point. Using null if the point is inside the plot area. AxisPosition? position = null; double plotAreaValue = 0; if (pt.X < this.PlotArea.Left) { position = AxisPosition.Left; plotAreaValue = this.PlotArea.Left; } if (pt.X > this.PlotArea.Right) { position = AxisPosition.Right; plotAreaValue = this.PlotArea.Right; } if (pt.Y < this.PlotArea.Top) { position = AxisPosition.Top; plotAreaValue = this.PlotArea.Top; } if (pt.Y > this.PlotArea.Bottom) { position = AxisPosition.Bottom; plotAreaValue = this.PlotArea.Bottom; } foreach (var axis in this.Axes) { if (axis is ColorAxis) { continue; } if (axis is MagnitudeAxis) { xaxis = axis; continue; } if (axis is AngleAxis) { yaxis = axis; continue; } double x = double.NaN; if (axis.IsHorizontal()) { x = axis.InverseTransform(pt.X); } if (axis.IsVertical()) { x = axis.InverseTransform(pt.Y); } if (x >= axis.ActualMinimum && x <= axis.ActualMaximum) { if (position == null) { if (axis.IsHorizontal()) { if (xaxis == null) { xaxis = axis; } } else if (axis.IsVertical()) { if (yaxis == null) { yaxis = axis; } } } else if (position == axis.Position) { // Choose right tier double positionTierMinShift = axis.PositionTierMinShift; double positionTierMaxShift = axis.PositionTierMaxShift; double posValue = axis.IsHorizontal() ? pt.Y : pt.X; bool isLeftOrTop = position == AxisPosition.Top || position == AxisPosition.Left; if ((posValue >= plotAreaValue + positionTierMinShift && posValue < plotAreaValue + positionTierMaxShift && !isLeftOrTop) || (posValue <= plotAreaValue - positionTierMinShift && posValue > plotAreaValue - positionTierMaxShift && isLeftOrTop)) { if (axis.IsHorizontal()) { if (xaxis == null) { xaxis = axis; } } else if (axis.IsVertical()) { if (yaxis == null) { yaxis = axis; } } } } } } }
private void RenderAngleAxis(Axis axis, Axis magnitudeAxis) { if (axis.RelatedAxis != null) magnitudeAxis = axis.RelatedAxis; if (axis.ShowMinorTicks) { // GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1); foreach (double xValue in minorTickValues) { if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum) { continue; } if (majorTickValues.Contains(xValue)) { continue; } var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis); if (minorPen != null) { RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, minorPen, false); } // RenderGridline(x, y + y0, x, y + y1, minorTickPen); } } // GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1); foreach (double xValue in majorTickValues) { if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum) { continue; } var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis); if (majorPen != null) { RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, majorPen, false); } // RenderGridline(x, y + y0, x, y + y1, majorTickPen); //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST); //string text = axis.FormatValue(xValue); //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height; //rc.DrawText(pt, text, plot.TextColor, // axis.FontFamily, axis.FontSize, axis.FontWeight, // axis.Angle, // HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top); //maxh = Math.Max(maxh, h); } }
/// <summary> /// Transform the specified screen point to data coordinates. /// </summary> /// <param name="p">The point.</param> /// <param name="xaxis">The x axis.</param> /// <param name="yaxis">The y axis.</param> /// <returns>The data point.</returns> public static DataPoint InverseTransform(ScreenPoint p, Axis xaxis, Axis yaxis) { return xaxis.InverseTransform(p.x, p.y, yaxis); }
private void GetVerticalTickPositions(Axis axis, TickStyle glt, double ticksize, out double y0, out double y1) { y0 = 0; y1 = 0; bool istop = axis.Position == AxisPosition.Top; double topsign = istop ? -1 : 1; switch (glt) { case TickStyle.Crossing: y0 = -ticksize*topsign; y1 = ticksize*topsign; break; case TickStyle.Inside: y0 = -ticksize*topsign; break; case TickStyle.Outside: y1 = ticksize*topsign; break; } }
/// <summary> /// Inverse transform the specified screen point. /// </summary> /// <param name="x"> /// The x coordinate. /// </param> /// <param name="y"> /// The y coordinate. /// </param> /// <param name="yaxis"> /// The y-axis. /// </param> /// <returns> /// The data point. /// </returns> public virtual DataPoint InverseTransform(double x, double y, Axis yaxis) { return new DataPoint(this.InverseTransform(x), yaxis != null ? yaxis.InverseTransform(y) : 0); }
private void GetHorizontalTickPositions(Axis axis, TickStyle glt, double ticksize, out double x0, out double x1) { x0 = 0; x1 = 0; bool isLeft = axis.Position == AxisPosition.Left; double leftSign = isLeft ? -1 : 1; switch (glt) { case TickStyle.Crossing: x0 = -ticksize*leftSign; x1 = ticksize*leftSign; break; case TickStyle.Inside: x0 = -ticksize*leftSign; break; case TickStyle.Outside: x1 = ticksize*leftSign; break; } }
/// <summary> /// Check if the data series is using the specified axis. /// </summary> /// <param name="axis"> /// An axis which should be checked if used /// </param> /// <returns> /// True if the axis is in use. /// </returns> protected internal override bool IsUsing(Axis axis) { return this.XAxis == axis || this.YAxis == axis; }
public void CreatePens(Axis axis) { minorPen = CreatePen(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle); majorPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle); minorTickPen = CreatePen(axis.TicklineColor, axis.MinorGridlineThickness, LineStyle.Solid); majorTickPen = CreatePen(axis.TicklineColor, axis.MajorGridlineThickness, LineStyle.Solid); zeroPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle); extraPen = CreatePen(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle); }
/// <summary> /// The create pens. /// </summary> /// <param name="axis"> /// The axis. /// </param> protected void CreatePens(Axis axis) { this.MinorPen = OxyPen.Create(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle); this.MajorPen = OxyPen.Create(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle); this.MinorTickPen = OxyPen.Create(axis.TicklineColor, axis.MinorGridlineThickness); this.MajorTickPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness); this.ZeroPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness); this.ExtraPen = OxyPen.Create(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle); this.AxislinePen = OxyPen.Create(axis.AxislineColor, axis.AxislineThickness, axis.AxislineStyle); }
private void RenderHorizontalAxis(Axis axis, Axis perpendicularAxis) { double y = Plot.Bounds.Bottom; switch (axis.Position) { case AxisPosition.Top: y = Plot.Bounds.Top; break; case AxisPosition.Bottom: y = Plot.Bounds.Bottom; break; } if (axis.PositionAtZeroCrossing) { y = perpendicularAxis.TransformX(0); } double y0, y1; if (axis.ShowMinorTicks) { GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1); foreach (double xValue in minorTickValues) { if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum) { continue; } if (majorTickValues.Contains(xValue)) { continue; } double x = axis.TransformX(xValue); if (minorPen != null) { RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, minorPen); } RenderLine(x, y + y0, x, y + y1, minorTickPen); } } GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1); double maxh = 0; bool istop = axis.Position == AxisPosition.Top; foreach (double xValue in majorTickValues) { if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum) { continue; } double x = axis.TransformX(xValue); if (majorPen != null) { RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen); } RenderLine(x, y + y0, x, y + y1, majorTickPen); if (xValue == 0 && axis.PositionAtZeroCrossing) continue; var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST); string text = axis.FormatValue(xValue); double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height; rc.DrawText(pt, text, Plot.TextColor, axis.FontFamily, axis.FontSize, axis.FontWeight, axis.Angle, HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top); maxh = Math.Max(maxh, h); } if (axis.PositionAtZeroCrossing) { double x = axis.TransformX(0); RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, zeroPen); } if (axis.ExtraGridlines != null) { foreach (double x in axis.ExtraGridlines) { if (!IsWithin(x, axis.ActualMinimum, axis.ActualMaximum)) continue; double sx = axis.TransformX(x); RenderLine(sx, Plot.Bounds.Top, sx, Plot.Bounds.Bottom, extraPen); } } // The horizontal axis line RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen); // The horizontal axis legend (centered horizontally) double legendX = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2); HorizontalTextAlign halign = HorizontalTextAlign.Center; VerticalTextAlign valign = VerticalTextAlign.Bottom; if (axis.PositionAtZeroCrossing) { legendX = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum); } double legendY = rc.Height - AXIS_LEGEND_DIST; if (istop) { legendY = AXIS_LEGEND_DIST; valign = VerticalTextAlign.Top; } rc.DrawText(new ScreenPoint(legendX, legendY), axis.Title, Plot.TextColor, axis.FontFamily, axis.FontSize, axis.FontWeight, 0, halign, valign); }
/// <summary> /// Determines whether the point is valid. /// </summary> /// <param name="pt">The point.</param> /// <param name="xaxis">The x axis.</param> /// <param name="yaxis">The y axis.</param> /// <returns> /// <c>true</c> if [is valid point] [the specified pt]; otherwise, <c>false</c>. /// </returns> public virtual bool IsValidItem(HighLowItem pt, Axis xaxis, Axis yaxis) { return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.High) && !double.IsInfinity(pt.High) && !double.IsNaN(pt.Low) && !double.IsInfinity(pt.Low); }
/// <summary> /// Gets the first axes that covers the area of the specified point. /// </summary> /// <param name="pt"> /// The point. /// </param> /// <param name="xaxis"> /// The xaxis. /// </param> /// <param name="yaxis"> /// The yaxis. /// </param> public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis) { xaxis = yaxis = null; // Get the axis position of the given point. Using null if the point is inside the plot area. AxisPosition?position = null; double plotAreaValue = 0; if (pt.X < this.PlotArea.Left) { position = AxisPosition.Left; plotAreaValue = this.PlotArea.Left; } if (pt.X > this.PlotArea.Right) { position = AxisPosition.Right; plotAreaValue = this.PlotArea.Right; } if (pt.Y < this.PlotArea.Top) { position = AxisPosition.Top; plotAreaValue = this.PlotArea.Top; } if (pt.Y > this.PlotArea.Bottom) { position = AxisPosition.Bottom; plotAreaValue = this.PlotArea.Bottom; } foreach (var axis in this.Axes) { if (axis is ColorAxis) { continue; } if (axis is MagnitudeAxis) { xaxis = axis; continue; } if (axis is AngleAxis) { yaxis = axis; continue; } double x = double.NaN; if (axis.IsHorizontal()) { x = axis.InverseTransform(pt.X); } if (axis.IsVertical()) { x = axis.InverseTransform(pt.Y); } if (x >= axis.ActualMinimum && x <= axis.ActualMaximum) { if (position == null) { if (axis.IsHorizontal()) { if (xaxis == null) { xaxis = axis; } } else if (axis.IsVertical()) { if (yaxis == null) { yaxis = axis; } } } else if (position == axis.Position) { // Choose right tier double positionTierMinShift = axis.PositionTierMinShift; double positionTierMaxShift = axis.PositionTierMaxShift; double posValue = axis.IsHorizontal() ? pt.Y : pt.X; bool isLeftOrTop = position == AxisPosition.Top || position == AxisPosition.Left; if ((posValue >= plotAreaValue + positionTierMinShift && posValue < plotAreaValue + positionTierMaxShift && !isLeftOrTop) || (posValue <= plotAreaValue - positionTierMinShift && posValue > plotAreaValue - positionTierMaxShift && isLeftOrTop)) { if (axis.IsHorizontal()) { if (xaxis == null) { xaxis = axis; } } else if (axis.IsVertical()) { if (yaxis == null) { yaxis = axis; } } } } } } }