/// <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);
        }
Beispiel #6
0
        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;
     }
 }
Beispiel #9
0
        /// <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);
        }
Beispiel #10
0
        /// <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();
			}
		}
Beispiel #21
0
        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;
			}
		}