コード例 #1
0
ファイル: NestedArcChart.cs プロジェクト: zjp1907/FlexCharts
        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);
        }
コード例 #2
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            PART_focusedsegmentlabel.Foreground = SecondaryValueForeground.GetMaterial(FallbackMaterialSet);
            PART_segments.Children.Clear();

            var context = new ProviderContext(FilteredData.Count);

            MaterialProvider.Reset(context);

            var radius = (PART_segments.RenderSize.Smallest() * CircleScale) / 2;

            var total           = Data.SumValue();
            var angleTrace      = 0d;
            var actualRingWidth = radius * RingWidthPercentage;

            foreach (var d in FilteredData)
            {
                var materialSet = MaterialProvider.ProvideNext(context);
                var degrees     = (d.Value / total) * 360;

                var activePath = new ArcPath(degrees, angleTrace, actualRingWidth, CircleScale, radius, PART_segments.RenderSize, d)
                {
                    Fill          = SegmentForeground.GetMaterial(materialSet),
                    MouseOverFill = materialSet.GetMaterial(Luminosity.P700),
                    DataContext   = this
                };
                activePath.Click += segmentClicked;
                PART_segments.Children.Add(activePath);
                d.RenderedVisual = activePath;
                angleTrace      += degrees;
            }
            if (FocusedSegment == null)
            {
                return;
            }
            PART_categorylabels.Children.Clear();
            var diameter = PART_segments.RenderSize.Smallest() * CircleScale;

            var outerLabelRadius     = (diameter / 2) * OuterLabelPositionScale;
            var overlayedLabelRadius = (diameter / 2) - (actualRingWidth / 2);

            var targetAngularOffset = FocusedSegment.RequireType <ArcPath>().CalculateAngularOffset();

            MaterialProvider.Reset(context);
            foreach (var d in FilteredData)
            {
                var materialSet = MaterialProvider.ProvideNext(context);

                var categoryNameLabel = positionLabel(d, outerLabelRadius, targetAngularOffset, true);

                categoryNameLabel.Content = d.CategoryName;
                categoryNameLabel.BindTextualPrimitive <BarTotalPrimitive>(this);
                categoryNameLabel.Foreground = BarTotalForeground.GetMaterial(materialSet);
                PART_categorylabels.Children.Add(categoryNameLabel);

                var valueLabel = positionLabel(d, overlayedLabelRadius, targetAngularOffset);

                valueLabel.Content = d.Value;
                valueLabel.BindTextualPrimitive <ValuePrimitive>(this);
                valueLabel.Foreground = ValueForeground.GetMaterial(materialSet);
                PART_categorylabels.Children.Add(valueLabel);
            }
            base.OnRender(drawingContext);
        }