Пример #1
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            if (FilteredData.Count < 1)
            {
                base.OnRender(drawingContext);
                return;
            }
            visualContext = new LineGraphVisualContext();

            _bars.Children.Clear();
            _barLabels.Children.Clear();
            _lineVisual.Children.Clear();
            _xAxisGrid.Children.Clear();
            //_highlightGrid.Children.Clear();

            var max = FilteredData.MaxValue();

            var context           = new ProviderContext(FilteredData.Count);
            var barAvailableWidth = (_bars.RenderSize.Width) / FilteredData.Count;

            MaterialProvider.Reset(context);

            MaterialProvider.Reset(context);
            var total = FilteredData.SumValue();
            var availableLineGraphSize = new Size(_bars.ActualWidth - (DotRadius * 2),
                                                  _bars.ActualHeight - (DotRadius * 2));
            var startX = (barAvailableWidth / 2) - DotRadius;

            var verticalpttrace = 0d;
            var pttrace         = 0;

            var pathSegments = new PathSegmentCollection();
            var pathFigure   = new PathFigure
            {
                Segments = pathSegments
            };

            MaterialProvider.Reset(context);

            var isFirstPoint = true;

            foreach (var d in FilteredData)
            {
                var material           = MaterialProvider.ProvideNext(context);
                var nextPoint          = new Point(startX + (barAvailableWidth * pttrace), verticalpttrace + 0);
                var baseAnimationPoint = new Point(nextPoint.X, 0).LocalizeInCartesianSpace(_lineVisual);
                var actualNextPoint    = nextPoint.LocalizeInCartesianSpace(_lineVisual);

                // TODO get rid of this
                var plottedPoint = IsLoaded ? actualNextPoint : baseAnimationPoint;

                if (isFirstPoint)
                {
                    visualContext.PolyLineStartPointAnimationAspect = new AnimationAspect <Point, PathFigure, PointAnimation>(
                        pathFigure, PathFigure.StartPointProperty, baseAnimationPoint, actualNextPoint, animationState)
                    {
                        AccelerationRatio = AnimationParameters.AccelerationRatio,
                        DecelerationRatio = AnimationParameters.DecelerationRatio,
                        Duration          = TimeSpan.FromMilliseconds(800),
                    };
                    isFirstPoint = false;
                }
                else
                {
                    var lineSegment = new LineSegment(plottedPoint, true)
                    {
                        IsSmoothJoin = true
                    };
                    pathSegments.Add(lineSegment);

                    visualContext.LineSegmentVisuals.Add(new LineGraphLineSegmentVisualContext
                    {
                        PointAnimationAspect =
                            new AnimationAspect <Point, LineSegment, PointAnimation>(lineSegment, LineSegment.PointProperty,
                                                                                     baseAnimationPoint, actualNextPoint, animationState)
                        {
                            AccelerationRatio = AnimationParameters.AccelerationRatio,
                            DecelerationRatio = AnimationParameters.DecelerationRatio,
                            Duration          = TimeSpan.FromMilliseconds(800)
                        }
                    });
                }

                var beginDotMargin  = new Thickness(nextPoint.X, 0, 0, 0);
                var actualDotMargin = new Thickness(nextPoint.X, 0, 0, nextPoint.Y);

                var dot = new Ellipse
                {
                    Width               = (DotRadius * 2),
                    Height              = (DotRadius * 2),
                    VerticalAlignment   = VerticalAlignment.Bottom,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Fill   = DotFill.GetMaterial(material),
                    Stroke = DotStroke.GetMaterial(material),
                };
                BindingOperations.SetBinding(dot, Shape.StrokeThicknessProperty, new Binding("DotStrokeThickness")
                {
                    Source = this
                });

                //currentCategoryVisualContext.DotMarginAnimationAspect =
                //	new AnimationAspect<Thickness, Ellipse, ThicknessAnimation>(dot, MarginProperty,
                //		beginDotMargin, actualDotMargin, animationState)
                //	{
                //		AccelerationRatio = AnimationParameters.AccelerationRatio,
                //		DecelerationRatio = AnimationParameters.DecelerationRatio,
                //		Duration = TimeSpan.FromMilliseconds(800)
                //	};

                _lineVisual.Children.Add(dot);
                Panel.SetZIndex(dot, 50);
                verticalpttrace += d.Value.Map(0, total, 0, availableLineGraphSize.Height);
                pttrace++;
            }

            var path = new Path
            {
                VerticalAlignment   = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Left,
                Data = new PathGeometry
                {
                    Figures = new PathFigureCollection
                    {
                        pathFigure
                    }
                },
                Margin = new Thickness(DotRadius, 0, 0, 0 + DotRadius),
                Stroke = LineStroke.GetMaterial(FallbackMaterialSet),
            };

            BindingOperations.SetBinding(path, Shape.StrokeThicknessProperty, new Binding("LineStrokeThickness")
            {
                Source = this
            });

            _lineVisual.Children.Add(path);
            base.OnRender(drawingContext);
        }
Пример #2
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            //TODO potential rendering loop.
            if (FilteredData.Count < 1)
            {
                FilteredData = DataFilter.Filter(DataSorter.Sort(Data));
                base.OnRender(drawingContext);
                return;
            }
            visualContext = new ParetoChartVisualContext();

            PART_bars.Children.Clear();
            PART_barlabels.Children.Clear();
            PART_line.Children.Clear();
            PART_xaxis.Children.Clear();
            //_highlightGrid.Children.Clear();

            var max = FilteredData.MaxValue();

            var context           = new ProviderContext(FilteredData.Count);
            var barAvailableWidth = (PART_bars.RenderSize.Width) / FilteredData.Count;
            var barActiveWidth    = barAvailableWidth * SegmentWidthPercentage;
            var barLeftSpacing    = (barAvailableWidth - barActiveWidth) / 2;
            var barLabelSize      = RenderingExtensions.EstimateLabelRenderSize(BarTotalFontFamily, BarTotalFontSize);

            MaterialProvider.Reset(context);

            #region X-Axis Label Generation

            var xtrace = 0;
            foreach (var d in FilteredData)
            {
                var material = MaterialProvider.ProvideNext(context);
                var categoryVisualContext = new ParetoChartCategoryVisualContext();
                var axisLabel             = new Label
                {
                    Content                    = d.CategoryName,
                    IsHitTestVisible           = false,
                    HorizontalContentAlignment = HorizontalAlignment.Center,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    HorizontalAlignment        = HorizontalAlignment.Left,
                    VerticalAlignment          = VerticalAlignment.Bottom,
                    Width       = barAvailableWidth,
                    Margin      = new Thickness(barAvailableWidth * xtrace, 0, 0, 0),
                    DataContext = this,
                    Foreground  = XAxisForeground.GetMaterial(material)
                };
                axisLabel.BindTextualPrimitive <XAxisPrimitive>(this);
                categoryVisualContext.AxisLabel = axisLabel;
                PART_xaxis.Children.Add(axisLabel);
                visualContext.CategoryVisuals.Add(categoryVisualContext);
                xtrace++;
            }

            #endregion

            MaterialProvider.Reset(context);
            var horizontalTrace = 0d;
            var xAxisHeight     = barLabelSize.Height;         //_xAxisGrid.ActualHeight;
            var backHeight      = PART_bars.RenderSize.Height - xAxisHeight;
            var trace           = 0;
            foreach (var d in FilteredData)
            {
                var currentCategoryVisualContext = visualContext.CategoryVisuals[trace];
                currentCategoryVisualContext.CategoryDataPoint = d;
                //if (barActiveWidth <= 0 || backHeight <= 0) return; //TODO fix
                var material = MaterialProvider.ProvideNext(context);
                currentCategoryVisualContext.CategoryMaterialSet = material;

                var backRectangle = new Rectangle
                {
                    Width               = barActiveWidth,
                    Height              = Math.Abs(backHeight),
                    VerticalAlignment   = VerticalAlignment.Bottom,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Fill   = SegmentSpaceBackground.GetMaterial(material),
                    Margin = new Thickness(horizontalTrace + barLeftSpacing, 0, 0, xAxisHeight)
                };


                currentCategoryVisualContext.InactiveBarVisual = backRectangle;
                PART_bars.Children.Add(backRectangle);

                var height    = d.Value.Map(0, max, 0, PART_bars.RenderSize.Height - xAxisHeight - barLabelSize.Height);
                var rectangle = new Rectangle
                {
                    Width                 = barActiveWidth,
                    Height                = Math.Abs(height),
                    Fill                  = SegmentForeground.GetMaterial(material),
                    VerticalAlignment     = VerticalAlignment.Bottom,
                    HorizontalAlignment   = HorizontalAlignment.Left,
                    Margin                = new Thickness(horizontalTrace + barLeftSpacing, 0, 0, xAxisHeight),
                    RenderTransform       = new ScaleTransform(1, 0, .5, 1),
                    RenderTransformOrigin = new Point(.5, 1)
                };


                currentCategoryVisualContext.ActiveBarRenderTransformScaleYAnimationAspect =
                    new AnimationAspect <double, Transform, DoubleAnimation>(rectangle.RenderTransform,
                                                                             ScaleTransform.ScaleYProperty, 0, 1, animationState)
                {
                    AccelerationRatio = AnimationParameters.AccelerationRatio,
                    DecelerationRatio = AnimationParameters.DecelerationRatio,
                    Duration          = TimeSpan.FromMilliseconds(800)
                };

                //TODO replace .RenderedVisual pairing method completely
                d.RenderedVisual = rectangle;
                PART_bars.Children.Add(rectangle);

                #region Bar Value Label Generation

                var beginBarLabelMargin  = new Thickness(horizontalTrace, 0, 0, xAxisHeight);
                var actualBarLabelMargin = new Thickness(horizontalTrace, 0, 0, xAxisHeight + height);

                var barLabel = new Label
                {
                    Content                    = d.Value,
                    IsHitTestVisible           = false,
                    HorizontalContentAlignment = HorizontalAlignment.Center,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    HorizontalAlignment        = HorizontalAlignment.Left,
                    VerticalAlignment          = VerticalAlignment.Bottom,
                    Width      = barAvailableWidth,
                    Foreground = BarTotalForeground.GetMaterial(material)
                };
                barLabel.BindTextualPrimitive <BarTotalPrimitive>(this);

                currentCategoryVisualContext.BarLabelMarginAnimationAspect = new AnimationAspect
                                                                             <Thickness, Label, ThicknessAnimation>(
                    barLabel, MarginProperty, beginBarLabelMargin, actualBarLabelMargin, animationState)
                {
                    AccelerationRatio = AnimationParameters.AccelerationRatio,
                    DecelerationRatio = AnimationParameters.DecelerationRatio,
                    Duration          = TimeSpan.FromMilliseconds(800)
                };

                #endregion

                PART_barlabels.Children.Add(barLabel);
                horizontalTrace += barAvailableWidth;
                trace++;
            }
            var total = FilteredData.SumValue();
            var availableLineGraphSize = new Size(PART_bars.ActualWidth - (DotRadius * 2),
                                                  PART_bars.ActualHeight - (DotRadius * 2) - xAxisHeight);
            var startX = (barAvailableWidth / 2) - DotRadius;

            var verticalpttrace = 0d;
            var pttrace         = 0;

            var pathSegments = new PathSegmentCollection();
            var pathFigure   = new PathFigure
            {
                Segments = pathSegments
            };
            MaterialProvider.Reset(context);

            var isFirstPoint = true;
            foreach (var d in FilteredData)
            {
                var material = MaterialProvider.ProvideNext(context);
                var currentCategoryVisualContext = visualContext.CategoryVisuals[pttrace];
                var nextPoint          = new Point(startX + (barAvailableWidth * pttrace), verticalpttrace + xAxisHeight);
                var baseAnimationPoint = new Point(nextPoint.X, 0).LocalizeInCartesianSpace(PART_line);
                var actualNextPoint    = nextPoint.LocalizeInCartesianSpace(PART_line);

                // TODO get rid of this
                var plottedPoint = IsLoaded ? actualNextPoint : baseAnimationPoint;

                if (isFirstPoint)
                {
                    visualContext.PolyLineStartPointAnimationAspect = new AnimationAspect <Point, PathFigure, PointAnimation>(
                        pathFigure, PathFigure.StartPointProperty, baseAnimationPoint, actualNextPoint, animationState)
                    {
                        AccelerationRatio = AnimationParameters.AccelerationRatio,
                        DecelerationRatio = AnimationParameters.DecelerationRatio,
                        Duration          = TimeSpan.FromMilliseconds(800),
                    };
                    isFirstPoint = false;
                }
                else
                {
                    var lineSegment = new LineSegment(plottedPoint, true)
                    {
                        IsSmoothJoin = true
                    };
                    pathSegments.Add(lineSegment);

                    visualContext.LineSegmentVisuals.Add(new ParetoChartLineSegmentVisualContext
                    {
                        PointAnimationAspect =
                            new AnimationAspect <Point, LineSegment, PointAnimation>(lineSegment, LineSegment.PointProperty,
                                                                                     baseAnimationPoint, actualNextPoint, animationState)
                        {
                            AccelerationRatio = AnimationParameters.AccelerationRatio,
                            DecelerationRatio = AnimationParameters.DecelerationRatio,
                            Duration          = TimeSpan.FromMilliseconds(800)
                        }
                    });
                }

                var beginDotMargin  = new Thickness(nextPoint.X, 0, 0, xAxisHeight);
                var actualDotMargin = new Thickness(nextPoint.X, 0, 0, nextPoint.Y);

                var dot = new Ellipse
                {
                    Width               = (DotRadius * 2),
                    Height              = (DotRadius * 2),
                    VerticalAlignment   = VerticalAlignment.Bottom,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Fill   = DotFill.GetMaterial(material),
                    Stroke = DotStroke.GetMaterial(material),
                };
                BindingOperations.SetBinding(dot, Shape.StrokeThicknessProperty, new Binding("DotStrokeThickness")
                {
                    Source = this
                });

                currentCategoryVisualContext.DotMarginAnimationAspect =
                    new AnimationAspect <Thickness, Ellipse, ThicknessAnimation>(dot, MarginProperty,
                                                                                 beginDotMargin, actualDotMargin, animationState)
                {
                    AccelerationRatio = AnimationParameters.AccelerationRatio,
                    DecelerationRatio = AnimationParameters.DecelerationRatio,
                    Duration          = TimeSpan.FromMilliseconds(800)
                };

                PART_line.Children.Add(dot);
                Panel.SetZIndex(dot, 50);
                verticalpttrace += d.Value.Map(0, total, 0, availableLineGraphSize.Height);
                pttrace++;
            }

            var path = new Path
            {
                VerticalAlignment   = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Left,
                Data = new PathGeometry
                {
                    Figures = new PathFigureCollection
                    {
                        pathFigure
                    }
                },
                Margin = new Thickness(DotRadius, 0, 0, xAxisHeight + DotRadius),
                Stroke = LineStroke.GetMaterial(FallbackMaterialSet),
            };
            BindingOperations.SetBinding(path, Shape.StrokeThicknessProperty, new Binding("LineStrokeThickness")
            {
                Source = this
            });

            PART_line.Children.Add(path);
            base.OnRender(drawingContext);
        }