Ejemplo n.º 1
0
 public Pyramid3DSlice(Pyramid2DSlice pyramid2DSlice, Double topOffset, Double bottomOffset, Brush color, Boolean isTopOfPyramid, Boolean lightingEnabled, Double opacity)
 {
     _points2d = pyramid2DSlice;
     _topOffset = topOffset;
     _bottomOffset = bottomOffset;
     _color = color;
     _isTopOfPyramid = isTopOfPyramid;
     _lightingEnabled = lightingEnabled;
     _opacity = opacity;
     Calculate3DLayerPoints();
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Create a slice of a pyramid
        /// </summary>
        /// <param name="isLightingGradientLayer">Whether CreatePyramidSlice() function should create a layer for lighting</param>
        /// <param name="topRadius">Top Radius of the pyramid</param>
        /// <param name="is3D">Whether the chart is a 3D Chart</param>
        /// <param name="pyramidSlice">PyramidSlice canvas reference</param>
        /// <param name="yScaleTop">Top YScale for 3D view</param>
        /// <param name="yScaleBottom">Bottom YScale for 3D view</param>
        /// <param name="sideFillColor">Side surface fill color</param>
        /// <param name="topFillColor">Top surface fill color</param>
        /// <param name="topSurfaceStroke">Top surface stroke color</param>
        /// <param name="animationEnabled">Whether animation is enabled</param>
        /// <returns>Return pyramid slice canvas</returns>
        private static Canvas CreatePyramidSlice(Boolean isLightingGradientLayer, Double topRadius, Boolean is3D, TriangularChartSliceParms pyramidSlice, Double yScaleTop, Double yScaleBottom, Brush sideFillColor, Brush topFillColor, Brush topSurfaceStroke, Boolean animationEnabled)
        {
            Canvas sliceCanvas = new Canvas() { Tag = new ElementData() { Element = pyramidSlice.DataPoint } };
            Canvas visual = new Canvas() { Width = topRadius * 2, Height = pyramidSlice.Height, Tag = new ElementData() { Element = pyramidSlice.DataPoint } };  // Canvas holds a slice of a pyramid chart
            Faces faces = null;
            //visual.Background = Graphics.GetRandomColor();

            Pyramid2DSlice pyramid2DSlice = new Pyramid2DSlice()
            {
                LT = new Point(topRadius - Math.Abs(pyramidSlice.TopRadius), 0),
                RT = new Point(topRadius + Math.Abs(pyramidSlice.TopRadius), 0),
                LB = new Point(topRadius - Math.Abs(pyramidSlice.BottomRadius), pyramidSlice.Height),
                RB = new Point(topRadius + Math.Abs(pyramidSlice.BottomRadius), pyramidSlice.Height)
            };

            Pyramid3DSlice pyramid3DSlice = null;

            if (is3D)
            {
                Double opacity = pyramidSlice.DataPoint.Opacity * pyramidSlice.DataPoint.Parent.Opacity;

                pyramid3DSlice = new Pyramid3DSlice(pyramid2DSlice, Math.Abs(yScaleTop / 2), Math.Abs(yScaleBottom / 2)
                    , isLightingGradientLayer ? new SolidColorBrush(Colors.Transparent) : pyramidSlice.DataPoint.Color
                    , (pyramidSlice.Index == 0)
                    , (Boolean)pyramidSlice.DataPoint.LightingEnabled, opacity);

                List<Path> paths = new List<Path>();

                Path lightingLayerLeft = null, lightingLayerFront = null, lightingLayerRight = null;
                Path backLayerLeft = pyramid3DSlice.GetFace(Pyramid3dLayer.BackLayerLeft, pyramidSlice.DataPoint, !isLightingGradientLayer);
                Path backLayerRight = pyramid3DSlice.GetFace(Pyramid3dLayer.BackLayerRight, pyramidSlice.DataPoint, !isLightingGradientLayer);
                Path bottomLayer = pyramid3DSlice.GetFace(Pyramid3dLayer.BottomLayer, pyramidSlice.DataPoint, !isLightingGradientLayer);
                Path frontLayerLeft = pyramid3DSlice.GetFace(Pyramid3dLayer.FrontLayerLeft, pyramidSlice.DataPoint, !isLightingGradientLayer);
                Path frontLayerRight = pyramid3DSlice.GetFace(Pyramid3dLayer.FrontLayerRight, pyramidSlice.DataPoint, !isLightingGradientLayer);
                Path topLayer = pyramid3DSlice.GetFace(Pyramid3dLayer.TopLayer, pyramidSlice.DataPoint, !isLightingGradientLayer);
                
                paths.Add(backLayerLeft);
                paths.Add(backLayerRight);
                paths.Add(bottomLayer);

                paths.Add(frontLayerLeft);
                paths.Add(frontLayerRight);
                paths.Add(topLayer);

                if ((Boolean)pyramidSlice.DataPoint.LightingEnabled && !isLightingGradientLayer)
                {   
                    if (pyramidSlice.Index != 0)
                        paths.Add(lightingLayerLeft = pyramid3DSlice.GetFace(Pyramid3dLayer.LightingLayerLeft, pyramidSlice.DataPoint, !isLightingGradientLayer));

                    paths.Add(lightingLayerFront = pyramid3DSlice.GetFace(Pyramid3dLayer.LightingLayerFront, pyramidSlice.DataPoint, !isLightingGradientLayer));

                    if (pyramidSlice.Index != 0)
                        paths.Add(lightingLayerRight = pyramid3DSlice.GetFace(Pyramid3dLayer.LightingLayerRight, pyramidSlice.DataPoint, !isLightingGradientLayer));
                }

                foreach (Path path in paths)
                    visual.Children.Add(path);

                if (!isLightingGradientLayer)
                {   
                    // Update faces for the DataPoint
                    faces = new Faces();

                    foreach (Path path in paths)
                        faces.VisualComponents.Add(path);

                    foreach (Path path in paths)
                        faces.Parts.Add(path);

                    // If lighting is disabled then the visual components are the border elements
                    if (!(Boolean)pyramidSlice.DataPoint.LightingEnabled)
                    {
                        foreach (Path path in paths)
                        {   
                            if (path != bottomLayer && path != backLayerLeft && path != backLayerRight)
                                faces.BorderElements.Add(path);
                        }

                        if(opacity < 1)
                            faces.BorderElements.Add(bottomLayer);
                    }

                    pyramidSlice.DataPoint.Faces = faces;
                }
                else
                {
                    faces = pyramidSlice.DataPoint.Faces;

                    if (faces != null)
                    {
                        foreach (Path path in paths)
                        {
                            if (path != bottomLayer && path != backLayerLeft && path != backLayerRight)
                                faces.BorderElements.Add(path);
                        }

                        if (opacity < 1)
                            faces.BorderElements.Add(bottomLayer);
                    }
                }


                if (faces.BorderElements != null)
                {
                    foreach (Path path in faces.BorderElements)
                    {
                        path.StrokeThickness = pyramidSlice.DataPoint.BorderThickness.Left;
                        path.Stroke = pyramidSlice.DataPoint.BorderColor;
                        path.StrokeDashArray = ExtendedGraphics.GetDashArray((BorderStyles)pyramidSlice.DataPoint.BorderStyle);
                    }
                }

                // Apply animation for the 3D pyramid slice
                if (animationEnabled)
                {
                    foreach (Path path in paths)
                    {
                        //Double animationBeginTime = (pyramidSlice.DataPoint.Parent.InternalDataPoints.Count - pyramidSlice.Index) / pyramidSlice.DataPoint.Parent.InternalDataPoints.Count;
                        pyramidSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(path, pyramidSlice.DataPoint.Parent, pyramidSlice.DataPoint.Parent.Storyboard, 0, pyramidSlice.DataPoint.InternalOpacity, 0, 1);
                    }
                }
            }
            else
            {   
                // PathGeometry for for a pyramid slice path
                PathGeometry pathGeometry = new PathGeometry();

                // pathFigure for for a pyramid slice path
                PathFigure pathFigure = new PathFigure() { StartPoint = pyramid2DSlice.LT, IsClosed= true };  // PathFigure of a pyramid slice

                // Path for for a pyramid slice
                Path path4Slice = new Path() { Fill = sideFillColor };

                path4Slice.Tag = new ElementData() { Element = pyramidSlice.DataPoint };

                // Set path data
                path4Slice.Data = pathGeometry;

                // Set properties for path
                path4Slice.StrokeThickness = 0;
                path4Slice.Stroke = new SolidColorBrush(Colors.Black);

                // Add path elements to its parent canvas
                pathGeometry.Figures.Add(pathFigure);
                visual.Children.Add(path4Slice);
                
                PolyLineSegment polySeg = new PolyLineSegment();
                polySeg.Points = pyramid2DSlice.GetAllPoints();
                pathFigure.Segments.Add(polySeg);

                // Points of a 2D pyramid slice
                Point[] pyramidCornerPoints = new Point[8];
                pyramidCornerPoints[0] = new Point(topRadius - pyramidSlice.TopRadius, 0);
                pyramidCornerPoints[1] = new Point(topRadius + pyramidSlice.TopRadius, 0);
                pyramidCornerPoints[2] = new Point(topRadius + pyramidSlice.BottomRadius, pyramidSlice.Height);
                pyramidCornerPoints[3] = new Point(topRadius - pyramidSlice.BottomRadius, pyramidSlice.Height);

                // Apply animation for the 2D pyramid slice
                if (animationEnabled)
                    pyramidSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(path4Slice, pyramidSlice.DataPoint.Parent, pyramidSlice.DataPoint.Parent.Storyboard, 0, pyramidSlice.DataPoint.InternalOpacity, 0, 1);

                if (!isLightingGradientLayer)
                {
                    // Update faces for the DataPoint
                    faces = new Faces();
                    faces.VisualComponents.Add(path4Slice);

                    (path4Slice.Tag as ElementData).VisualElementName = "PyramidBase";
                    faces.Parts.Add(path4Slice);

                    faces.BorderElements.Add(path4Slice);

                    path4Slice.StrokeThickness = pyramidSlice.DataPoint.BorderThickness.Left;
                    path4Slice.Stroke = pyramidSlice.DataPoint.BorderColor;
                    path4Slice.StrokeDashArray = ExtendedGraphics.GetDashArray((BorderStyles)pyramidSlice.DataPoint.BorderStyle);

                    pyramidSlice.DataPoint.Faces = faces;

                    // Apply bevel effect for the 2D pyramid Slice
                    if (pyramidSlice.DataPoint.Parent.Bevel)
                    {
                        ApplyPyramidBevel(visual, pyramidSlice, sideFillColor, pyramidCornerPoints);
                    }
                }
                else
                {
                    path4Slice.IsHitTestVisible = false;
                    pyramidSlice.DataPoint.Faces.VisualComponents.Add(path4Slice);
                    (path4Slice.Tag as ElementData).VisualElementName = "Lighting";
                }
            }

            if (isLightingGradientLayer)
            {
                visual.IsHitTestVisible = false;
            }
            else
            {
                // Drawing LabelLine
                Canvas labelLineCanvas = CreateLabelLine(pyramidSlice, pyramid3DSlice, topRadius, animationEnabled);

                if (labelLineCanvas != null)
                {
                    sliceCanvas.Children.Add(labelLineCanvas);
                    faces.VisualComponents.Add(labelLineCanvas);
                }

                // Add label visual to the visual
                if ((Boolean)pyramidSlice.DataPoint.LabelEnabled)
                {
                    Canvas labelCanvas = new Canvas();
                    labelCanvas.SetValue(Canvas.ZIndexProperty, (Int32)10);

                    faces.VisualComponents.Add(pyramidSlice.DataPoint.LabelVisual);

                    // Label placement

                    if (pyramidSlice.DataPoint.LabelStyle == LabelStyles.OutSide)
                    {
                        pyramidSlice.DataPoint.LabelVisual.SetValue(Canvas.TopProperty, pyramidSlice.LabelLineEndPoint.Y - pyramidSlice.DataPoint.LabelVisual.Height / 2);
                        pyramidSlice.DataPoint.LabelVisual.SetValue(Canvas.LeftProperty, pyramidSlice.LabelLineEndPoint.X + 2);
                    }
                    else
                    {
                        if(is3D)
                        {
                            Point centerPoint = Graphics.MidPointOfALine(pyramid3DSlice.Top3DLayer.CB, pyramid3DSlice.Bottom3DLayer.CB);
                           pyramidSlice.DataPoint.LabelVisual.SetValue(Canvas.TopProperty, (centerPoint.Y - pyramidSlice.DataPoint.LabelVisual.Height / 2));
                        }
                        else
                            pyramidSlice.DataPoint.LabelVisual.SetValue(Canvas.TopProperty, pyramidSlice.LabelLineEndPoint.Y - pyramidSlice.DataPoint.LabelVisual.Height / 2);
                        pyramidSlice.DataPoint.LabelVisual.SetValue(Canvas.LeftProperty, topRadius - pyramidSlice.DataPoint.LabelVisual.Width / 2);
                    }

                    if (animationEnabled)
                        pyramidSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(pyramidSlice.DataPoint.LabelVisual, pyramidSlice.DataPoint.Parent, pyramidSlice.DataPoint.Parent.Storyboard, 1.2, 0.5, 0, 1);

                    labelCanvas.Children.Add(pyramidSlice.DataPoint.LabelVisual);
                    sliceCanvas.Children.Add(labelCanvas);
                }
            }

            // if (!isLightingGradientLayer)
            //    faces.Visual = visual;

            sliceCanvas.Children.Add(visual);

            // sliceCanvas.Background = new SolidColorBrush(Color.FromArgb((byte)rand.Next(0,200),(byte)rand.Next(0,200),(byte)rand.Next(0,200),(byte)rand.Next(0,200)));

            return sliceCanvas;
        }