protected void RenderLogLabel(DrawingContext dc, double position, string text) { double val = Math.Log10(double.Parse(text)); var ft = new FormattedText(val.ToString(CultureInfo.CurrentCulture), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize * 0.75, Foreground); var fpow = new FormattedText(@"10", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, Foreground); var wd = ft.Width + fpow.Width - 1; var hg = ft.Height + fpow.Height - 7; Rect rect; var p = new Pen(Brushes.Black, 1); var halfPenSize = p.Thickness / 2; var pos = Math.Round(position, MidpointRounding.AwayFromZero); dc.PushGuidelineSet(new GuidelineSet(new double[0], new[] { pos - halfPenSize })); switch (AxisAlignment) { case HorizontalAlignment.Left: rect = GetRectangleByAlignment(new Point(_tickSize + 2, pos), new Size(wd, hg), TextAlignment); dc.DrawLine(p, new Point(0, pos), new Point(_tickSize, pos)); break; case HorizontalAlignment.Right: rect = GetRectangleByAlignment(new Point(ActualWidth - (_tickSize + 2), pos), new Size(wd, hg), TextAlignment); dc.DrawLine(p, new Point(ActualWidth - _tickSize, pos), new Point(ActualWidth, pos)); break; case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: rect = GetRectangleByAlignment(new Point(ActualWidth / 2, pos), new Size(wd, hg), TextAlignment); dc.DrawLine(p, new Point(ActualWidth / 2 - _tickSize, pos), new Point(ActualWidth / 2 + _tickSize, pos)); break; default: throw new ArgumentOutOfRangeException(); } dc.Pop(); if (!OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect))) { Point ftL = rect.TopRight; ftL.X -= ft.Width; Point fpowL = rect.BottomLeft; fpowL.Y -= fpow.Height; dc.DrawText(ft, ftL); dc.DrawText(fpow, fpowL); OccupiedLabelPlaces.Add(rect); } }
protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); if (Axis != null && Visibility == Visibility.Visible) { if (TrimSideLabels) { OccupiedLabelPlaces.Add(new Rect(0, 0, 1, ActualHeight)); OccupiedLabelPlaces.Add(new Rect(ActualWidth, 0, 1, ActualHeight)); } else { OccupiedLabelPlaces.Clear(); } var marks = MarkProvider.GetMarks(Axis).Select(m => new Tuple <double, FormattedText>(m.Item1, new FormattedText(m.Item2, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, Foreground))).ToList(); if (marks.Count > 0) { var maxWidth = marks.Max(m => m.Item2.Width) + LabelMargin; foreach (var m in marks) { RenderLabel(drawingContext, m.Item1, m.Item2, maxWidth); } } RenderAxis(drawingContext); } }
protected override void RenderLabel(DrawingContext dc, double position, FormattedText ft, double max) { var p = new Pen(Brushes.Black, 1); Rect rect; var halfPenSize = p.Thickness / 2; var pos = Math.Round(position, MidpointRounding.AwayFromZero); dc.PushGuidelineSet(new GuidelineSet(new double[0], new[] { pos - halfPenSize })); bool drawLabel; switch (AxisAlignment) { case HorizontalAlignment.Left: rect = GetRectangleByAlignment(new Point(_tickSize + 2, pos), new Size(ft.Width, max), TextAlignment); drawLabel = !OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect)); if (drawLabel) { dc.DrawLine(p, new Point(0, pos), new Point(_tickSize, pos)); } else { dc.DrawLine(p, new Point(0, pos), new Point(_tickSize / 2.0, pos)); } break; case HorizontalAlignment.Right: rect = GetRectangleByAlignment(new Point(ActualWidth - (_tickSize + 2), pos), new Size(ft.Width, max), TextAlignment); drawLabel = !OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect)); if (drawLabel) { dc.DrawLine(p, new Point(ActualWidth - _tickSize, pos), new Point(ActualWidth, pos)); } else { dc.DrawLine(p, new Point(ActualWidth - _tickSize / 2.0, pos), new Point(ActualWidth, pos)); } break; case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: rect = GetRectangleByAlignment(new Point(ActualWidth / 2, position), new Size(ft.Width, max), TextAlignment); drawLabel = !OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect)); if (drawLabel) { dc.DrawLine(p, new Point(ActualWidth / 2 - _tickSize, pos), new Point(ActualWidth / 2 + _tickSize, pos)); } else { dc.DrawLine(p, new Point(ActualWidth / 2 - _tickSize / 2.0, pos), new Point(ActualWidth / 2 + _tickSize / 2.0, pos)); } break; default: throw new ArgumentOutOfRangeException(); } dc.Pop(); if (drawLabel) { var hReal = ft.Height; var hSpace = rect.Height; double y; if (TextAlignment == ContentAlignment.BottomLeft || TextAlignment == ContentAlignment.BottomCenter || TextAlignment == ContentAlignment.BottomRight) { y = rect.Y + (hReal - hSpace); } else if (TextAlignment == ContentAlignment.MiddleLeft || TextAlignment == ContentAlignment.MiddleCenter || TextAlignment == ContentAlignment.MiddleRight) { y = rect.Y + (hSpace - hReal) / 2.0; } else { y = rect.Y; } dc.DrawText(ft, new Point(rect.Location.X, y)); OccupiedLabelPlaces.Add(rect); } }
protected override void RenderLabel(DrawingContext dc, double position, FormattedText ft, double max) { var p = new Pen(Brushes.Black, 1); Rect rect; var halfPenSize = p.Thickness / 2; var pos = Math.Round(position, MidpointRounding.AwayFromZero); dc.PushGuidelineSet(new GuidelineSet(new[] { pos - halfPenSize }, new double[0])); bool drawLabel; switch (AxisAlignment) { case VerticalAlignment.Top: rect = GetRectangleByAlignment(new Point(pos, _tickSize), new Size(max, ft.Height), TextAlignment); drawLabel = !OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect)); if (drawLabel) { dc.DrawLine(p, new Point(pos, 0), new Point(pos, _tickSize)); } else { dc.DrawLine(p, new Point(pos, 0), new Point(pos, _tickSize / 2.0)); } break; case VerticalAlignment.Bottom: rect = GetRectangleByAlignment(new Point(pos, ActualHeight - _tickSize), new Size(max, ft.Height), TextAlignment); drawLabel = !OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect)); if (drawLabel) { dc.DrawLine(p, new Point(pos, ActualHeight - _tickSize), new Point(pos, ActualHeight)); } else { dc.DrawLine(p, new Point(pos, ActualHeight - _tickSize / 2.0), new Point(pos, ActualHeight)); } break; case VerticalAlignment.Center: case VerticalAlignment.Stretch: rect = GetRectangleByAlignment(new Point(pos, ActualHeight / 2), new Size(max, ft.Height), TextAlignment); drawLabel = !OccupiedLabelPlaces.Exists(r => r.IntersectsWith(rect)); if (drawLabel) { dc.DrawLine(p, new Point(pos, ActualHeight / 2 - _tickSize), new Point(pos, ActualHeight / 2 + _tickSize)); } else { dc.DrawLine(p, new Point(pos, ActualHeight / 2 - _tickSize / 2.0), new Point(pos, ActualHeight / 2 + _tickSize / 2.0)); } break; default: throw new ArgumentOutOfRangeException(); } dc.Pop(); if (drawLabel) { var wReal = ft.Width; var wSpace = rect.Width; double x; if (TextAlignment == ContentAlignment.BottomLeft || TextAlignment == ContentAlignment.MiddleLeft || TextAlignment == ContentAlignment.TopLeft) { x = rect.X; } else if (TextAlignment == ContentAlignment.BottomCenter || TextAlignment == ContentAlignment.MiddleCenter || TextAlignment == ContentAlignment.TopCenter) { x = rect.X + (wSpace - wReal) / 2.0; } else { x = rect.X + (wSpace - wReal); } dc.DrawText(ft, new Point(x, rect.Location.Y)); OccupiedLabelPlaces.Add(rect); } }