/// <summary> /// Annotates the specified isoline collection. /// </summary> /// <param name="collection">The collection.</param> /// <param name="visible">The visible rectangle.</param> /// <returns></returns> public Collection<IsolineTextLabel> Annotate(IsolineCollection collection, Rect visible) { Collection<IsolineTextLabel> res = new Collection<IsolineTextLabel>(); foreach (var line in collection.Lines) { double way = 0; foreach (var segment in line.GetSegments()) { double length = segment.GetLength(); way += length; if (way > wayBeforeText) { way = 0; res.Add(new IsolineTextLabel { Text = line.RealValue.ToString("G2"), Position = segment.Max, Rotation = (segment.Max - segment.Min).ToAngle() }); } } } return res; }
protected IEnumerable<double> GetAdditionalLevels(IsolineCollection collection) { var dataSource = DataSource; var visibleMinMax = dataSource.GetMinMax(Plotter2D.Visible); double totalDelta = collection.Max - collection.Min; double visibleMinMaxRatio = totalDelta / visibleMinMax.GetLength(); double defaultDelta = totalDelta / 12; if (true || 2 * defaultDelta < visibleMinMaxRatio) { double number = Math.Ceiling(visibleMinMaxRatio * 4); number = Math.Pow(2, Math.Ceiling(Math.Log(number) / Math.Log(2))); double delta = totalDelta / number; double x = collection.Min + Math.Ceiling((visibleMinMax.Min - collection.Min) / delta) * delta; List<double> result = new List<double>(); while (x < visibleMinMax.Max) { result.Add(x); x += delta; } return result; } return Enumerable.Empty<double>(); }
protected IEnumerable <double> GetAdditionalLevels(IsolineCollection collection) { var dataSource = DataSource; var visibleMinMax = dataSource.GetMinMax(Plotter2D.Visible); double totalDelta = collection.Max - collection.Min; double visibleMinMaxRatio = totalDelta / visibleMinMax.GetLength(); double defaultDelta = totalDelta / 12; if (true || 2 * defaultDelta < visibleMinMaxRatio) { double number = Math.Ceiling(visibleMinMaxRatio * 4); number = Math.Pow(2, Math.Ceiling(Math.Log(number) / Math.Log(2))); double delta = totalDelta / number; double x = collection.Min + Math.Ceiling((visibleMinMax.Min - collection.Min) / delta) * delta; List <double> result = new List <double>(); while (x < visibleMinMax.Max) { result.Add(x); x += delta; } return(result); } return(Enumerable.Empty <double>()); }
/// <summary> /// Builds isoline data for 2d scalar field contained in data source. /// </summary> /// <returns>Collection of data describing built isolines.</returns> public IsolineCollection BuildIsoline() { VerifyDataSource(); segments = new IsolineCollection(); minMax = (Double.IsNaN(missingValue) ? dataSource.GetMinMax() : dataSource.GetMinMax(missingValue)); segments.Min = minMax.Min; segments.Max = minMax.Max; if (!minMax.IsEmpty) { values = dataSource.Data; double[] levels = GetLevelsForIsolines(); foreach (double level in levels) { PrepareCells(level); } if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0) { segments.Lines.RemoveAt(segments.Lines.Count - 1); } } return(segments); }
/// <summary> /// Builds isoline data for 2d scalar field contained in data source. /// </summary> /// <returns>Collection of data describing built isolines.</returns> public IsolineCollection BuildIsoline() { VerifyDataSource(); segments = new IsolineCollection(); // Cannot draw isolines for fields with one dimension lesser than 2 if (dataSource.Width < 2 || dataSource.Height < 2) { return(segments); } Init(); if (!minMax.IsEmpty) { values = dataSource.Data; double[] levels = GetLevelsForIsolines(); foreach (double level in levels) { PrepareCells(level); } if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0) { segments.Lines.RemoveAt(segments.Lines.Count - 1); } } return(segments); }
private IEnumerable <double> GetAdditionalIsolines(IsolineCollection collection) { var dataSource = DataSource; var visibleMinMax = dataSource.GetMinMax(Plotter2D.Visible); var visibleMinMaxRatio = (collection.Max - collection.Min) / visibleMinMax.GetLength(); var log = Math.Log10(visibleMinMaxRatio); if (log > 0.9) { var upperLog = Math.Ceiling(log); var divisionsNum = Math.Pow(10, upperLog); var delta = (collection.Max - collection.Min) / divisionsNum; var start = Math.Ceiling(visibleMinMax.Min / delta) * delta; var x = start; while (x < visibleMinMax.Max) { yield return(x); x += delta; } } }
/// <summary> /// Annotates the specified isoline collection. /// </summary> /// <param name="collection">The collection.</param> /// <param name="visible">The visible rectangle.</param> /// <returns></returns> public Collection <IsolineTextLabel> Annotate(IsolineCollection collection, Rect visible) { Collection <IsolineTextLabel> res = new Collection <IsolineTextLabel>(); foreach (var line in collection.Lines) { double way = 0; foreach (var segment in line.GetSegments()) { double length = segment.GetLength(); way += length; if (way > wayBeforeText) { way = 0; res.Add(new IsolineTextLabel { Text = line.RealValue.ToString("G2"), Position = segment.Max, Rotation = (segment.Max - segment.Min).ToAngle() }); } } } return(res); }
/// <summary> /// This method is called when data source changes. /// </summary> protected virtual void UpdateDataSource() { if (dataSource != null) { IsolineBuilder.DataSource = dataSource; collection = IsolineBuilder.Build(); } else { collection = null; } }
/// <summary> /// Builds isoline data for the specified level in 2d scalar field. /// </summary> /// <param name="level">The level.</param> /// <returns></returns> public IsolineCollection Build(double level) { VerifyDataSource(); minMax = dataSource.GetMinMax(); values = dataSource.Data; segments = new IsolineCollection(); PrepareCells(level); return(segments); }
/// <summary> /// Builds isoline data by 2d scalar field containing in data source. /// </summary> /// <returns>Collection of data describing built isolines</returns> public IsolineCollection Build() { VerifyDataSource(); minMax = dataSource.GetMinMax(); values = dataSource.Data; double[] levels = GetLevelsForIsolines(); segments = new IsolineCollection(); foreach (double level in levels) { PrepareCells(level); } return(segments); }
/// <summary> /// Annotates the specified isoline collection. /// </summary> /// <param name="collection">The collection.</param> /// <param name="visible">The visible rectangle.</param> /// <returns></returns> public Collection<IsolineTextLabel> Annotate(IsolineCollection collection, DataRect visible) { Collection<IsolineTextLabel> res = new Collection<IsolineTextLabel>(); foreach (var line in collection.Lines) { double way = 0; var forwardSegments = line.GetSegments(); var forwardEnumerator = forwardSegments.GetEnumerator(); forwardEnumerator.MoveNext(); foreach (var segment in line.GetSegments()) { bool hasForwardSegment = forwardEnumerator.MoveNext(); double length = segment.GetLength(); way += length; if (way > wayBeforeText) { way = 0; var rotation = (segment.Max - segment.Min).ToAngle(); if (hasForwardSegment) { var forwardSegment = forwardEnumerator.Current; rotation = (rotation + (forwardSegment.Max - forwardSegment.Min).ToAngle()) / 2; } res.Add(new IsolineTextLabel { Value = line.RealValue, Position = segment.Max, Rotation = rotation }); } } } return res; }
/// <summary> /// Annotates the specified isoline collection. /// </summary> /// <param name="collection">The collection.</param> /// <param name="visible">The visible rectangle.</param> /// <returns></returns> public Collection <IsolineTextLabel> Annotate(IsolineCollection collection, DataRect visible) { Collection <IsolineTextLabel> res = new Collection <IsolineTextLabel>(); foreach (var line in collection.Lines) { double way = 0; var forwardSegments = line.GetSegments(); var forwardEnumerator = forwardSegments.GetEnumerator(); forwardEnumerator.MoveNext(); foreach (var segment in line.GetSegments()) { bool hasForwardSegment = forwardEnumerator.MoveNext(); double length = segment.GetLength(); way += length; if (way > wayBeforeText) { way = 0; var rotation = (segment.Max - segment.Min).ToAngle(); if (hasForwardSegment) { var forwardSegment = forwardEnumerator.Current; rotation = (rotation + (forwardSegment.Max - forwardSegment.Min).ToAngle()) / 2; } res.Add(new IsolineTextLabel { Value = line.RealValue, Position = segment.Max, Rotation = rotation }); } } } return(res); }
/// <summary> /// Builds isoline data for the specified level in 2d scalar field. /// </summary> /// <param name="level">The level.</param> /// <returns></returns> public IsolineCollection BuildIsoline(double level) { VerifyDataSource(); segments = new IsolineCollection(); Init(); if (!minMax.IsEmpty) { values = dataSource.Data; PrepareCells(level); if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0) { segments.Lines.RemoveAt(segments.Lines.Count - 1); } } return(segments); }
private IEnumerable<double> GetAdditionalIsolines(IsolineCollection collection) { var dataSource = DataSource; var visibleMinMax = dataSource.GetMinMax(Plotter2D.Visible); var visibleMinMaxRatio = (collection.Max - collection.Min) / visibleMinMax.GetLength(); var log = Math.Log10(visibleMinMaxRatio); if (log > 0.9) { var upperLog = Math.Ceiling(log); var divisionsNum = Math.Pow(10, upperLog); var delta = (collection.Max - collection.Min) / divisionsNum; var start = Math.Ceiling(visibleMinMax.Min / delta) * delta; var x = start; while (x < visibleMinMax.Max) { yield return x; x += delta; } } }
protected void RenderIsolineCollection(DrawingContext dc, double strokeThickness, IsolineCollection collection, CoordinateTransform transform) { foreach (LevelLine line in collection) { StreamGeometry lineGeometry = new StreamGeometry(); using (var context = lineGeometry.Open()) { context.BeginFigure(line.StartPoint.ViewportToScreen(transform), false, false); if (!UseBezierCurves) { context.PolyLineTo(line.OtherPoints.ViewportToScreen(transform).ToArray(), true, true); } else { context.PolyBezierTo(BezierBuilder.GetBezierPoints(line.AllPoints.ViewportToScreen(transform).ToArray()).Skip(1).ToArray(), true, true); } } lineGeometry.Freeze(); Pen pen = new Pen(new SolidColorBrush(Palette.GetColor(line.Value01)), strokeThickness); dc.DrawGeometry(null, pen, lineGeometry); } }
/// <summary> /// Builds isoline data for 2d scalar field contained in data source. /// </summary> /// <returns>Collection of data describing built isolines.</returns> public IsolineCollection BuildIsoline() { VerifyDataSource(); segments = new IsolineCollection(); minMax = (Double.IsNaN(missingValue) ? dataSource.GetMinMax() : dataSource.GetMinMax(missingValue)); segments.Min = minMax.Min; segments.Max = minMax.Max; if (!minMax.IsEmpty) { values = dataSource.Data; double[] levels = GetLevelsForIsolines(); foreach (double level in levels) { PrepareCells(level); } if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0) segments.Lines.RemoveAt(segments.Lines.Count - 1); } return segments; }
/// <summary> /// Builds isoline data by 2d scalar field containing in data source. /// </summary> /// <returns>Collection of data describing built isolines</returns> public IsolineCollection Build() { VerifyDataSource(); minMax = dataSource.GetMinMax(); values = dataSource.Data; double[] levels = GetLevelsForIsolines(); segments = new IsolineCollection(); foreach (double level in levels) { PrepareCells(level); } return segments; }
protected void RenderIsolineCollection(DrawingContext dc, double strokeThickness, IsolineCollection collection, CoordinateTransform transform) { foreach (LevelLine line in collection) { StreamGeometry lineGeometry = new StreamGeometry(); using (var context = lineGeometry.Open()) { context.BeginFigure(line.StartPoint.ViewportToScreen(transform), false, false); if (!UseBezierCurves) { context.PolyLineTo(line.OtherPoints.ViewportToScreen(transform).ToArray(), true, true); } else { context.PolyBezierTo(BezierBuilder.GetBezierPoints(line.AllPoints.ViewportToScreen(transform).ToArray()).Skip(1).ToArray(), true, true); } } lineGeometry.Freeze(); Pen pen = new Pen(new SolidColorBrush(Palette.GetColor(line.Value01)), strokeThickness); dc.DrawGeometry(null, pen, lineGeometry); } }
/// <summary> /// Builds isoline data for the specified level in 2d scalar field. /// </summary> /// <param name="level">The level.</param> /// <returns></returns> public IsolineCollection Build(double level) { VerifyDataSource(); minMax = dataSource.GetMinMax(); values = dataSource.Data; segments = new IsolineCollection(); PrepareCells(level); return segments; }
private void RenderLabels(DrawingContext dc, IsolineCollection collection) { if (Plotter2D == null) return; if (collection == null) return; if (!DrawLabels) return; var viewportBounds = ViewportPanel.GetViewportBounds(this); if (viewportBounds.IsEmpty) return; var strokeThickness = StrokeThickness; var visible = Plotter2D.Visible; var output = Plotter2D.Viewport.Output; var transform = Plotter2D.Transform.WithRects(viewportBounds, new Rect(RenderSize)); var labelStringFormat = LabelStringFormat; // drawing constants var labelRectangleFill = Brushes.White; var biggerViewport = viewportBounds.ZoomOutFromCenter(1.1); // getting and filtering annotations to draw only visible ones Annotater.WayBeforeText = Math.Sqrt(visible.Width * visible.Width + visible.Height * visible.Height) / 8 * WayBeforeTextMultiplier; var annotations = Annotater.Annotate(collection, visible) .Where(annotation => { Point viewportPosition = annotation.Position.DataToViewport(transform); return biggerViewport.Contains(viewportPosition); }); var labelsScale = LabelsScaling; // drawing annotations foreach (var annotation in annotations) { FormattedText text = CreateFormattedText(annotation.Value.ToString(LabelStringFormat)); Point position = annotation.Position.DataToScreen(transform); var labelTransform = CreateTransform(annotation, text, position); // creating rectange stroke double colorRatio = (annotation.Value - collection.Min) / (collection.Max - collection.Min); colorRatio = MathHelper.Clamp(colorRatio); Color rectangleStrokeColor = Palette.GetColor(colorRatio); SolidColorBrush rectangleStroke = new SolidColorBrush(rectangleStrokeColor); Pen labelRectangleStrokePen = new Pen(rectangleStroke, 2); dc.PushTransform(new ScaleTransform(1, labelsScale)); dc.PushTransform(labelTransform); { var bounds = RectExtensions.FromCenterSize(position, new Size(text.Width, text.Height)); bounds = bounds.ZoomOutFromCenter(1.3); dc.DrawRoundedRectangle(labelRectangleFill, labelRectangleStrokePen, bounds, 8, 8); DrawTextInPosition(dc, text, position); } dc.Pop(); dc.Pop(); } }
private void RenderLabels(DrawingContext dc, IsolineCollection collection) { if (Plotter2D == null) { return; } if (collection == null) { return; } if (!DrawLabels) { return; } var viewportBounds = ViewportPanel.GetViewportBounds(this); if (viewportBounds.IsEmpty) { return; } var strokeThickness = StrokeThickness; var visible = Plotter2D.Visible; var output = Plotter2D.Viewport.Output; var transform = Plotter2D.Transform.WithRects(viewportBounds, new Rect(RenderSize)); var labelStringFormat = LabelStringFormat; // drawing constants var labelRectangleFill = Brushes.White; var biggerViewport = viewportBounds.ZoomOutFromCenter(1.1); // getting and filtering annotations to draw only visible ones Annotater.WayBeforeText = Math.Sqrt(visible.Width * visible.Width + visible.Height * visible.Height) / 8 * WayBeforeTextMultiplier; var annotations = Annotater.Annotate(collection, visible) .Where(annotation => { Point viewportPosition = annotation.Position.DataToViewport(transform); return(biggerViewport.Contains(viewportPosition)); }); var labelsScale = LabelsScaling; // drawing annotations foreach (var annotation in annotations) { FormattedText text = CreateFormattedText(annotation.Value.ToString(LabelStringFormat)); Point position = annotation.Position.DataToScreen(transform); var labelTransform = CreateTransform(annotation, text, position); // creating rectange stroke double colorRatio = (annotation.Value - collection.Min) / (collection.Max - collection.Min); colorRatio = MathHelper.Clamp(colorRatio); Color rectangleStrokeColor = Palette.GetColor(colorRatio); SolidColorBrush rectangleStroke = new SolidColorBrush(rectangleStrokeColor); Pen labelRectangleStrokePen = new Pen(rectangleStroke, 2); dc.PushTransform(new ScaleTransform(1, labelsScale)); dc.PushTransform(labelTransform); { var bounds = RectExtensions.FromCenterSize(position, new Size(text.Width, text.Height)); bounds = bounds.ZoomOutFromCenter(1.3); dc.DrawRoundedRectangle(labelRectangleFill, labelRectangleStrokePen, bounds, 8, 8); DrawTextInPosition(dc, text, position); } dc.Pop(); dc.Pop(); } }
/// <summary> /// Builds isoline data for 2d scalar field contained in data source. /// </summary> /// <returns>Collection of data describing built isolines.</returns> public IsolineCollection BuildIsoline() { VerifyDataSource(); segments = new IsolineCollection(); // Cannot draw isolines for fields with one dimension lesser than 2 if (dataSource.Width < 2 || dataSource.Height < 2) return segments; Init(); if (!minMax.IsEmpty) { values = dataSource.Data; double[] levels = GetLevelsForIsolines(); foreach (double level in levels) { PrepareCells(level); } if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0) segments.Lines.RemoveAt(segments.Lines.Count - 1); } return segments; }
/// <summary> /// Builds isoline data for the specified level in 2d scalar field. /// </summary> /// <param name="level">The level.</param> /// <returns></returns> public IsolineCollection BuildIsoline(double level) { VerifyDataSource(); segments = new IsolineCollection(); Init(); if (!minMax.IsEmpty) { values = dataSource.Data; PrepareCells(level); if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0) segments.Lines.RemoveAt(segments.Lines.Count - 1); } return segments; }
/// <summary> /// This method is called when data source changes. /// </summary> protected virtual void UpdateDataSource() { if (dataSource != null) { IsolineBuilder.DataSource = dataSource; collection = IsolineBuilder.Build(); } else { collection = null; } }