Пример #1
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            _segments.Children.Clear();

            var angle = FilteredData.Map(0, 100, 0, 360);

            var radius       = (_segments.RenderSize.Smallest() * CircleScale) / 2;
            var segmentWidth = radius * SegmentWidthPercentage;
            var inactivePath = new ArcPath(359.999, 0, segmentWidth, CircleScale, radius, _segments.RenderSize, null)
            {
                DataContext = this
            };
            var activePath = new ArcPath(angle, AngleOffset, segmentWidth, CircleScale, radius, _segments.RenderSize, FilteredData)
            {
                DataContext = this
            };

            inactivePath.Fill = SegmentSpaceBackground.GetMaterial(FallbackMaterialSet);
            activePath.Fill   = RingForeground.GetMaterial(FallbackMaterialSet);
            //inactivePath.SetBinding(Shape.FillProperty, new Binding("SegmentSpaceBackground"));
            //activePath.SetBinding(Shape.FillProperty, new Binding("RingForeground"));

            _segments.Children.Add(inactivePath);
            _segments.Children.Add(activePath);

            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 NestedArcChartVisualContext();

            PART_segments.Children.Clear();
            PART_inactivesegments.Children.Clear();
            PART_categorylabels.Children.Clear();

            var context = new ProviderContext(FilteredData.Count);

            MaterialProvider.Reset(context);

            var fullArcDiameter      = PART_main.RenderSize.Height - TopRingPadding;
            var fullArcWidth         = fullArcDiameter - BottomRingPadding;
            var subArcAvailableWidth = fullArcWidth / FilteredData.Count;
            var subArcActualWidth    = subArcAvailableWidth * SegmentWidthPercentage;
            var subRingOffset        = (subArcAvailableWidth - subArcActualWidth) / 2;

            var fullRadius  = PART_main.RenderSize.Width / 2;
            var centerPoint = new Point(0, fullRadius);

            if (FilteredData.Count < 1)
            {
                base.OnRender(drawingContext);
                return;
            }

            var max   = FilteredData.MaxValue();
            var trace = 0;

            foreach (var d in FilteredData)
            {
                var categoryVisualContext = new NestedArcCategoryVisualContext();
                var materialSet           = MaterialProvider.ProvideNext(context);

                categoryVisualContext.CategoryDataPoint = d;
                var arcDiameter = BottomRingPadding + (subArcAvailableWidth * trace) + subRingOffset;

                var inactiveArcPath = CalculatePath(centerPoint, arcDiameter, subArcActualWidth);
                inactiveArcPath.Fill = SegmentSpaceBackground.GetMaterial(materialSet);
                //BindingOperations.SetBinding(inactiveArcPath, Shape.FillProperty, new Binding("SegmentSpaceBackground") { Source = this });

                categoryVisualContext.InactiveArcVisual = inactiveArcPath;
                PART_inactivesegments.Children.Add(inactiveArcPath);

                var activeArcAngle = d.Value.Map(0, max, 0, MaxArcAngle);

                var activeArcPath = CalculateActiveArcPath(centerPoint, arcDiameter, subArcActualWidth, activeArcAngle);


                categoryVisualContext.CategoryMaterialSet = materialSet;

                activeArcPath.Fill                  = SegmentForeground.GetMaterial(materialSet);
                activeArcPath.MouseOverFill         = materialSet.GetMaterial(Luminosity.P700);
                activeArcPath.RenderTransformOrigin = new Point(.5, 1);
                activeArcPath.RenderTransform       = new RotateTransform((IsLoaded ? 0 : 180), .5, .5);
                d.RenderedVisual = activeArcPath;

                categoryVisualContext.ActiveArcVisual = activeArcPath;
                PART_segments.Children.Add(activeArcPath);

                visualContext.CategoryVisuals.Add(categoryVisualContext);
                trace++;
            }
            var ltrace = 0;

            for (var x = FilteredData.Count - 1; x >= 0; x--)
            {
                var d = FilteredData[x];
                var currentCategoryVisualContext = visualContext.CategoryVisuals[x];
                var shape              = (Shape)d.RenderedVisual;     //.ShouldBeCastable<Shape>();
                var renderedFill       = (SolidColorBrush)shape.Fill; //.ShouldBeType<SolidColorBrush>();
                var arcLabelMarginLeft = fullRadius + LeftArcLabelSpacing;
                var categoryLabel      = new Label
                {
                    Width                      = ValueLabelHorizontalSpacing,
                    VerticalAlignment          = VerticalAlignment.Top,
                    HorizontalAlignment        = HorizontalAlignment.Left,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    HorizontalContentAlignment = HorizontalAlignment.Left,
                    Margin                     = new Thickness(arcLabelMarginLeft, (ltrace * subArcAvailableWidth) + subRingOffset + 6, 0, 0),
                    //Foreground = renderedFill.Lighten(.2),
                    Foreground  = ValueForeground.GetMaterial(currentCategoryVisualContext.CategoryMaterialSet),
                    Content     = d.CategoryName.ToUpper(),
                    Height      = subArcAvailableWidth,
                    Padding     = new Thickness(0),
                    Opacity     = IsLoaded ? 1 : 0,                 // TODO isloaded
                    DataContext = this
                };
                currentCategoryVisualContext.CategoryLabel = categoryLabel;
                //BindingOperations.SetBinding(categoryLabel, FontFamilyProperty, new Binding("ValueFontFamily") { Source = this });
                //BindingOperations.SetBinding(categoryLabel, FontStyleProperty, new Binding("ValueFontStyle") { Source = this });
                //BindingOperations.SetBinding(categoryLabel, FontWeightProperty, new Binding("ValueFontWeight") { Source = this });
                //BindingOperations.SetBinding(categoryLabel, FontSizeProperty, new Binding("ValueFontSize") { Source = this });
                categoryLabel.BindTextualPrimitive <ValuePrimitive>(this);
                var valuePercentLabel = new Label
                {
                    Width                      = ValueLabelHorizontalSpacing,
                    VerticalAlignment          = VerticalAlignment.Top,
                    HorizontalAlignment        = HorizontalAlignment.Left,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    HorizontalContentAlignment = HorizontalAlignment.Right,
                    Margin                     = new Thickness(arcLabelMarginLeft, (ltrace * subArcAvailableWidth) + subRingOffset + 6, 0, 0),
                    //Foreground = renderedFill.Lighten(.2),
                    Foreground  = ValueForeground.GetMaterial(currentCategoryVisualContext.CategoryMaterialSet),
                    Content     = d.Value + " Minutes",
                    Height      = subArcAvailableWidth,
                    Padding     = new Thickness(0),
                    Opacity     = IsLoaded ? 1 : 0,
                    DataContext = this
                };
                currentCategoryVisualContext.ValuePercentLabel = valuePercentLabel;
                valuePercentLabel.BindTextualPrimitive <ValuePrimitive>(this);
                var valueLabelLeftSpace = arcLabelMarginLeft + ValueLabelHorizontalSpacing;
                var valueLabelWidth     = PART_main.RenderSize.Width - valueLabelLeftSpace;
                if (valueLabelWidth < 0)
                {
                    valueLabelWidth = 0;
                }
                var valueLabel = new Label()
                {
                    Width                      = valueLabelWidth,
                    VerticalAlignment          = VerticalAlignment.Top,
                    HorizontalAlignment        = HorizontalAlignment.Left,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    HorizontalContentAlignment = HorizontalAlignment.Left,
                    Foreground                 = SecondaryValueForeground.GetMaterial(currentCategoryVisualContext.CategoryMaterialSet),
                    Margin                     = new Thickness(arcLabelMarginLeft + ValueLabelHorizontalSpacing, (ltrace * subArcAvailableWidth) + subRingOffset + 6, 0, 0),
                    Content                    = $" = {Math.Round(d.Value / 60, 2)} Hours", //{Math.Round(d.Value * 48):n0}
                    Height                     = subArcAvailableWidth,
                    Opacity                    = IsLoaded ? 1 : 0,                          // TODO isloaded
                    Padding                    = new Thickness(0),
                };
                currentCategoryVisualContext.ValueLabel = valueLabel;
                valueLabel.BindTextualPrimitive <SecondaryValuePrimitive>(this);

                PART_categorylabels.Children.Add(categoryLabel);
                PART_categorylabels.Children.Add(valuePercentLabel);
                PART_categorylabels.Children.Add(valueLabel);

                ltrace++;
            }
            base.OnRender(drawingContext);
        }
Пример #3
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            PART_bars.Children.Clear();
            PART_xAxis.Children.Clear();
            PART_highlight.Children.Clear();

            if (FilteredData.Count < 1)
            {
                base.OnRender(drawingContext);
                return;
            }
            var total = 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);
            var xtrace = 0;

            foreach (var d in FilteredData)
            {
                var materialSet = MaterialProvider.ProvideNext(context);
                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),
                    Foreground  = BarTotalForeground.GetMaterial(materialSet),
                    DataContext = this
                };
                axisLabel.BindTextualPrimitive <XAxisPrimitive>(this);

                PART_xAxis.Children.Add(axisLabel);
                xtrace++;
            }
            var horizontalTrace = 0d;
            var xAxisHeight     = PART_xAxis.ActualHeight;
            var backHeight      = PART_bars.RenderSize.Height - xAxisHeight;

            MaterialProvider.Reset(context);
            foreach (var d in FilteredData)
            {
                var materialSet   = MaterialProvider.ProvideNext(context);
                var backRectangle = new Rectangle
                {
                    Width               = barActiveWidth,
                    Height              = backHeight,
                    VerticalAlignment   = VerticalAlignment.Bottom,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Margin              = new Thickness(horizontalTrace + barLeftSpacing, 0, 0, xAxisHeight),
                    Fill = SegmentSpaceBackground.GetMaterial(materialSet)
                };
                //backRectangle.MouseEnter += (s, e) => barMouseEnter(d);
                //BindingOperations.SetBinding(backRectangle, Shape.FillProperty, new Binding("SegmentSpaceBackground") { Source = this });

                PART_bars.Children.Add(backRectangle);


                var verticalTrace = 0d;
                var pathBuffer    = new List <Shape>();


                var height    = d.Value.Map(0, total, 0, PART_bars.RenderSize.Height - xAxisHeight - barLabelSize.Height);
                var rectangle = new Rectangle
                {
                    Width               = barActiveWidth,
                    Height              = height + verticalTrace,
                    Fill                = SegmentForeground.GetMaterial(materialSet),
                    VerticalAlignment   = VerticalAlignment.Bottom,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Margin              = new Thickness(horizontalTrace + barLeftSpacing, 0, 0, xAxisHeight)
                };
                //rectangle.MouseEnter += (s, e) => barMouseEnter(d);
                //rectangle.MouseLeave += (s, e) => barMouseLeave(s, e, d, sd);
                rectangle.RenderTransform       = new ScaleTransform(1, (IsLoaded ? 1 : 0), .5, 1);           //TODO get rid of all isloaded conditional sets
                rectangle.RenderTransformOrigin = new Point(.5, 1);

                d.RenderedVisual = rectangle;
                pathBuffer.Add(rectangle);
                verticalTrace += height;

                for (var x = pathBuffer.Count - 1; x >= 0; x--)
                {
                    var path = pathBuffer[x];
                    PART_bars.Children.Add(path);
                }
                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(materialSet),
                    Margin     = new Thickness(horizontalTrace, 0, 0, xAxisHeight + verticalTrace),
                };
                barLabel.BindTextualPrimitive <BarTotalPrimitive>(this);
                d.RenderedVisual = pathBuffer;
                PART_bars.Children.Add(barLabel);
                horizontalTrace += barAvailableWidth;
            }
            base.OnRender(drawingContext);
        }
Пример #4
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);
        }
Пример #5
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            visualContext = new HorizontalBarChartVisualContext();

            PART_bars.Rows  = FilteredData.Count;
            PART_yaxis.Rows = FilteredData.Count;

            PART_bars.Children.Clear();
            PART_yaxis.Children.Clear();

            if (FilteredData.Count < 1)
            {
                base.OnRender(drawingContext);
                return;
            }
            var effeectiveTargetRenderingMax = CommonFixedRangeMax > 0 ? CommonFixedRangeMax : FilteredData.MaxValue();

            var context = new ProviderContext(FilteredData.Count);

            MaterialProvider.Reset(context);
            double YAxisRenderingWidth;

            if (CommonYAxisWidth <= 0)
            {
                var maxYAxisTextLength = FilteredData.Select(d => RenderingExtensions.EstimateLabelRenderSize(
                                                                 YAxisFontFamily, YAxisFontSize, d.CategoryName))
                                         .Select(renderSize => renderSize.Width).Concat(new[] { 0.0 }).Max();
                YAxisRenderingWidth = maxYAxisTextLength;
            }
            else
            {
                YAxisRenderingWidth = CommonYAxisWidth;
            }
            PART_yaxis.Width = YAxisRenderingWidth;

            var maxValueTextLength = FilteredData.Select(d => RenderingExtensions.EstimateLabelRenderSize(
                                                             BarTotalFontFamily, BarTotalFontSize, new Thickness(10, 5, 10, 5), d.Value.ToString(CultureInfo.InvariantCulture)))
                                     .Select(renderSize => renderSize.Width).Concat(new[] { 0.0 }).Max();
            var totalAvailableVerticalSpace = 0.0;

            if (CommonFixedRowHeight > 0)
            {
                totalAvailableVerticalSpace = CommonFixedRowHeight;
            }
            else
            {
                totalAvailableVerticalSpace = PART_bars.ActualHeight / FilteredData.Count;
            }
            var totalAvailableHorizontalExpanse = PART_bars.ActualWidth;
            var totalAvailableHorizontalSpace   = totalAvailableHorizontalExpanse - maxValueTextLength;
            var actualBarHeight = totalAvailableVerticalSpace * SegmentWidthPercentage;

            foreach (var d in FilteredData)
            {
                var barContext  = new HorizontalBarChartSegmentVisualContext();
                var barWidth    = d.Value.Map(0, effeectiveTargetRenderingMax, 0, totalAvailableHorizontalSpace);
                var materialSet = MaterialProvider.ProvideNext(context);

                var barGrid = new Grid();

                var bar = new Rectangle
                {
                    Fill   = SegmentForeground.GetMaterial(materialSet),
                    Height = actualBarHeight,
                    Width  = barWidth,
                    HorizontalAlignment = HorizontalAlignment.Left
                };
                barGrid.Children.Add(bar);
                barContext.ActiveBar = bar;

                var barSpaceBackground = new Rectangle
                {
                    Fill   = SegmentSpaceBackground.GetMaterial(materialSet),
                    Height = actualBarHeight,
                    Width  = totalAvailableHorizontalExpanse,
                    HorizontalAlignment = HorizontalAlignment.Left
                };
                barGrid.Children.Add(barSpaceBackground);
                barContext.InactiveBar = barSpaceBackground;

                var barLabel = new Label
                {
                    Content                    = d.Value,
                    IsHitTestVisible           = false,
                    HorizontalContentAlignment = HorizontalAlignment.Center,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    HorizontalAlignment        = HorizontalAlignment.Left,
                    //VerticalAlignment = VerticalAlignment.Center ,
                    Width      = maxValueTextLength,
                    Padding    = new Thickness(10, 5, 10, 5),
                    Foreground = BarTotalForeground.GetMaterial(materialSet),
                    Margin     = new Thickness(barWidth, 0, 0, 0),
                };
                barLabel.BindTextualPrimitive <BarTotalPrimitive>(this);
                barGrid.Children.Add(barLabel);
                barContext.BarLabel = barLabel;

                PART_bars.Children.Add(barGrid);

                var yaxisLabel = new Label
                {
                    Content                    = TextRenderingStrategy.ProvideText(d.CategoryName, YAxisRenderingWidth, YAxisFontFamily, YAxisFontSize, YAxisPadding),
                    IsHitTestVisible           = false,
                    HorizontalContentAlignment = HorizontalAlignment.Left,
                    VerticalContentAlignment   = VerticalAlignment.Center,
                    ToolTip                    = d.CategoryName,
                    //HorizontalAlignment = HorizontalAlignment.Left,
                    //VerticalAlignment = VerticalAlignment.Center,
                    Width      = YAxisRenderingWidth,
                    Foreground = YAxisForeground.GetMaterial(materialSet),
                    Margin     = new Thickness(0, 0, 0, 0),
                    Padding    = YAxisPadding
                };
                yaxisLabel.BindTextualPrimitive <YAxisPrimitive>(this);
                PART_yaxis.Children.Add(yaxisLabel);

                visualContext.BarVisuals.Add(barContext);
            }
            base.OnRender(drawingContext);
        }