예제 #1
0
        protected override Point GetToolTipPosition(ShapeMap sender, List <ShapeMap> sibilings)
        {
            DataTooltip.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            var unitW = Methods.GetUnitWidth((Invert ? AxisTags.Y : AxisTags.X), this,
                                             (Invert ? sender.Series.ScalesYAt : sender.Series.ScalesXAt));
            var overflow = unitW - MaxColumnWidth * 3 > 0 ? unitW - MaxColumnWidth * 3 : 0;

            unitW = unitW > MaxColumnWidth * 3 ? MaxColumnWidth * 3 : unitW;
            var targetAxis = Invert ? sender.Series.ScalesYAt : sender.Series.ScalesXAt;
            var x          = sender.ChartPoint.X + 1 > (AxisX[targetAxis].MaxLimit + AxisX[targetAxis].MaxLimit) / 2
                ? ToPlotArea(sender.ChartPoint.X, AxisTags.X) + overflow * .5 - DataTooltip.DesiredSize.Width
                : ToPlotArea(sender.ChartPoint.X, AxisTags.X) + unitW + overflow * .5;
            var y = ToPlotArea(sibilings.Select(s => s.ChartPoint.Y).DefaultIfEmpty(0).Sum()
                               / sibilings.Count, AxisTags.Y);

            y = y + DataTooltip.DesiredSize.Height > ActualHeight
                ? y - (y + DataTooltip.DesiredSize.Height - ActualHeight) - 5
                : y;
            return(new Point(x, y));
        }
예제 #2
0
        private void PlotRow()
        {
            var stackedChart = Chart as IStackedBar;

            if (stackedChart == null)
            {
                return;
            }

            var stackedSeries = Chart.Series.OfType <StackedBarSeries>().ToList();

            var serieIndex = stackedSeries.IndexOf(this);
            var unitW      = Methods.GetUnitWidth(AxisTags.Y, Chart, ScalesYAt);
            var overflow   = unitW - stackedChart.MaxColumnWidth > 0 ? unitW - stackedChart.MaxColumnWidth : 0;

            unitW = unitW > stackedChart.MaxColumnWidth ? stackedChart.MaxColumnWidth : unitW;
            var       pointPadding  = .1 * unitW;
            const int seriesPadding = 2;
            var       h             = unitW - 2 * pointPadding;

            var f = (Chart.Invert ? CurrentXAxis : CurrentYAxis).GetFormatter();

            foreach (var point in Values.Points)
            {
                var visual = GetVisual(point);

                var helper = stackedChart.IndexTotals[(int)point.Y];
                var w      = ToPlotArea(helper.Total, AxisTags.X, ScalesXAt) - ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt);
                var rh     = w * (point.X / helper.Total);
                if (double.IsNaN(rh))
                {
                    return;
                }
                var stackedW = w * (helper.Stacked.ContainsKey(serieIndex) ? (helper.Stacked[serieIndex].Stacked / helper.Total) : 0);

                var height = Math.Max(0, h - seriesPadding);

                visual.PointShape.Height = height;
                visual.HoverShape.Height = height;
                visual.HoverShape.Width  = rh;

                Canvas.SetTop(visual.PointShape, ToPlotArea(point.Y, AxisTags.Y, ScalesYAt) + pointPadding + overflow / 2);
                Canvas.SetTop(visual.HoverShape, ToPlotArea(point.Y, AxisTags.Y, ScalesYAt) + pointPadding + overflow / 2);
                Canvas.SetLeft(visual.HoverShape, ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt) + stackedW);
                Panel.SetZIndex(visual.HoverShape, int.MaxValue);

                if (!Chart.DisableAnimations)
                {
                    var wAnim = new DoubleAnimation
                    {
                        From     = visual.IsNew ? 0 : visual.PointShape.Width,
                        To       = rh,
                        Duration = TimeSpan.FromMilliseconds(500)
                    };
                    var leftAnim = new DoubleAnimation
                    {
                        From     = visual.IsNew ? ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt) : Canvas.GetLeft(visual.PointShape),
                        To       = ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt) + stackedW,
                        Duration = TimeSpan.FromMilliseconds(500)
                    };
                    visual.PointShape.BeginAnimation(WidthProperty, wAnim);
                    visual.PointShape.BeginAnimation(Canvas.LeftProperty, leftAnim);
                }
                else
                {
                    visual.PointShape.Width = rh;
                    Canvas.SetLeft(visual.PointShape, ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt) + stackedW);
                }

                if (DataLabels)
                {
                    var tb = BindATextBlock(0);
                    var te = f(Chart.Invert ? point.X : point.Y);
                    var ft = new FormattedText(
                        te,
                        CultureInfo.CurrentCulture,
                        FlowDirection.LeftToRight,
                        new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, Brushes.Black);
                    Canvas.SetLeft(tb, Canvas.GetLeft(visual.HoverShape) + visual.HoverShape.Width * .5 - ft.Width * .5);
                    Canvas.SetTop(tb, Canvas.GetTop(visual.HoverShape) + visual.HoverShape.Height * .5 - ft.Height * .5);
                    Panel.SetZIndex(tb, int.MaxValue - 1);

                    tb.Text       = te;
                    tb.Visibility = Visibility.Hidden;
                    Chart.Canvas.Children.Add(tb);
                    Chart.Shapes.Add(tb);
                    if (!Chart.DisableAnimations)
                    {
                        var t = new DispatcherTimer {
                            Interval = TimeSpan.FromMilliseconds(animationSpeed)
                        };
                        t.Tick += (sender, args) =>
                        {
                            tb.Visibility = Visibility.Visible;
                            var fadeIn = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(animationSpeed));
                            tb.BeginAnimation(OpacityProperty, fadeIn);
                            t.Stop();
                        };
                        t.Start();
                    }
                    else
                    {
                        tb.Visibility = Visibility.Visible;
                    }
                }

                if (visual.IsNew)
                {
                    Chart.ShapesMapper.Add(new ShapeMap
                    {
                        Series     = this,
                        HoverShape = visual.HoverShape,
                        Shape      = visual.PointShape,
                        ChartPoint = point
                    });
                    Chart.Canvas.Children.Add(visual.PointShape);
                    Chart.Canvas.Children.Add(visual.HoverShape);
                    //Shapes.Add(visual.PointShape);
                    //Shapes.Add(visual.HoverShape);
                    Panel.SetZIndex(visual.HoverShape, int.MaxValue);
                    Panel.SetZIndex(visual.PointShape, int.MaxValue - 2);
                    visual.HoverShape.MouseDown  += Chart.DataMouseDown;
                    visual.HoverShape.MouseEnter += Chart.DataMouseEnter;
                    visual.HoverShape.MouseLeave += Chart.DataMouseLeave;
                }
            }
        }
예제 #3
0
        private bool GetArea(int s, bool isUp, out LineAndAreaShape area, out Point ofPt)
        {
            var isNew = false;

            ofPt = new Point();

            if (_areas.Count <= s)
            {
                var path = new Path();
                BindingOperations.SetBinding(path, Shape.StrokeProperty,
                                             new Binding {
                    Path = new PropertyPath("Stroke"), Source = this
                });
                BindingOperations.SetBinding(path, Shape.FillProperty,
                                             new Binding {
                    Path = new PropertyPath("Fill"), Source = this
                });
                BindingOperations.SetBinding(path, Shape.StrokeThicknessProperty,
                                             new Binding {
                    Path = new PropertyPath("StrokeThickness"), Source = this
                });
                BindingOperations.SetBinding(path, VisibilityProperty,
                                             new Binding {
                    Path = new PropertyPath("Visibility"), Source = this
                });
                BindingOperations.SetBinding(path, Panel.ZIndexProperty,
                                             new Binding {
                    Path = new PropertyPath(Panel.ZIndexProperty), Source = this
                });
                BindingOperations.SetBinding(path, Shape.StrokeDashArrayProperty,
                                             new Binding {
                    Path = new PropertyPath(StrokeDashArrayProperty), Source = this
                });
                var geometry = new PathGeometry();
                area = new LineAndAreaShape(new PathFigure(), path);
                geometry.Figures.Add(area.Figure);
                path.Data = geometry;
                _areas.Add(area);
                Chart.DrawMargin.Children.Add(path);
                isNew = true;
                if (isUp)
                {
                    if (Chart.Invert)
                    {
                        ofPt = new Point(0, Methods.GetUnitWidth(AxisTags.Y, Chart, ScalesYAt) * .5);
                        Canvas.SetTop(path, ofPt.Y);
                    }
                    else
                    {
                        ofPt = new Point(Methods.GetUnitWidth(AxisTags.X, Chart, ScalesXAt) * .5, 0);
                        Canvas.SetLeft(path, ofPt.X);
                    }
                }
            }
            else
            {
                area = _areas[s];
                if (isUp)
                {
                    if (Chart.Invert)
                    {
                        ofPt = new Point(0, Methods.GetUnitWidth(AxisTags.Y, Chart, ScalesYAt) * .5);
                        Canvas.SetTop(area.Path, ofPt.Y);
                    }
                    else
                    {
                        ofPt = new Point(Methods.GetUnitWidth(AxisTags.X, Chart, ScalesXAt) * .5, 0);
                        Canvas.SetLeft(area.Path, ofPt.X);
                    }
                }
            }
            return(isNew);
        }
예제 #4
0
        public override void Plot(bool animate = true)
        {
            _isPrimitive = Values.Count >= 1 && Values[0].GetType().IsPrimitive;

            var rr = PointRadius < 5 ? 5 : PointRadius;
            var f  = (Chart.Invert ? CurrentXAxis : CurrentYAxis).GetFormatter();

            var s  = 0;
            var so = 0;

            var isUp = Chart is IUnitaryPoints;

            foreach (var segment in Values.Points.AsSegments().Where(segment => segment.Count != 0))
            {
                LineAndAreaShape area;
                bool             isNew = false;
                var ofPt = new Point();

                if (_areas.Count <= s)
                {
                    var path = new Path();
                    BindingOperations.SetBinding(path, Shape.StrokeProperty,
                                                 new Binding {
                        Path = new PropertyPath("Stroke"), Source = this
                    });
                    BindingOperations.SetBinding(path, Shape.FillProperty,
                                                 new Binding {
                        Path = new PropertyPath("Fill"), Source = this
                    });
                    BindingOperations.SetBinding(path, Shape.StrokeThicknessProperty,
                                                 new Binding {
                        Path = new PropertyPath("StrokeThickness"), Source = this
                    });
                    BindingOperations.SetBinding(path, VisibilityProperty,
                                                 new Binding {
                        Path = new PropertyPath("Visibility"), Source = this
                    });
                    BindingOperations.SetBinding(path, Panel.ZIndexProperty,
                                                 new Binding {
                        Path = new PropertyPath(Panel.ZIndexProperty), Source = this
                    });
                    BindingOperations.SetBinding(path, Shape.StrokeDashArrayProperty,
                                                 new Binding {
                        Path = new PropertyPath(StrokeDashArrayProperty), Source = this
                    });
                    var geometry = new PathGeometry();
                    area = new LineAndAreaShape(new PathFigure(), path);
                    geometry.Figures.Add(area.Figure);
                    path.Data = geometry;
                    _areas.Add(area);
                    Chart.DrawMargin.Children.Add(path);
                    isNew = true;
                    if (isUp)
                    {
                        if (Chart.Invert)
                        {
                            ofPt = new Point(0, Methods.GetUnitWidth(AxisTags.Y, Chart, ScalesYAt) * .5);
                            Canvas.SetTop(path, ofPt.Y);
                        }
                        else
                        {
                            ofPt = new Point(Methods.GetUnitWidth(AxisTags.X, Chart, ScalesYAt) * .5, 0);
                            Canvas.SetLeft(path, ofPt.X);
                        }
                    }
                }
                else
                {
                    area = _areas[s];
                    if (isUp)
                    {
                        if (Chart.Invert)
                        {
                            ofPt = new Point(0, Methods.GetUnitWidth(AxisTags.Y, Chart, ScalesYAt) * .5);
                            Canvas.SetTop(area.Path, ofPt.Y);
                        }
                        else
                        {
                            ofPt = new Point(Methods.GetUnitWidth(AxisTags.X, Chart, ScalesYAt) * .5, 0);
                            Canvas.SetLeft(area.Path, ofPt.X);
                        }
                    }
                }

                var p0 = ToDrawMargin(segment[0], ScalesXAt, ScalesYAt).AsPoint();
                area.Figure.StartPoint = isNew
                    ? (Chart.Invert
                        ? new Point(ToPlotArea(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt), p0.X)
                        : new Point(p0.X, ToPlotArea(CurrentYAxis.MinLimit, AxisTags.Y, ScalesYAt)))
                    : p0;
                area.Figure.BeginAnimation(PathFigure.StartPointProperty,
                                           new PointAnimation(area.Figure.StartPoint,
                                                              segment.Count > 0 ? p0 : new Point(), AnimSpeed));

                AnimatableSegments previous = null;
                var isVirgin = true;
                var first    = new Point();
                var last     = new Point();

                for (var i = 0; i < segment.Count; i++)
                {
                    var point = segment[i];
                    point.ChartLocation = ToDrawMargin(point, ScalesXAt, ScalesYAt).AsPoint();
                    if (isUp)
                    {
                        point.ChartLocation =
                            new Point(point.ChartLocation.X + ofPt.X, point.ChartLocation.Y + ofPt.Y);
                    }

                    if (isVirgin)
                    {
                        isVirgin = false;
                        first    = point.ChartLocation;
                    }

                    var visual = GetVisual(segment[i]);

                    PlaceVisual(visual, point.ChartLocation, rr);

                    if (DataLabels)
                    {
                        Label(point, f, point.ChartLocation);
                    }

                    if (visual.IsNew)
                    {
                        AddToCanvas(visual, point);
                    }

                    var helper = GetSegmentHelper(point.Key, segment[i].Instance, area.Figure);
                    helper.Data = i == segment.Count - 1
                        ? new BezierData(previous != null ? previous.Data.P3 : area.Figure.StartPoint)
                                  //last line is a dummy line, just to keep algorithm simple.
                        : CalculateBezier(i, segment);
                    helper.Previous = previous != null && previous.IsNew ? previous.Previous : previous;
                    helper.Animate(i + so, Chart, so);
                    previous = helper;
                    last     = point.ChartLocation;
                }

                if (area != null)
                {
                    area.DrawLimits(first, last,
                                    new Point(ToDrawMargin(CurrentXAxis.MinLimit, AxisTags.X, ScalesXAt),
                                              ToDrawMargin(CurrentYAxis.MinLimit, AxisTags.Y, ScalesYAt)),
                                    Chart.Invert);
                }

#if DEBUG
                Trace.WriteLine("Segments count: " + area.Figure.Segments.Count);
#endif

                s++;
                so += segment.Count;
            }
        }