/// <summary> /// Converts a chart values pair to pixels /// </summary> /// <param name="chart">Target chart</param> /// <param name="chartPoint">point in screen</param> /// <param name="axisX">axis x index</param> /// <param name="axisY">axis y index</param> /// <returns></returns> public static Point ConvertToPixels(this Chart chart, Point chartPoint, int axisX = 0, int axisY = 0) { if (chart.Model == null || chart.AxisX.Any(x => x.Model == null)) { return(new Point()); } var uw = new CorePoint( chart.AxisX[axisX].Model.EvaluatesUnitWidth ? ChartFunctionsNew.GetUnitWidth(AxisOrientationNew.X, chart.Model, axisX) / 2 : 0, chart.AxisY[axisY].Model.EvaluatesUnitWidth ? ChartFunctionsNew.GetUnitWidth(AxisOrientationNew.Y, chart.Model, axisY) / 2 : 0); return(new Point( ChartFunctionsNew.ToPlotArea(chartPoint.X, AxisOrientationNew.X, chart.Model, axisX) + uw.X, ChartFunctionsNew.ToPlotArea(chartPoint.Y, AxisOrientationNew.Y, chart.Model, axisY) + uw.Y)); }
/// <summary> /// Ends the segment. /// </summary> /// <param name="atIndex">At index.</param> /// <param name="location">The location.</param> public override void EndSegment(int atIndex, CorePoint location) { var splitter = Splitters[ActiveSplitters - 1]; var animSpeed = Model.Chart.View.AnimationsSpeed; var noAnim = Model.Chart.View.DisableAnimations; var areaLimit = ChartFunctionsNew.ToDrawMargin(double.IsNaN(AreaLimit) ? Model.Chart.AxisX[ScalesXAt].FirstSeparator : AreaLimit, AxisOrientationNew.X, Model.Chart, ScalesXAt); var uw = Model.Chart.AxisY[ScalesYAt].EvaluatesUnitWidth ? ChartFunctionsNew.GetUnitWidth(AxisOrientationNew.Y, Model.Chart, ScalesYAt) / 2 : 0; location.Y += uw; if (splitter.IsNew) { splitter.Right.Point = new Point(0, location.Y); } Figure.Segments.Remove(splitter.Right); if (noAnim) { splitter.Right.Point = new Point(areaLimit, location.Y); } else { splitter.Right.BeginAnimation(LineSegment.PointProperty, new PointAnimation(new Point(areaLimit, location.Y), animSpeed)); } Figure.Segments.Insert(atIndex, splitter.Right); splitter.IsNew = false; }
/// <summary> /// This method runs when the update starts /// </summary> public override void OnSeriesUpdateStart() { ActiveSplitters = 0; if (SplittersCollector == int.MaxValue - 1) { //just in case! Splitters.ForEach(s => s.SplitterCollectorIndex = 0); SplittersCollector = 0; } SplittersCollector++; if (Figure != null && Values != null) { var yIni = ChartFunctionsNew.ToDrawMargin(Values.GetTracker(this).YLimit.Min, AxisOrientationNew.Y, Model.Chart, ScalesYAt); if (Model.Chart.View.DisableAnimations) { Figure.StartPoint = new Point(0, yIni); } else { Figure.BeginAnimation(PathFigure.StartPointProperty, new PointAnimation(new Point(0, yIni), Model.Chart.View.AnimationsSpeed)); } } if (IsPathInitialized) { Model.Chart.View.EnsureElementBelongsToCurrentDrawMargin(Path); Path.Stroke = Stroke; Path.StrokeThickness = StrokeThickness; Path.Fill = Fill; Path.Visibility = Visibility; Path.StrokeDashArray = StrokeDashArray; return; } IsPathInitialized = true; Path = new Path { Stroke = Stroke, StrokeThickness = StrokeThickness, Fill = Fill, Visibility = Visibility, StrokeDashArray = StrokeDashArray }; Panel.SetZIndex(Path, Panel.GetZIndex(this)); var geometry = new PathGeometry(); Figure = new PathFigure(); geometry.Figures.Add(Figure); Path.Data = geometry; Model.Chart.View.AddToDrawMargin(Path); var y = ChartFunctionsNew.ToDrawMargin(ActualValues.GetTracker(this).YLimit.Min, AxisOrientationNew.Y, Model.Chart, ScalesYAt); Figure.StartPoint = new Point(0, y); var i = Model.Chart.View.Series.IndexOf(this); Panel.SetZIndex(Path, Model.Chart.View.Series.Count - i); }
/// <summary> /// Starts the segment. /// </summary> /// <param name="atIndex">At index.</param> /// <param name="location">The location.</param> public override void StartSegment(int atIndex, CorePoint location) { if (Splitters.Count <= ActiveSplitters) { Splitters.Add(new LineSegmentSplitter { IsNew = true }); } var splitter = Splitters[ActiveSplitters]; splitter.SplitterCollectorIndex = SplittersCollector; ActiveSplitters++; var animSpeed = Model.Chart.View.AnimationsSpeed; var noAnim = Model.Chart.View.DisableAnimations; var areaLimit = ChartFunctionsNew.ToDrawMargin(double.IsNaN(AreaLimit) ? Model.Chart.AxisX[ScalesXAt].FirstSeparator : AreaLimit, AxisOrientationNew.X, Model.Chart, ScalesXAt); if (Values != null && atIndex == 0) { if (Model.Chart.View.DisableAnimations || IsNew) { Figure.StartPoint = new Point(areaLimit, location.Y); } else { Figure.BeginAnimation(PathFigure.StartPointProperty, new PointAnimation(new Point(areaLimit, location.Y), animSpeed)); } IsNew = false; } if (atIndex != 0) { Figure.Segments.Remove(splitter.Bottom); if (splitter.IsNew) { splitter.Bottom.Point = new Point(Model.Chart.DrawMargin.Width, location.Y); splitter.Left.Point = new Point(Model.Chart.DrawMargin.Width, location.Y); } if (noAnim) { splitter.Bottom.Point = new Point(Model.Chart.DrawMargin.Width, location.Y); } else { splitter.Bottom.BeginAnimation(LineSegment.PointProperty, new PointAnimation(new Point(Model.Chart.DrawMargin.Width, location.Y), animSpeed)); } Figure.Segments.Insert(atIndex, splitter.Bottom); Figure.Segments.Remove(splitter.Left); if (noAnim) { splitter.Left.Point = location.AsPoint(); } else { splitter.Left.BeginAnimation(LineSegment.PointProperty, new PointAnimation(location.AsPoint(), animSpeed)); } Figure.Segments.Insert(atIndex + 1, splitter.Left); return; } if (splitter.IsNew) { splitter.Bottom.Point = new Point(location.X, Model.Chart.DrawMargin.Height); splitter.Left.Point = new Point(location.X, Model.Chart.DrawMargin.Height); } Figure.Segments.Remove(splitter.Left); if (Model.Chart.View.DisableAnimations) { splitter.Left.Point = location.AsPoint(); } else { splitter.Left.BeginAnimation(LineSegment.PointProperty, new PointAnimation(location.AsPoint(), animSpeed)); } Figure.Segments.Insert(atIndex, splitter.Left); }
private void PlaceLabel(string text, AxisCoreNew axis, AxisOrientationNew source) { _label.Text = text; var formattedText = new FormattedText( _label.Text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(_label.FontFamily, _label.FontStyle, _label.FontWeight, _label.FontStretch), _label.FontSize, Brushes.Black); var transform = new LabelEvaluation(axis.View.LabelsRotation, formattedText.Width + 10, formattedText.Height, axis, source); _label.RenderTransform = Math.Abs(transform.LabelAngle) > 1 ? new RotateTransform(transform.LabelAngle) : null; var toLine = ChartFunctionsNew.ToPlotArea(Value + SectionOffset + SectionWidth * .5, source, Model.Chart, axis); var direction = source == AxisOrientationNew.X ? 1 : -1; toLine += axis.EvaluatesUnitWidth ? direction * ChartFunctionsNew.GetUnitWidth(source, Model.Chart, axis) / 2 : 0; var toLabel = toLine + transform.GetOffsetBySource(source); var chart = Model.Chart; if (axis.IsMerged) { const double padding = 4; if (source == AxisOrientationNew.Y) { if (toLabel + transform.ActualHeight > chart.DrawMargin.Top + chart.DrawMargin.Height) { toLabel -= transform.ActualHeight + padding; } } else { if (toLabel + transform.ActualWidth > chart.DrawMargin.Left + chart.DrawMargin.Width) { toLabel -= transform.ActualWidth + padding; } } } var labelTab = axis.Tab; labelTab += transform.GetOffsetBySource(source.Invert()); if (source == AxisOrientationNew.Y) { labelTab += 8 * (axis.Position == AxisPositionNew.LeftBottom ? 1 : -1); if (Model.View.DisableAnimations || DisableAnimations) { Canvas.SetLeft(_label, labelTab); Canvas.SetTop(_label, toLabel); return; } _label.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(toLabel, chart.View.AnimationsSpeed)); _label.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(labelTab, chart.View.AnimationsSpeed)); } else { if (Model.View.DisableAnimations || DisableAnimations) { Canvas.SetLeft(_label, toLabel); Canvas.SetTop(_label, labelTab); return; } _label.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(toLabel, chart.View.AnimationsSpeed)); _label.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(labelTab, chart.View.AnimationsSpeed)); } }
/// <summary> /// Draws the or move. /// </summary> /// <param name="source">The source.</param> /// <param name="axis">The axis.</param> public void DrawOrMove(AxisOrientationNew source, int axis) { _rectangle.Fill = Fill; _rectangle.Stroke = Stroke; _rectangle.StrokeDashArray = StrokeDashArray; _rectangle.StrokeThickness = StrokeThickness; Panel.SetZIndex(_rectangle, Panel.GetZIndex(this)); BindingOperations.SetBinding(_rectangle, VisibilityProperty, new Binding { Path = new PropertyPath(VisibilityProperty), Source = this }); var ax = source == AxisOrientationNew.X ? Model.Chart.AxisX[axis] : Model.Chart.AxisY[axis]; var uw = ax.EvaluatesUnitWidth ? ChartFunctionsNew.GetUnitWidth(source, Model.Chart, axis) / 2 : 0; if (Parent == null) { _label = ((AxisNew)ax.View).BindATextBlock(); _label.Padding = new Thickness(5, 2, 5, 2); Model.Chart.View.AddToView(this); Model.Chart.View.AddToDrawMargin(_rectangle); Model.Chart.View.AddToView(_label); _rectangle.Height = 0; _rectangle.Width = 0; Canvas.SetLeft(_rectangle, 0d); Canvas.SetTop(_rectangle, Model.Chart.DrawMargin.Height); #region Obsolete Canvas.SetTop(_label, Model.Chart.DrawMargin.Height); Canvas.SetLeft(_label, 0d); #endregion } #pragma warning disable 618 var from = ChartFunctionsNew.ToDrawMargin(double.IsNaN(FromValue) ? Value + SectionOffset : FromValue, source, Model.Chart, axis) + uw; #pragma warning restore 618 #pragma warning disable 618 var to = ChartFunctionsNew.ToDrawMargin(double.IsNaN(ToValue) ? Value + SectionOffset + SectionWidth : ToValue, source, Model.Chart, axis) + uw; #pragma warning restore 618 if (from > to) { var temp = to; to = from; from = temp; } var anSpeed = Model.Chart.View.AnimationsSpeed; if (DataLabel) { if (DataLabelForeground != null) { _label.Foreground = DataLabelForeground; } _label.UpdateLayout(); _label.Background = Stroke ?? Fill; PlaceLabel(ax.GetFormatter()(Value), ax, source); } if (source == AxisOrientationNew.X) { var w = to - from; w = StrokeThickness > w ? StrokeThickness : w; Canvas.SetTop(_rectangle, 0); _rectangle.Height = Model.Chart.DrawMargin.Height; if (Model.Chart.View.DisableAnimations || DisableAnimations) { _rectangle.Width = w > 0 ? w : 0; Canvas.SetLeft(_rectangle, from - StrokeThickness / 2); } else { _rectangle.BeginAnimation(WidthProperty, new DoubleAnimation(w > 0 ? w : 0, anSpeed)); _rectangle.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(from - StrokeThickness / 2, anSpeed)); } return; } var h = to - from; h = StrokeThickness > h ? StrokeThickness : h; Canvas.SetLeft(_rectangle, 0d); _rectangle.Width = Model.Chart.DrawMargin.Width; if (Model.Chart.View.DisableAnimations || DisableAnimations) { Canvas.SetTop(_rectangle, from - StrokeThickness / 2); _rectangle.Height = h > 0 ? h : 0; } else { _rectangle.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(from, anSpeed)); _rectangle.BeginAnimation(HeightProperty, new DoubleAnimation(h, anSpeed)); } }
/// <summary> /// Adds the or move. /// </summary> /// <param name="chart">The chart.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// </exception> public void AddOrMove(ChartCore chart) { if (chart == null || UIElement == null) { return; } if (!chart.AreComponentsLoaded) { return; } if (UIElement.Parent == null) { chart.View.AddToDrawMargin(UIElement); Panel.SetZIndex(UIElement, 1000); } var coordinate = new CorePoint(ChartFunctionsNew.ToDrawMargin(X, AxisOrientationNew.X, chart, AxisX), ChartFunctionsNew.ToDrawMargin(Y, AxisOrientationNew.Y, chart.View.Model, AxisY)); var wpfChart = (CartesianChart)chart.View; var uw = new CorePoint( wpfChart.AxisX[AxisX].Model.EvaluatesUnitWidth ? ChartFunctionsNew.GetUnitWidth(AxisOrientationNew.X, chart, AxisX) / 2 : 0, wpfChart.AxisY[AxisY].Model.EvaluatesUnitWidth ? ChartFunctionsNew.GetUnitWidth(AxisOrientationNew.Y, chart, AxisY) / 2 : 0); coordinate += uw; UIElement.UpdateLayout(); switch (VerticalAlignment) { case VerticalAlignment.Top: coordinate = new CorePoint(coordinate.X, coordinate.Y - UIElement.ActualHeight); break; case VerticalAlignment.Center: coordinate = new CorePoint(coordinate.X, coordinate.Y - UIElement.ActualHeight / 2); break; case VerticalAlignment.Bottom: coordinate = new CorePoint(coordinate.X, coordinate.Y); break; case VerticalAlignment.Stretch: break; default: throw new ArgumentOutOfRangeException(); } switch (HorizontalAlignment) { case HorizontalAlignment.Left: coordinate = new CorePoint(coordinate.X - UIElement.ActualWidth, coordinate.Y); break; case HorizontalAlignment.Center: coordinate = new CorePoint(coordinate.X - UIElement.ActualWidth / 2, coordinate.Y); break; case HorizontalAlignment.Right: coordinate = new CorePoint(coordinate.X, coordinate.Y); break; case HorizontalAlignment.Stretch: break; default: throw new ArgumentOutOfRangeException(); } if (chart.View.DisableAnimations) { Canvas.SetLeft(UIElement, coordinate.X); Canvas.SetTop(UIElement, coordinate.Y); } else { if (double.IsNaN(Canvas.GetLeft(UIElement))) { Canvas.SetLeft(UIElement, coordinate.X); Canvas.SetTop(UIElement, coordinate.Y); } UIElement.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(coordinate.X, wpfChart.AnimationsSpeed)); UIElement.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(coordinate.Y, wpfChart.AnimationsSpeed)); } _owner = chart; }