Ejemplo n.º 1
0
        private static void UpdateLabelLineEndPoint(TriangularChartSliceParms funnelSlice)
        {
            Path labelLine = funnelSlice.DataPoint.LabelLine;

            if (labelLine != null && labelLine.Data != null)
            {
                LineSegment ls = (((labelLine.Data as PathGeometry).Figures[0] as PathFigure).Segments[0] as LineSegment);
                ls.Point = funnelSlice.LabelLineEndPoint;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get top lighting brush for funnel slice
        /// </summary>
        /// <param name="fillBrush">Current brush</param>
        /// <returns>Return new Brush</returns>
        private static Brush GetTopBrush(Brush fillBrush, TriangularChartSliceParms funnelSlice)
        {
            if ((fillBrush as SolidColorBrush) != null)
            {
                 SolidColorBrush solidBrush = fillBrush as SolidColorBrush;
                // LinearGradientBrush gb = new LinearGradientBrush() { EndPoint = new Point(0.5, 1), StartPoint = new Point(0.5, 0) };
                // gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetLighterColor(solidBrush.Color, 0.8), Offset = 1 });
                // gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetLighterColor(solidBrush.Color, 1), Offset = 0 });

                Double r = ((double)solidBrush.Color.R / (double)255) * 0.9999;
                Double g = ((double)solidBrush.Color.G / (double)255) * 0.9999;
                Double b = ((double)solidBrush.Color.B / (double)255) * 0.9999;

                /*-----------Solid---------
                 * 
                SolidColorBrush solidBrush = fillBrush as SolidColorBrush;
                // List<Color> colors = new List<Color>();
                // List<Double> stops = new List<Double>();
                */

                LinearGradientBrush gb = null;

                if (funnelSlice.FillType == FillType.Solid)
                {
                    gb = new LinearGradientBrush() { StartPoint = new Point(0, 0), EndPoint = new Point(1, 1) };
                    gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetLighterColor(solidBrush.Color, 1 - r, 1 - g, 1 - b), Offset = 0 });
                    gb.GradientStops.Add(new GradientStop() { Color = solidBrush.Color, Offset = 0.9 });
                    gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetDarkerColor(solidBrush.Color, 1), Offset = 0.99 });
                    gb.Opacity = 1;

                }
                else if (funnelSlice.FillType == FillType.Hollow)
                {   
                    gb = new LinearGradientBrush()
                    {
                        StartPoint = new Point(0.233, 0.297),
                        EndPoint = new Point(0.757, 0.495)
                    };

                    gb.GradientStops.Add(new GradientStop() { Offset = 0, Color = Graphics.GetDarkerColor(solidBrush.Color, 0.5) });
                    gb.GradientStops.Add(new GradientStop() { Offset = 0.70, Color = solidBrush.Color });
                   // gb.GradientStops.Add(new GradientStop() { Offset = 0.495, Color = Colors.White });
                    gb.GradientStops.Add(new GradientStop() { Offset = 1, Color = Graphics.GetDarkerColor(solidBrush.Color, 0.8)});
                    // gb.Opacity = 0.5;


                    //gb.GradientStops.Add(new GradientStop() { Offset = 0, Color = Graphics.GetDarkerColor(solidBrush.Color, 0.5) });
                    //gb.GradientStops.Add(new GradientStop() { Offset = 0.60, Color = Graphics.GetLighterColor(solidBrush.Color, 1 - r, 1 - g, 1 - b) });
                    //// gb.GradientStops.Add(new GradientStop() { Offset = 0.495, Color = Colors.White });
                    //gb.GradientStops.Add(new GradientStop() { Offset = 1, Color = Graphics.GetDarkerColor(solidBrush.Color, 0.8) });
                   
                    //gb = new LinearGradientBrush() { StartPoint = new Point(0.2, 1.6), EndPoint = new Point(0.7, 0) };
                    //gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetLighterColor(solidBrush.Color, 1 - r, 1 - g, 1 - b), Offset = 0 });
                    //gb.GradientStops.Add(new GradientStop() { Color = solidBrush.Color, Offset = 0.9 });
                    //gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetLighterColor(solidBrush.Color, 0.5), Offset = 0.99 });
                    //gb.Opacity = 1;
                }

                return gb;
            }
            else
                return fillBrush;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Arrange labels to overcome overlaps
        /// </summary>
        internal static void ArrangeLabels(TriangularChartSliceParms[] funnelSlices, Double width, Double height)
        {
            if (funnelSlices == null || funnelSlices.Length < 0)
                return;

            TriangularChartSliceParms[] selectedfunnelSlices = (from fs in funnelSlices where fs.DataPoint.LabelStyle == LabelStyles.OutSide select fs).ToArray();

            Rect baseArea = new Rect(0, 0, width, height);
            Rect[] labelInfo = new Rect[selectedfunnelSlices.Length];
            Double gapAtBottomLineOfBaseArea = 0;

            for (Int32 index = 0; index < selectedfunnelSlices.Length; index++)
            {
                //selectedfunnelSlices[index].DataPoint.LabelVisual.SetValue(Canvas.TopProperty, selectedfunnelSlices[index].OrginalLabelLineEndPoint.Y - selectedfunnelSlices[index].DataPoint.LabelVisual.Height / 2);
                
                Double left = (Double)selectedfunnelSlices[index].DataPoint.LabelVisual.GetValue(Canvas.LeftProperty);
                Double top = (Double)selectedfunnelSlices[index].DataPoint.LabelVisual.GetValue(Canvas.TopProperty);

                Double sliceCanvasTop = selectedfunnelSlices[index].Top + top;

                if (sliceCanvasTop + selectedfunnelSlices[index].DataPoint.LabelVisual.Height + gapAtBottomLineOfBaseArea > baseArea.Height)
                {
                    sliceCanvasTop -= (sliceCanvasTop + selectedfunnelSlices[index].DataPoint.LabelVisual.Height + gapAtBottomLineOfBaseArea) - baseArea.Height;
                }
                
                labelInfo[index] = new Rect
                    (left,
                    sliceCanvasTop,
                    selectedfunnelSlices[index].DataPoint.LabelVisual.Width,
                    selectedfunnelSlices[index].DataPoint.LabelVisual.Height);
            }

            Visifire.Commons.LabelPlacementHelper.VerticalLabelPlacement(baseArea, ref labelInfo);

            for (Int32 index = 0; index < selectedfunnelSlices.Length; index++)
            {
                Double labelTop = labelInfo[index].Top - selectedfunnelSlices[index].Top;

                selectedfunnelSlices[index].DataPoint.LabelVisual.SetValue(Canvas.LeftProperty, labelInfo[index].Left);
                selectedfunnelSlices[index].DataPoint.LabelVisual.SetValue(Canvas.TopProperty, labelTop);

                selectedfunnelSlices[index].LabelLineEndPoint = new Point(selectedfunnelSlices[index].LabelLineEndPoint.X, labelTop + selectedfunnelSlices[index].DataPoint.LabelVisual.Height / 2);
                UpdateLabelLineEndPoint(selectedfunnelSlices[index]);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Calculate Bevel innter points
        /// </summary>
        /// <param name="funnelSlice">funnelSlice</param>
        /// <param name="points">Array of points</param>
        private static void CalculateBevelInnerPoints(TriangularChartSliceParms funnelSlice, Point[] points)
        {
            Double a, b, h = Chart.BEVEL_DEPTH;

            a = h * Math.Sin(funnelSlice.TopAngle / 2);
            b = h * Math.Cos(funnelSlice.TopAngle / 2);

            points[4] = new Point(points[0].X + b, a);
            points[5] = new Point(points[1].X - b, a);

            // a = h * Math.Cos(funnelSlice.BottomAngle / 2);
            b = h * Math.Sin(funnelSlice.TopAngle / 2);

            points[6] = new Point(points[2].X - a, points[2].Y - b);
            points[7] = new Point(points[3].X + a, points[3].Y - b);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Get side lighting brush for the funnel slice
        /// </summary>
        /// <returns></returns>
        private static Brush GetSideLightingBrush(TriangularChartSliceParms funnelSlice)
        {

             //LinearGradientBrush gb = new LinearGradientBrush() { EndPoint = new Point(1.016, 0.558), StartPoint = new Point(0.075, 0.708) };
             //gb.GradientStops.Add(new GradientStop() { Color = Color.FromArgb(0, 0, 0, 0), Offset = 0.491 });
             //gb.GradientStops.Add(new GradientStop() { Color = Color.FromArgb(135, 8, 8, 8), Offset = 0.938 });
             //gb.GradientStops.Add(new GradientStop() { Color = Color.FromArgb(71, 71, 71, 71), Offset = 0 });

            //LinearGradientBrush gb = new LinearGradientBrush() { EndPoint = new Point(1.016, 0.558),  };
            List<Double> stops = new List<double>();
            List<Color> colors = new List<Color>();
            
            colors.Add(Color.FromArgb(0, 0, 0, 0)); stops.Add(0.491);
            colors.Add(Color.FromArgb(135, 8, 8, 8)); stops.Add(0.938);
            colors.Add(Color.FromArgb(71, 71, 71, 71)); stops.Add(0);
            //Double angle = funnelSlice.BottomAngle * 180 / Math.PI;
            Brush gb = Graphics.CreateLinearGradientBrush(0, new Point(-0.1, 0.5), new Point(1, 0.5), colors, stops);

            return gb;
        }
Ejemplo n.º 6
0
        public static void FixTopAndBottomRadiusForStreamLineFunnel(ref TriangularChartSliceParms funnelSlice)
        {
            if (Double.IsNaN(funnelSlice.TopRadius))
            {
                funnelSlice.TopRadius = 0.00000001;
                funnelSlice.Height = 0;
            }

            if (Double.IsNaN(funnelSlice.BottomRadius))
                funnelSlice.BottomRadius = 0.0000001;

            if (Double.IsNaN(funnelSlice.Height))
                funnelSlice.Height = 0.0000001;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates a LabelLine for Pyramid Chart
        /// </summary>
        /// <param name="pyramidSlice">TriangularChartSliceParms</param>
        /// <param name="topRadius">Top most radius of the pyramid</param>
        /// <param name="animationEnabled">Whether animation is enabled</param>
        /// <returns>Canvas for labelline </returns>
        private static Canvas CreateLabelLine(TriangularChartSliceParms pyramidSlice, Pyramid3DSlice pyramid3DSlice, Double topRadius, Boolean animationEnabled)
        {
            Canvas labelLineCanvas = null;

            Point topRightPoint; 
            Point bottomRightPoint;

            if (pyramid3DSlice == null) // If 2d
            {
                topRightPoint = new Point(topRadius + Math.Abs(pyramidSlice.TopRadius), 0);
                bottomRightPoint = new Point(topRadius + Math.Abs(pyramidSlice.BottomRadius), pyramidSlice.Height);
            }
            else
            {
                topRightPoint = pyramid3DSlice.Top3DLayer.R;
                bottomRightPoint = pyramid3DSlice.Bottom3DLayer.R;
            }

            pyramidSlice.RightMidPoint = Graphics.MidPointOfALine(topRightPoint, bottomRightPoint);

            pyramidSlice.LabelLineEndPoint = new Point(2 * topRadius, pyramidSlice.RightMidPoint.Y);

            pyramidSlice.OrginalLabelLineEndPoint = pyramidSlice.LabelLineEndPoint;

            if ((Boolean)pyramidSlice.DataPoint.LabelLineEnabled && pyramidSlice.DataPoint.LabelStyle == LabelStyles.OutSide)
            {
                labelLineCanvas = new Canvas();

                labelLineCanvas.Width = topRadius * 2;
                labelLineCanvas.Height = pyramidSlice.Height;

                pyramidSlice.DataPoint.LabelLine = null;

                Path line = new Path()
                {
                    Stroke = pyramidSlice.DataPoint.LabelLineColor,
                    Fill = pyramidSlice.DataPoint.LabelLineColor,
                    StrokeDashArray = ExtendedGraphics.GetDashArray((LineStyles)pyramidSlice.DataPoint.LabelLineStyle),
                    StrokeThickness = (Double)pyramidSlice.DataPoint.LabelLineThickness,
                };

                PathGeometry linePathGeometry = new PathGeometry();

                // Set first point of the line
                PathFigure linePathFigure = new PathFigure()
                {
                    StartPoint = pyramidSlice.RightMidPoint
                };

                // Set second point of line
                linePathFigure.Segments.Add(new LineSegment() { Point = pyramidSlice.LabelLineEndPoint });

                linePathGeometry.Figures.Add(linePathFigure);

                line.Data = linePathGeometry;

                pyramidSlice.DataPoint.LabelLine = line;

                labelLineCanvas.Children.Add(line);

                if (animationEnabled)
                    pyramidSlice.DataPoint.Parent.Storyboard = ApplyLabeLineAnimation(labelLineCanvas, pyramidSlice.DataPoint.Parent, pyramidSlice.DataPoint.Parent.Storyboard);
            }

            return labelLineCanvas;
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Get new Brush for Bevel
 /// </summary>
 /// <param name="bevelSideName"></param>
 /// <param name="fullBrush"></param>
 /// <returns></returns>
 /// 
 internal static void ReCalculateAndApplyTheNewBrush(Shape shape, Brush newBrush, Boolean isLightingEnabled, Boolean is3D, TriangularChartSliceParms funnelSliceParms)
 {
     switch ((shape.Tag as ElementData).VisualElementName)
     {
         case "FunnelBase":
         case "FunnelTop": shape.Fill = newBrush; shape.Stroke = newBrush; break;
         case "TopBevel": shape.Fill = Graphics.GetBevelTopBrush(newBrush, 90); break;
         case "LeftBevel": shape.Fill = Graphics.GetBevelSideBrush(45, newBrush); break;
         case "RightBevel": shape.Fill = Graphics.GetBevelSideBrush(45, newBrush); break;
         case "BottomBevel": shape.Fill = Graphics.GetBevelSideBrush(180, newBrush); break;
         case "Lighting": shape.Fill = isLightingEnabled ? GetSideLightingBrush(funnelSliceParms) : newBrush; break;
         case "FunnelTopLighting":
             shape.Fill = is3D ? GetTopBrush(newBrush, funnelSliceParms) : newBrush;
             shape.Stroke = GetLightingBrushForStroke(newBrush, funnelSliceParms.Index);
             break;
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Apply Bevel effect for a funnel slice
        /// </summary>
        /// <param name="parentVisual">Parent canvas of Bevel layer</param>
        /// <param name="funnelSlice">funnelSlice</param>
        /// <param name="sideFillColor">Side fill color</param>
        /// <param name="points">Funnel Points</param>
        private static void ApplyFunnelBevel(Canvas parentVisual, TriangularChartSliceParms funnelSlice, Brush sideFillColor, Point[] points)
        {
            if (funnelSlice.DataPoint.Parent.Bevel && funnelSlice.Height > Chart.BEVEL_DEPTH)
            {
                // Generate Inner Points
                CalculateBevelInnerPoints(funnelSlice, points);

                Path topBevelPath = ExtendedGraphics.GetPathFromPoints(Graphics.GetBevelTopBrush(sideFillColor, 90), points[0], points[4], points[5], points[1]);
                Path leftBevelPath = ExtendedGraphics.GetPathFromPoints(Graphics.GetBevelSideBrush(45, sideFillColor), points[0], points[4], points[7], points[3]);
                Path rightBevelPath = ExtendedGraphics.GetPathFromPoints(Graphics.GetBevelSideBrush(45, sideFillColor), points[1], points[5], points[6], points[2]);
                Path bottomBevelPath = ExtendedGraphics.GetPathFromPoints(Graphics.GetBevelSideBrush(180, sideFillColor), points[7], points[6], points[2], points[3]);

                topBevelPath.IsHitTestVisible = false;
                leftBevelPath.IsHitTestVisible = false;
                rightBevelPath.IsHitTestVisible = false;
                bottomBevelPath.IsHitTestVisible = false;

                parentVisual.Children.Add(topBevelPath);
                parentVisual.Children.Add(leftBevelPath);
                parentVisual.Children.Add(rightBevelPath);
                parentVisual.Children.Add(bottomBevelPath);

                topBevelPath.Tag = new ElementData() { Element = funnelSlice.DataPoint, VisualElementName = "TopBevel" };
                leftBevelPath.Tag = new ElementData() { Element = funnelSlice.DataPoint, VisualElementName = "LeftBevel" };
                rightBevelPath.Tag = new ElementData() { Element = funnelSlice.DataPoint, VisualElementName = "RightBevel" };
                bottomBevelPath.Tag = new ElementData() { Element = funnelSlice.DataPoint, VisualElementName = "BottomBevel" };

                funnelSlice.DataPoint.Faces.Parts.Add(topBevelPath);
                funnelSlice.DataPoint.Faces.Parts.Add(leftBevelPath);
                funnelSlice.DataPoint.Faces.Parts.Add(rightBevelPath);
                funnelSlice.DataPoint.Faces.Parts.Add(bottomBevelPath);

                funnelSlice.DataPoint.Faces.VisualComponents.Add(topBevelPath);
                funnelSlice.DataPoint.Faces.VisualComponents.Add(leftBevelPath);
                funnelSlice.DataPoint.Faces.VisualComponents.Add(rightBevelPath);
                funnelSlice.DataPoint.Faces.VisualComponents.Add(bottomBevelPath);

                if ((funnelSlice.DataPoint.Chart as Chart).InternalAnimationEnabled)
                {
                    funnelSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(topBevelPath, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard, 0, funnelSlice.DataPoint.InternalOpacity, 0, 1);
                    funnelSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(leftBevelPath, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard, 0, funnelSlice.DataPoint.InternalOpacity, 0, 1);
                    funnelSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(rightBevelPath, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard, 0, funnelSlice.DataPoint.InternalOpacity, 0, 1);
                    funnelSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(bottomBevelPath, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard, 0, funnelSlice.DataPoint.InternalOpacity, 0, 1);
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Calculate pyramidSliceParms information
        /// </summary>
        /// <param name="dataSeries">DataSeries reference</param>
        /// <param name="dataPoints">List of sorted reference(If required)</param>
        /// <param name="plotHeight">Total height of the plot canvas</param>
        /// <param name="plotWidth">Total width of the plot canvas</param>
        /// <param name="minPointHeight">Min height of a pyramid slice</param>
        /// <param name="is3D">Whether chart is a 3D chart</param>
        /// <param name="yScale">YScale of the chart</param>
        /// <param name="gapRatio">Gap between two data points while a particular datapoint is Exploded</param>
        /// <param name="isSameSlantAngle">Whether the same slant angle to be used while drawing each slice</param>
        /// <param name="bottomRadius">Bottom most raduis of a pyramid</param>
        /// <returns>TriangularChartSliceParms[]</returns>
        private static TriangularChartSliceParms[] CalculatePyramidSliceParmsInfo(DataSeries dataSeries, List<DataPoint> dataPoints, Double plotHeight, Double plotWidth, Double minPointHeight, Boolean is3D, Double yScale, Double gapRatio, Boolean isSameSlantAngle, Double bottomRadius)
        {
            // Initialize pyramid Slices parameters
            TriangularChartSliceParms[] pyramidSlicesParms;

            // Actual pyramid height
            // For 3d pyramid height will be reduced to maintain yScale
            Double pyramidHeight;

            plotHeight = Math.Max(plotHeight, 0);
            plotWidth = Math.Max(plotWidth, 0);

            if (dataSeries.Exploded)
            {
                gapRatio = 0.02;

                // Single gap height
                _singleGap = gapRatio * plotHeight;

                _totalGap = _singleGap * (dataPoints.Count + 1);
            }
            else
            {
                // Single gap height
                _singleGap = gapRatio * plotHeight;

                _totalGap = _singleGap * 2;
            }

            // Actual pyramid height
            // For 3d pyramid height will be reduced to maintain yScale
            pyramidHeight = plotHeight - _totalGap -(is3D ? yScale / 3 : 0) - (is3D ? plotHeight * 0.05:0);

            #region Sectional Pyramid

            // Initialization of pyramidSliceParms
            pyramidSlicesParms = new TriangularChartSliceParms[dataPoints.Count];

            // Calculate sum of values
            Double sum = (from dp in dataPoints select dp.YValue).Sum();

            // Min YValue
            Double min = (from dp in dataPoints select dp.YValue).Min();

            // Pyramid angle
            Double theta = Math.Atan((plotWidth / 2 - bottomRadius) / pyramidHeight);

            // Height of the pyramid drawn considering bottom radius
            pyramidHeight -= Math.Tan(theta) / ((bottomRadius == 0) ? 1 : bottomRadius);

            // Creating prams for each pyramid slice
            for (Int32 index = 0; index < dataPoints.Count; index++)
            {
                pyramidSlicesParms[index] = new TriangularChartSliceParms() { DataPoint = dataPoints[index], TopAngle = Math.PI / 2 - theta, BottomAngle = Math.PI / 2 + theta };

                pyramidSlicesParms[index].Height = pyramidHeight * (dataPoints[index].YValue / sum);
                pyramidSlicesParms[index].TopRadius = index == 0 ? 0 : pyramidSlicesParms[index - 1].BottomRadius;
                pyramidSlicesParms[index].BottomRadius = pyramidSlicesParms[index].TopRadius - pyramidSlicesParms[index].Height * Math.Tan(theta);


                pyramidSlicesParms[index].TopGap = 0; // ((index == 0 && is3D) ? yScale / 2 : 0);

            }

            if (!Double.IsNaN(minPointHeight))
            {
                Boolean isFixedSize = false;    // Whether to fix height of all slice
                Double fixedSliceHeight = 0;

                Double totalSumOfHeight = (from pyramidSlice in pyramidSlicesParms select pyramidSlice.Height).Sum();
                fixedSliceHeight = totalSumOfHeight / pyramidSlicesParms.Length;

                // Calculate minPointHeight in terms of pixel value
                minPointHeight = (minPointHeight / 100) * pyramidHeight;

                // Pyramid slices where height is less than the minPointHeight
                List<TriangularChartSliceParms> fixedHeightPyramidSlices = (from pyramidSlice in pyramidSlicesParms where pyramidSlice.Height < minPointHeight select pyramidSlice).ToList();

                List<TriangularChartSliceParms> variableHeightPyramidSlices = (from pyramidSlice in pyramidSlicesParms
                                                                     where !(from slice in fixedHeightPyramidSlices select slice).Contains(pyramidSlice)
                                                                     select pyramidSlice).ToList();

                if (minPointHeight > fixedSliceHeight || fixedHeightPyramidSlices.Count == pyramidSlicesParms.Count())
                {
                    isFixedSize = true;
                }

                Double sumOfHeightOfSlice2BeFixed = (from pyramidSlice in fixedHeightPyramidSlices select pyramidSlice.Height).Sum();
                Double sumOfVariableHeightSlices = (from pyramidSlice in variableHeightPyramidSlices select pyramidSlice.Height).Sum();

                Double totalHeight2Reduce = minPointHeight * fixedHeightPyramidSlices.Count() - sumOfHeightOfSlice2BeFixed;

                // Creating prams for each pyramid slice
                for (Int32 index = 0; index < dataPoints.Count; index++)
                {
                    if (isFixedSize)
                    {
                        pyramidSlicesParms[index].Height = fixedSliceHeight;
                    }
                    else
                    {
                        if (pyramidSlicesParms[index].Height < minPointHeight)
                            pyramidSlicesParms[index].Height = minPointHeight;
                        else
                            pyramidSlicesParms[index].Height -= totalHeight2Reduce * (pyramidSlicesParms[index].Height / sumOfVariableHeightSlices);
                    }

                    pyramidSlicesParms[index].TopRadius = index == 0 ? 0 : pyramidSlicesParms[index - 1].BottomRadius;
                    pyramidSlicesParms[index].BottomRadius = pyramidSlicesParms[index].TopRadius - pyramidSlicesParms[index].Height * Math.Tan(theta);

                    // Set topgap and bottom gap
                    /*if (index == 0 || (Boolean)pyramidSlicesParms[index].DataPoint.Exploded)
                        pyramidSlicesParms[index].TopGap = _singleGap + ((index == 0 && is3D) ? yScale / 2 : 0);
                        
                    if(index == dataPoints.Count -1 || (Boolean) pyramidSlicesParms[index].DataPoint.Exploded)
                        pyramidSlicesParms[index].BottomGap = _singleGap;
                     */
                }
            }

            #endregion

            return pyramidSlicesParms;
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Get new Brush for Bevel
 /// </summary>
 /// <param name="bevelSideName"></param>
 /// <param name="fullBrush"></param>
 /// <returns></returns>
 /// 
 internal static void ReCalculateAndApplyTheNewBrush(Shape shape, Brush newBrush, Boolean isLightingEnabled, Boolean is3D, TriangularChartSliceParms pyramidSliceParms)
 {
     if (is3D)
     {
         Path path = shape as Path; 
         Pyramid3DSlice.ApplyColor(ref path, (Pyramid3dLayer)Enum.Parse(typeof(Pyramid3dLayer), (shape.Tag as ElementData).VisualElementName, true)
             , newBrush
             , isLightingEnabled
             , pyramidSliceParms.Index == 0);
     }
     else
     {   
         switch ((shape.Tag as ElementData).VisualElementName)
         {
         case "PyramidBase":
         case "FunnelTop": shape.Fill = newBrush; shape.Stroke = newBrush; break;
         case "TopBevel": shape.Fill = Graphics.GetBevelTopBrush(newBrush, 90); break;
         case "LeftBevel": shape.Fill = Graphics.GetBevelSideBrush(45, newBrush); break;
         case "RightBevel": shape.Fill = Graphics.GetBevelSideBrush(45, newBrush); break;
         case "BottomBevel": shape.Fill = Graphics.GetBevelSideBrush(180, newBrush); break;
         case "Lighting": shape.Fill = isLightingEnabled ? GetSideLightingBrush(pyramidSliceParms) : newBrush; break;
         case "FunnelTopLighting":
             shape.Fill = is3D ? GetTopBrush(newBrush, pyramidSliceParms) : newBrush;
             shape.Stroke = GetLightingBrushForStroke(newBrush, pyramidSliceParms.Index);
             break;
         }
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Get top lighting brush for pyramid slice
        /// </summary>
        /// <param name="fillBrush">Current brush</param>
        /// <returns>Return new Brush</returns>
        private static Brush GetTopBrush(Brush fillBrush, TriangularChartSliceParms pyramidSlice)
        {
            if ((fillBrush as SolidColorBrush) != null)
            {
                SolidColorBrush solidBrush = fillBrush as SolidColorBrush;
                
                Double r = ((double)solidBrush.Color.R / (double)255) * 0.9999;
                Double g = ((double)solidBrush.Color.G / (double)255) * 0.9999;
                Double b = ((double)solidBrush.Color.B / (double)255) * 0.9999;

                LinearGradientBrush gb = null;

                if (pyramidSlice.FillType == FillType.Solid)
                {
                    gb = new LinearGradientBrush() { StartPoint = new Point(0, 0), EndPoint = new Point(1, 1) };
                    gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetLighterColor(solidBrush.Color, 1 - r, 1 - g, 1 - b), Offset = 0 });
                    gb.GradientStops.Add(new GradientStop() { Color = solidBrush.Color, Offset = 0.9 });
                    gb.GradientStops.Add(new GradientStop() { Color = Graphics.GetDarkerColor(solidBrush.Color, 1), Offset = 0.99 });
                    gb.Opacity = 1;

                }
                else if (pyramidSlice.FillType == FillType.Hollow)
                {   
                    gb = new LinearGradientBrush()
                    {
                        StartPoint = new Point(0.233, 0.297),
                        EndPoint = new Point(0.757, 0.495)
                    };

                    gb.GradientStops.Add(new GradientStop() { Offset = 0, Color = Graphics.GetDarkerColor(solidBrush.Color, 0.5) });
                    gb.GradientStops.Add(new GradientStop() { Offset = 0.70, Color = solidBrush.Color });
                    gb.GradientStops.Add(new GradientStop() { Offset = 1, Color = Graphics.GetDarkerColor(solidBrush.Color, 0.8)});
                }

                return gb;
            }
            else
                return fillBrush;
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Get side lighting brush for the pyramid slice
        /// </summary>
        /// <returns></returns>
        private static Brush GetSideLightingBrush(TriangularChartSliceParms pyramidSlice)
        {
            //LinearGradientBrush gb = new LinearGradientBrush() { EndPoint = new Point(1.016, 0.558),  };
            List<Double> stops = new List<double>();
            List<Color> colors = new List<Color>();
            
            colors.Add(Color.FromArgb(0, 0, 0, 0)); stops.Add(0.491);
            colors.Add(Color.FromArgb(135, 8, 8, 8)); stops.Add(0.938);
            colors.Add(Color.FromArgb(71, 71, 71, 71)); stops.Add(0);
            //Double angle = pyramidSlice.BottomAngle * 180 / Math.PI;
            Brush gb = Graphics.CreateLinearGradientBrush(0, new Point(-0.1, 0.5), new Point(1, 0.5), colors, stops);

            return gb;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Calculate Bevel innter points
        /// </summary>
        /// <param name="pyramidSlice">pyramidSlice</param>
        /// <param name="points">Array of points</param>
        private static void CalculateBevelInnerPoints(TriangularChartSliceParms pyramidSlice, Point[] points, Boolean isTopOfPyramid)
        {
            Double a, b, bevelHeight = 3;

            a = bevelHeight * Math.Sin(pyramidSlice.TopAngle / 2);
            b = bevelHeight * Math.Cos(pyramidSlice.TopAngle / 2);

            if (isTopOfPyramid)
            {
                points[4] = new Point(points[0].X, points[0].Y + bevelHeight);
                points[5] = new Point(points[1].X, points[1].Y + bevelHeight);
            }
            else
            {
                points[4] = new Point(points[0].X - a, bevelHeight);
                points[5] = new Point(points[1].X + a, bevelHeight);
            }

             //b = h * Math.Cos(Math.PI /2 - pyramidSlice.BottomAngle / 2);
            b = bevelHeight * Math.Tan(pyramidSlice.BottomAngle / 2);

            bevelHeight = 2;

            points[6] = new Point(points[2].X + b, points[2].Y - bevelHeight);
            points[7] = new Point(points[3].X - b, points[3].Y - bevelHeight);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Calculates Exploded DataPoint Positions
        /// </summary>
        /// <param name="funnelSlices"></param>
        private static void CalcutateExplodedPosition(ref TriangularChartSliceParms[] funnelSlices, Boolean isStreamLine, Double yScale, DataSeries dataSeries)
        {
            Int32 sliceCount = funnelSlices.Count();
            Int32 index = 0;

            if (funnelSlices[0].DataPoint.Parent.Exploded)
            {
                if (!funnelSlices[0].DataPoint.Chart.IsInDesignMode)
                {
                    Int32 midIndex = sliceCount / 2;
                    Double beginTime = 0.4;

                    if ((dataSeries.Chart as Chart).ChartArea._isFirstTimeRender)
                        beginTime = 1;

                    for (index = midIndex; index >= 0; index--)
                    {
                        if (index < 0)
                            break;

                        Double yPosition = funnelSlices[index].Top - (midIndex - index) * _singleGap;// -yScale / 2;
                        dataSeries.Storyboard = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, dataSeries.Storyboard, funnelSlices[index].DataPoint.Faces.Visual as Panel, yPosition, beginTime);
                    }

                    for (index = midIndex + 1; index < sliceCount; index++)
                    {
                        Double yPosition = funnelSlices[index].Top + (index - midIndex) * _singleGap;// -yScale / 2;
                        dataSeries.Storyboard = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, dataSeries.Storyboard, funnelSlices[index].DataPoint.Faces.Visual as Panel, yPosition, beginTime);
                    }

                    if (dataSeries.Storyboard != null)
                    {
                        if (dataSeries.Chart != null && !(dataSeries.Chart as Chart).ChartArea._isFirstTimeRender)
#if WPF
                        dataSeries.Storyboard.Begin(dataSeries.Chart._rootElement, true);
#else
                            dataSeries.Storyboard.Stop();
                        dataSeries.Storyboard.Begin();
#endif
                    }
                }
            }
            else
            {
                Storyboard unExplodeStoryBoard = new Storyboard();

                for (; index < sliceCount; index++)
                {
                    funnelSlices[index].ExplodedPoints = new List<Point>();
                    funnelSlices[index].DataPoint.ExplodeAnimation = new Storyboard();
                    // For top slice
                    if (index == 0)
                    {
                        funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[index].Top - _singleGap / 2));

                        funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[index].DataPoint.ExplodeAnimation, funnelSlices[index].DataPoint.Faces.Visual as Panel, (funnelSlices[index].Top - _singleGap / 2), 0);
                        //unExplodeStoryBoard = CreateExplodingAnimation(unExplodeStoryBoard, funnelSlices[index].DataPoint.Faces.Visual as Panel, funnelSlices[index].Top);

                        for (Int32 i = 1; i < funnelSlices.Length; i++)
                        {
                            funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[i].Top + _singleGap / 2));
                            funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[index].DataPoint.ExplodeAnimation, funnelSlices[i].DataPoint.Faces.Visual as Panel, (funnelSlices[i].Top + _singleGap / 2), 0);
                            //unExplodeStoryBoard = CreateExplodingAnimation(unExplodeStoryBoard, funnelSlices[i].DataPoint.Faces.Visual as Panel, funnelSlices[i].Top);
                        }

                    }
                    // For bottom slice
                    else if (index == funnelSlices.Length - 1)
                    {
                        Int32 i = 0;

                        for (; i < index; i++)
                        {
                            funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[i].Top - _singleGap / 2 + _singleGap / 6));
                            funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[index].DataPoint.ExplodeAnimation, funnelSlices[i].DataPoint.Faces.Visual as Panel, (funnelSlices[i].Top - _singleGap / 2 + _singleGap / 6), 0);
                        }

                        funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[i].Top + _singleGap / 2 + _singleGap / 6));
                        funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[i].DataPoint.ExplodeAnimation, funnelSlices[i].DataPoint.Faces.Visual as Panel, (funnelSlices[i].Top + _singleGap / 2 + _singleGap / 6), 0);
                    }
                    // For other slice
                    else
                    {
                        Int32 i;

                        for (i = 0; i < index; i++)
                        {
                            funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[i].Top - _singleGap / 2));
                            funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[index].DataPoint.ExplodeAnimation, funnelSlices[i].DataPoint.Faces.Visual as Panel, (funnelSlices[i].Top - _singleGap / 2), 0);
                        }

                        funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[i].Top));
                        funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[index].DataPoint.ExplodeAnimation, funnelSlices[index].DataPoint.Faces.Visual as Panel, funnelSlices[index].Top, 0);

                        for (++i; i < funnelSlices.Length; i++)
                        {
                            funnelSlices[index].ExplodedPoints.Add(new Point(0, funnelSlices[i].Top + _singleGap / 2));
                            funnelSlices[index].DataPoint.ExplodeAnimation = CreateExplodingAnimation(dataSeries, funnelSlices[index].DataPoint, funnelSlices[index].DataPoint.ExplodeAnimation, funnelSlices[i].DataPoint.Faces.Visual as Panel, (funnelSlices[i].Top + _singleGap / 2), 0);
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Create a slice of a funnel
        /// </summary>
        /// <param name="isLightingGradientLayer">Whether CreateFunnelSlice() function should create a layer for lighting</param>
        /// <param name="topRadius">Top Radius of the funnel</param>
        /// <param name="is3D">Whether the chart is a 3D Chart</param>
        /// <param name="funnelSlice">FunnelSlice 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 funnel slice canvas</returns>
        private static Canvas CreateFunnelSlice(Boolean isLightingGradientLayer, Double topRadius, Boolean is3D, TriangularChartSliceParms funnelSlice, Double yScaleTop, Double yScaleBottom, Brush sideFillColor, Brush topFillColor, Brush topSurfaceStroke, Boolean animationEnabled)
        {
            Double SOLID_FUNNEL_EDGE_THICKNESS = 3;

            if (funnelSlice.Index == 0 && is3D && isLightingGradientLayer && (funnelSlice.FillType == FillType.Solid))
            {   
                funnelSlice.Height += SOLID_FUNNEL_EDGE_THICKNESS;
            }

            Canvas sliceCanvas = new Canvas() { Tag = new ElementData() { Element = funnelSlice.DataPoint } };
            Canvas visual = new Canvas() { Width = topRadius * 2, Height = funnelSlice.Height, Tag = new ElementData() { Element = funnelSlice.DataPoint } };  // Canvas holds a slice of a funnel chart
            Faces faces = null;


            // GeometryGroup for for a funnel slice path
            GeometryGroup geometryGroup = new GeometryGroup();

            // PathGeometry for for a funnel slice path
            PathGeometry pathGeometry = new PathGeometry();

            // pathFigure for for a funnel slice path
            PathFigure pathFigure = new PathFigure() { StartPoint = new Point(topRadius - funnelSlice.TopRadius, 0) };  // PathFigure of a funnel slice


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

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

            // Add PathGeometry to GeometryGroup
            geometryGroup.Children.Add(pathGeometry);

            // Set path data
            path4Slice.Data = geometryGroup;

            // 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);
            
            if (is3D)
            {
                
                #region 3D

                geometryGroup.FillRule = FillRule.Nonzero;

                // Create top arc left
                ArcSegment arcSegment = new ArcSegment();
                arcSegment.Point = new Point(topRadius, yScaleTop / 2);
                arcSegment.Size = new Size(funnelSlice.TopRadius, yScaleTop / 2);
                pathFigure.Segments.Add(arcSegment);

                // Create top arc right
                arcSegment = new ArcSegment();
                arcSegment.Point = new Point(topRadius + funnelSlice.TopRadius, 0);
                arcSegment.Size = new Size(funnelSlice.TopRadius, yScaleTop / 2);
                pathFigure.Segments.Add(arcSegment);

                // Create right Plain
                LineSegment lineSegment = new LineSegment() { Point = new Point(topRadius + funnelSlice.BottomRadius, funnelSlice.Height) };
                pathFigure.Segments.Add(lineSegment);

                lineSegment = new LineSegment() { Point = new Point(topRadius - funnelSlice.BottomRadius, funnelSlice.Height) };
                pathFigure.Segments.Add(lineSegment);

                // Create left Plain
                lineSegment = new LineSegment() { Point = new Point(topRadius - funnelSlice.TopRadius, 0) };
                pathFigure.Segments.Add(lineSegment);

                EllipseGeometry ellipseGeometry = new EllipseGeometry();
                ellipseGeometry.Center = new Point(topRadius, funnelSlice.Height);
                ellipseGeometry.RadiusX = funnelSlice.BottomRadius;
                ellipseGeometry.RadiusY = yScaleBottom / 2;

                geometryGroup.Children.Add(ellipseGeometry);

                // Create ellips for the funnel top
                Ellipse funnelTopEllipse = new Ellipse() { Height = yScaleTop, Width = funnelSlice.TopRadius * 2, Fill = topFillColor, Tag = new ElementData() { Element = funnelSlice.DataPoint } };

                funnelTopEllipse.SetValue(Canvas.TopProperty, -yScaleTop / 2);
                funnelTopEllipse.SetValue(Canvas.LeftProperty, topRadius - funnelSlice.TopRadius);

                //if (funnelSlice.DataPoint.Parent.Bevel)
                    funnelTopEllipse.StrokeThickness = 1.24;
                //else
                //    funnelTopEllipse.StrokeThickness = 0.24;

                funnelTopEllipse.Stroke = Graphics.GetBevelTopBrush(topSurfaceStroke, 0);

                visual.Children.Add(funnelTopEllipse);

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

                    (path4Slice.Tag as ElementData).VisualElementName = "FunnelBase";
                    (funnelTopEllipse.Tag as ElementData).VisualElementName = "FunnelTop";

                    #region Creating Seperate BorderLine

                    GeometryGroup borderGeometryGroup = new GeometryGroup();

                    // PathGeometry for for a funnel slice path
                    PathGeometry leftRightBorderPathGeometry = new PathGeometry();

                    // LeftLine Border
                    PathFigure leftBorderPathFigure = new PathFigure() { StartPoint = pathFigure.StartPoint };
                    LineSegment leftBorderLineSegment = new LineSegment() { Point = new Point(topRadius - funnelSlice.BottomRadius, funnelSlice.Height) };
                    leftBorderPathFigure.Segments.Add(leftBorderLineSegment);

                    leftRightBorderPathGeometry.Figures.Add(leftBorderPathFigure);

                    // RightLine Border
                    PathGeometry rightRightBorderPathGeometry = new PathGeometry();
                    PathFigure rightBorderPathFigure = new PathFigure() { StartPoint = new Point(topRadius + funnelSlice.TopRadius, 0) };
                    LineSegment rightBorderLineSegment = new LineSegment() { Point = new Point(topRadius + funnelSlice.BottomRadius, funnelSlice.Height) };
                    rightBorderPathFigure.Segments.Add(rightBorderLineSegment);

                    rightRightBorderPathGeometry.Figures.Add(rightBorderPathFigure);

                    // Bottom _axisIndicatorBorderElement Ellipse
                    EllipseGeometry ellipseGeometryBorder = new EllipseGeometry();
                    ellipseGeometryBorder.Center = new Point(topRadius, funnelSlice.Height);
                    ellipseGeometryBorder.RadiusX = funnelSlice.BottomRadius;
                    ellipseGeometryBorder.RadiusY = yScaleBottom / 2;

                    borderGeometryGroup.Children.Add(ellipseGeometryBorder);

                    // Bottom _axisIndicatorBorderElement Ellipse
                    ellipseGeometryBorder = new EllipseGeometry();
                    ellipseGeometryBorder.Center = new Point(topRadius, 0);
                    ellipseGeometryBorder.RadiusX = funnelSlice.TopRadius;
                    ellipseGeometryBorder.RadiusY = yScaleTop / 2;

                    borderGeometryGroup.Children.Add(ellipseGeometryBorder);
                    borderGeometryGroup.Children.Add(leftRightBorderPathGeometry);
                    borderGeometryGroup.Children.Add(rightRightBorderPathGeometry);

                    Path borderPath = new Path() { Data = borderGeometryGroup, IsHitTestVisible = false };
                    borderPath.SetValue(Canvas.ZIndexProperty, (Int32)(-1));

                    visual.Children.Add(borderPath);
                    faces.BorderElements.Add(borderPath);
                    faces.BorderElements.Add(funnelTopEllipse);

                    #endregion
                    faces.Parts.Add(path4Slice);
                    faces.Parts.Add(funnelTopEllipse);
                    funnelSlice.DataPoint.Faces = faces;
                }
                else
                {
                    if (funnelSlice.FillType == FillType.Solid && funnelSlice.Index == 0)
                    {
                        path4Slice.SetValue(Canvas.ZIndexProperty, 1);
                        path4Slice.SetValue(Canvas.TopProperty, (-SOLID_FUNNEL_EDGE_THICKNESS));
                        funnelSlice.Height -= SOLID_FUNNEL_EDGE_THICKNESS;
                    }

                    path4Slice.IsHitTestVisible = false;
                    funnelTopEllipse.IsHitTestVisible = false;
                    funnelSlice.DataPoint.Faces.Parts.Add(path4Slice);
                    funnelSlice.DataPoint.Faces.Parts.Add(funnelTopEllipse);
                    funnelSlice.DataPoint.Faces.VisualComponents.Add(path4Slice);
                    funnelSlice.DataPoint.Faces.VisualComponents.Add(funnelTopEllipse);
                    (path4Slice.Tag as ElementData).VisualElementName = "Lighting";
                    (funnelTopEllipse.Tag as ElementData).VisualElementName = "FunnelTopLighting";
                }

                // Apply animation for the 3D funnel slice
                if (animationEnabled)
                {
                    funnelSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(funnelTopEllipse, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard, 0, funnelSlice.DataPoint.InternalOpacity, 0, 1);
                    funnelSlice.DataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(path4Slice, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard, 0, funnelSlice.DataPoint.InternalOpacity, 0, 1);
                }

                #endregion
            }
            else
            {   
                // Points of a 2D funnel slice
                Point[] funnelCornerPoints = new Point[8];

                // Top line
                LineSegment lineSegment = new LineSegment() { Point = new Point(topRadius - funnelSlice.BottomRadius, funnelSlice.Height) };
                pathFigure.Segments.Add(lineSegment);
                funnelCornerPoints[3] = lineSegment.Point;

                // Right line
                lineSegment = new LineSegment() { Point = new Point(topRadius + funnelSlice.BottomRadius, funnelSlice.Height) };
                pathFigure.Segments.Add(lineSegment);
                funnelCornerPoints[2] = lineSegment.Point;

                // Bottom line
                lineSegment = new LineSegment() { Point = new Point(topRadius + funnelSlice.TopRadius, 0) };
                pathFigure.Segments.Add(lineSegment);
                funnelCornerPoints[1] = lineSegment.Point;

                // Left line
                lineSegment = new LineSegment() { Point = new Point(topRadius - funnelSlice.TopRadius, 0) };
                pathFigure.Segments.Add(lineSegment);
                funnelCornerPoints[0] = lineSegment.Point;

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

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

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

                    faces.BorderElements.Add(path4Slice);
                    funnelSlice.DataPoint.Faces = faces;

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

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

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

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

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

                    // Label placement
                    funnelSlice.DataPoint.LabelVisual.SetValue(Canvas.TopProperty, funnelSlice.LabelLineEndPoint.Y - funnelSlice.DataPoint.LabelVisual.Height / 2);

                    if (funnelSlice.DataPoint.LabelStyle == LabelStyles.OutSide)
                    {
                        funnelSlice.DataPoint.LabelVisual.SetValue(Canvas.TopProperty, funnelSlice.LabelLineEndPoint.Y - funnelSlice.DataPoint.LabelVisual.Height / 2);
                        funnelSlice.DataPoint.LabelVisual.SetValue(Canvas.LeftProperty, funnelSlice.LabelLineEndPoint.X);
                    }
                    else
                    {
                        funnelSlice.DataPoint.LabelVisual.SetValue(Canvas.TopProperty, funnelSlice.LabelLineEndPoint.Y - funnelSlice.DataPoint.LabelVisual.Height / 2 + (is3D ? yScaleTop / 2 : 0));
                        funnelSlice.DataPoint.LabelVisual.SetValue(Canvas.LeftProperty, topRadius - funnelSlice.DataPoint.LabelVisual.Width / 2);
                    }

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

                    labelCanvas.Children.Add(funnelSlice.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;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Calculate funnelSliceParms information
        /// </summary>
        /// <param name="isStreamLine">Whether its a streamline funnel chart</param>
        /// <param name="dataSeries">DataSeries reference</param>
        /// <param name="dataPoints">List of sorted reference(If required)</param>
        /// <param name="plotHeight">Total height of the plot canvas</param>
        /// <param name="plotWidth">Total width of the plot canvas</param>
        /// <param name="minPointHeight">Min height of a funnel slice</param>
        /// <param name="is3D">Whether chart is a 3D chart</param>
        /// <param name="yScale">YScale of the chart</param>
        /// <param name="gapRatio">Gap between two data points while a particular datapoint is Exploded</param>
        /// <param name="isSameSlantAngle">Whether the same slant angle to be used while drawing each slice</param>
        /// <param name="bottomRadius">Bottom most raduis of a funnel</param>
        /// <returns>TriangularChartSliceParms[]</returns>
        private static TriangularChartSliceParms[] CalculateFunnelSliceParmsInfo(Boolean isStreamLine, DataSeries dataSeries, List<DataPoint> dataPoints, Double plotHeight, Double plotWidth, Double minPointHeight, Boolean is3D, Double yScale, Double gapRatio, Boolean isSameSlantAngle, Double bottomRadius)
        {
            // Initialize funnel Slices parameters
            TriangularChartSliceParms[] funnelSlicesParms;

            // Actual funnel height
            // For 3d funnel height will be reduced to maintain yScale
            Double funnelHeight;

            plotHeight = Math.Max(plotHeight, 0);
            plotWidth = Math.Max(plotWidth, 0);

            if (dataSeries.Exploded)
            {
                gapRatio = 0.02;

                // Single gap height
                _singleGap = gapRatio * plotHeight;

                _totalGap = _singleGap * ((isStreamLine) ? dataPoints.Count : (dataPoints.Count + 1));
            }
            else
            {
                // Single gap height
                _singleGap = gapRatio * plotHeight;

                _totalGap = _singleGap * 2;
            }

            // Actual funnel height
            // For 3d funnel height will be reduced to maintain yScale
            funnelHeight = plotHeight - _totalGap - (is3D ? yScale / 2 : 0);

            if (!isStreamLine)
            {
                #region Sectional Funnel

                // Initialization of funnelSliceParms
                funnelSlicesParms = new TriangularChartSliceParms[dataPoints.Count];

                // Calculate sum of values
                Double sum = (from dp in dataPoints select dp.YValue).Sum();

                // Min YValue
                Double min = (from dp in dataPoints select dp.YValue).Min();

                // Funnel angle
                Double theta = Math.Atan((plotWidth / 2 - bottomRadius) / funnelHeight);

                // Height of the funnel drawn considering bottom radius
                funnelHeight -= Math.Tan(theta) / ((bottomRadius == 0) ? 1 : bottomRadius);

                // Creating prams for each funnel slice
                for (Int32 index = 0; index < dataPoints.Count; index++)
                {
                    funnelSlicesParms[index] = new TriangularChartSliceParms() { DataPoint = dataPoints[index], TopAngle = Math.PI / 2 - theta, BottomAngle = Math.PI / 2 + theta };

                    funnelSlicesParms[index].Height = funnelHeight * (dataPoints[index].YValue / sum);
                    funnelSlicesParms[index].TopRadius = index == 0 ? plotWidth / 2 : funnelSlicesParms[index - 1].BottomRadius;
                    funnelSlicesParms[index].BottomRadius = funnelSlicesParms[index].TopRadius - funnelSlicesParms[index].Height * Math.Tan(theta);
                    /*
                    // Set topgap and bottom gap
                    if (index == 0)
                        funnelSlicesParms[index].TopGap = singleGap + ((index == 0 && is3D) ? yScale / 2 : 0);
                    else if ((Boolean)funnelSlicesParms[index].DataPoint.Exploded)
                        funnelSlicesParms[index].TopGap = singleGap + ((index == 0 && is3D) ? yScale / 2 : 0);

                    if (index == dataPoints.Count - 1)
                        funnelSlicesParms[index].BottomGap = singleGap;
                    else if ((Boolean)funnelSlicesParms[index].DataPoint.Exploded)
                        funnelSlicesParms[index].BottomGap = singleGap;*/

                    //--------------
                    funnelSlicesParms[index].TopGap = ((index == 0 && is3D) ? yScale / 2 : 0);
                    //--------------

                }

                if (!Double.IsNaN(minPointHeight))
                {
                    Boolean isFixedSize = false;    // Whether to fix height of all slice
                    Double fixedSliceHeight = 0;

                    Double totalSumOfHeight = (from funnelSlice in funnelSlicesParms select funnelSlice.Height).Sum();
                    fixedSliceHeight = totalSumOfHeight / funnelSlicesParms.Length;

                    // Calculate minPointHeight in terms of pixel value
                    minPointHeight = (minPointHeight / 100) * funnelHeight;

                    // Funnel slices where height is less than the minPointHeight
                    List<TriangularChartSliceParms> fixedHeightFunnelSlices = (from funnelSlice in funnelSlicesParms where funnelSlice.Height < minPointHeight select funnelSlice).ToList();

                    List<TriangularChartSliceParms> variableHeightFunnelSlices = (from funnelSlice in funnelSlicesParms
                                                                         where !(from slice in fixedHeightFunnelSlices select slice).Contains(funnelSlice)
                                                                         select funnelSlice).ToList();

                    if (minPointHeight > fixedSliceHeight || fixedHeightFunnelSlices.Count == funnelSlicesParms.Count())
                    {
                        isFixedSize = true;
                    }

                    Double sumOfHeightOfSlice2BeFixed = (from funnelSlice in fixedHeightFunnelSlices select funnelSlice.Height).Sum();
                    Double sumOfVariableHeightSlices = (from funnelSlice in variableHeightFunnelSlices select funnelSlice.Height).Sum();

                    Double totalHeight2Reduce = minPointHeight * fixedHeightFunnelSlices.Count() - sumOfHeightOfSlice2BeFixed;

                    // Creating prams for each funnel slice
                    for (Int32 index = 0; index < dataPoints.Count; index++)
                    {
                        if (isFixedSize)
                        {
                            funnelSlicesParms[index].Height = fixedSliceHeight;
                        }
                        else
                        {
                            if (funnelSlicesParms[index].Height < minPointHeight)
                                funnelSlicesParms[index].Height = minPointHeight;
                            else
                                funnelSlicesParms[index].Height -= totalHeight2Reduce * (funnelSlicesParms[index].Height / sumOfVariableHeightSlices);
                        }

                        funnelSlicesParms[index].TopRadius = index == 0 ? plotWidth / 2 : funnelSlicesParms[index - 1].BottomRadius;
                        funnelSlicesParms[index].BottomRadius = funnelSlicesParms[index].TopRadius - funnelSlicesParms[index].Height * Math.Tan(theta);

                        // Set topgap and bottom gap
                        /*if (index == 0 || (Boolean)funnelSlicesParms[index].DataPoint.Exploded)
                            funnelSlicesParms[index].TopGap = _singleGap + ((index == 0 && is3D) ? yScale / 2 : 0);
                        
                        if(index == dataPoints.Count -1 || (Boolean) funnelSlicesParms[index].DataPoint.Exploded)
                            funnelSlicesParms[index].BottomGap = _singleGap;
                         */
                    }
                }

                #endregion
            }
            else
            {
                #region StreamLineFunnel

                funnelHeight = Math.Max(funnelHeight - _streamLineParentTitleSize.Height, 0);

                // Initialization of iOValuePairs
                IOValuePair[] iOValuePairs = new IOValuePair[dataPoints.Count];

                for (Int32 index = 0; index < dataPoints.Count; index++)
                {
                    iOValuePairs[index] = new IOValuePair();
                    iOValuePairs[index].InputValue = ((index == 0) ? Double.NaN : dataPoints[index - 1].YValue);
                    iOValuePairs[index].OutPutValue = dataPoints[index].YValue;
                }

                // Initialization of funnelSliceParms
                funnelSlicesParms = new TriangularChartSliceParms[dataPoints.Count - 1];

                // Creating prams for each funnel slice
                Int32 slicesIndex;

                for (Int32 index = 1; index < iOValuePairs.Count(); index++)
                {
                    slicesIndex = index - 1;

                    funnelSlicesParms[slicesIndex] = new TriangularChartSliceParms() { DataPoint = dataPoints[index] };

                    funnelSlicesParms[slicesIndex].Height = (((iOValuePairs[index].InputValue - iOValuePairs[index].OutPutValue) / iOValuePairs[0].OutPutValue) * funnelHeight);
                    funnelSlicesParms[slicesIndex].TopRadius = slicesIndex == 0 ? plotWidth / 2 : funnelSlicesParms[slicesIndex - 1].BottomRadius;

                    if (!isSameSlantAngle)
                        funnelSlicesParms[slicesIndex].BottomRadius = (funnelSlicesParms[slicesIndex].TopRadius * Math.Sqrt(iOValuePairs[index].OutPutValue / iOValuePairs[index].InputValue));
                    else
                        funnelSlicesParms[slicesIndex].BottomRadius = (funnelSlicesParms[slicesIndex].TopRadius * (iOValuePairs[index].OutPutValue / iOValuePairs[index].InputValue));

                    Double theta = Math.Atan((funnelSlicesParms[slicesIndex].TopRadius - funnelSlicesParms[slicesIndex].BottomRadius) / funnelSlicesParms[slicesIndex].Height);
                    funnelSlicesParms[slicesIndex].TopAngle = Math.PI / 2 - theta;
                    funnelSlicesParms[slicesIndex].BottomAngle = Math.PI / 2 + theta;

                    /*
                    // Set top and bottom gap
                    if(index == 1 || (Boolean)funnelSlicesParms[slicesIndex].DataPoint.Exploded)
                        funnelSlicesParms[slicesIndex].TopGap = singleGap + ((slicesIndex == 0 && is3D) ? yScale / 2 : 0);

                    if (index == iOValuePairs.Count() - 1 || (Boolean)funnelSlicesParms[slicesIndex].DataPoint.Exploded)
                        funnelSlicesParms[slicesIndex].BottomGap = singleGap;
                    */

                    FixTopAndBottomRadiusForStreamLineFunnel(ref funnelSlicesParms[slicesIndex]);
                }

                // Enlarge Funnel Height-----------

                Double totalSumOfHeight = (from funnelSlice in funnelSlicesParms select funnelSlice.Height).Sum();

                if (totalSumOfHeight < funnelHeight)
                {
                    for (Int32 index = 1; index < iOValuePairs.Count(); index++)
                    {
                        slicesIndex = index - 1;

                        //funnelSlicesParms[slicesIndex] = new TriangularChartSliceParms() { DataPoint = dataPoints[index] };

                        funnelSlicesParms[slicesIndex].Height += (funnelHeight - totalSumOfHeight) * (funnelSlicesParms[slicesIndex].Height / totalSumOfHeight);

                        funnelSlicesParms[slicesIndex].TopRadius = slicesIndex == 0 ? plotWidth / 2 : funnelSlicesParms[slicesIndex - 1].BottomRadius;

                        if (!isSameSlantAngle)
                            funnelSlicesParms[slicesIndex].BottomRadius = Math.Round(funnelSlicesParms[slicesIndex].TopRadius * Math.Sqrt(iOValuePairs[index].OutPutValue / iOValuePairs[index].InputValue));
                        else
                            funnelSlicesParms[slicesIndex].BottomRadius = Math.Round(funnelSlicesParms[slicesIndex].TopRadius * (iOValuePairs[index].OutPutValue / iOValuePairs[index].InputValue));

                        Double theta = Math.Atan((funnelSlicesParms[slicesIndex].TopRadius - funnelSlicesParms[slicesIndex].BottomRadius) / funnelSlicesParms[slicesIndex].Height);
                        funnelSlicesParms[slicesIndex].TopAngle = Math.PI / 2 - theta;
                        funnelSlicesParms[slicesIndex].BottomAngle = Math.PI / 2 + theta;

                        /*
                        // Set top and bottom gap
                        if(index == 1 || (Boolean)funnelSlicesParms[slicesIndex].DataPoint.Exploded)
                            funnelSlicesParms[slicesIndex].TopGap = singleGap + ((slicesIndex == 0 && is3D) ? yScale / 2 : 0);

                        if (index == iOValuePairs.Count() - 1 || (Boolean)funnelSlicesParms[slicesIndex].DataPoint.Exploded)
                            funnelSlicesParms[slicesIndex].BottomGap = singleGap;
                        */

                        FixTopAndBottomRadiusForStreamLineFunnel(ref funnelSlicesParms[slicesIndex]);
                    }
                }

                // End Enlarge funnel Height-------


                if (!Double.IsNaN(minPointHeight))
                {
                    Boolean isFixedSize = false;    // Whether to fix height of all slice
                    Double fixedSliceHeight = 0;
                    Double funnelActualHeight = funnelHeight - _streamLineParentTitleSize.Height;

                    fixedSliceHeight = funnelActualHeight / funnelSlicesParms.Length;

                    // Calculate minPointHeight in terms of pixel value
                    minPointHeight = (minPointHeight / 100) * funnelHeight;

                    // Funnel slices where height is less than the minPointHeight
                    var fixedHeightFunnelSlices = (from funnelSlice in funnelSlicesParms where funnelSlice.Height < minPointHeight select funnelSlice);

                    var variableHeightFunnelSlices = (from funnelSlice in funnelSlicesParms
                                                      where !(from slice in fixedHeightFunnelSlices select slice).Contains(funnelSlice)
                                                      select funnelSlice);

                    if (minPointHeight > fixedSliceHeight || fixedHeightFunnelSlices.Count() == funnelSlicesParms.Count())
                    {
                        isFixedSize = true;
                    }

                    //Double totalSumOfHeight = (from funnelSlice in funnelSlicesParms select funnelSlice.Height).Sum();
                    Double sumOfHeightOfSlice2BeFixed = (from funnelSlice in fixedHeightFunnelSlices select funnelSlice.Height).Sum();
                    Double sumOfVariableHeightSlices = (from funnelSlice in variableHeightFunnelSlices select funnelSlice.Height).Sum();

                    Double totalHeight2Reduce = minPointHeight * fixedHeightFunnelSlices.Count() - sumOfHeightOfSlice2BeFixed;

                    for (Int32 index = 1; index < iOValuePairs.Count(); index++)
                    {
                        slicesIndex = index - 1;

                        if (isFixedSize)
                        {
                            funnelSlicesParms[slicesIndex].Height = fixedSliceHeight;
                        }
                        else
                        {
                            if (funnelSlicesParms[slicesIndex].Height < minPointHeight)
                                funnelSlicesParms[slicesIndex].Height = minPointHeight;
                            else
                                funnelSlicesParms[slicesIndex].Height -= totalHeight2Reduce * (funnelSlicesParms[slicesIndex].Height / sumOfVariableHeightSlices);
                        }

                        funnelSlicesParms[slicesIndex].TopRadius = slicesIndex == 0 ? plotWidth / 2 : funnelSlicesParms[slicesIndex - 1].BottomRadius;

                        if (!isSameSlantAngle)
                            funnelSlicesParms[slicesIndex].BottomRadius = Math.Round(funnelSlicesParms[slicesIndex].TopRadius * Math.Sqrt(iOValuePairs[index].OutPutValue / iOValuePairs[index].InputValue));
                        else
                            funnelSlicesParms[slicesIndex].BottomRadius = Math.Round(funnelSlicesParms[slicesIndex].TopRadius * (iOValuePairs[index].OutPutValue / iOValuePairs[index].InputValue));

                        // Set top and bottom gap
                        /*if(index == 1 || (Boolean)funnelSlicesParms[slicesIndex].DataPoint.Exploded)
                            funnelSlicesParms[slicesIndex].TopGap = _singleGap + ((slicesIndex == 0 && is3D) ? yScale / 2 : 0);
                        
                        if(index == iOValuePairs.Count() -1 || (Boolean)funnelSlicesParms[slicesIndex].DataPoint.Exploded)
                            funnelSlicesParms[slicesIndex].BottomGap = _singleGap;
                        */

                        // Calculate funnel angle
                        // funnelSlicesParms[slicesIndex].TopAngle = Math.PI / 2 - Math.Atan((funnelSlicesParms[slicesIndex].TopRadius - funnelSlicesParms[slicesIndex].BottomRadius) / funnelSlicesParms[slicesIndex].Height);

                        FixTopAndBottomRadiusForStreamLineFunnel(ref funnelSlicesParms[slicesIndex]);

                        Double theta = Math.Atan((funnelSlicesParms[slicesIndex].TopRadius - funnelSlicesParms[slicesIndex].BottomRadius) / funnelSlicesParms[slicesIndex].Height);
                        funnelSlicesParms[slicesIndex].TopAngle = Math.PI / 2 - theta;
                        funnelSlicesParms[slicesIndex].BottomAngle = Math.PI / 2 + theta;
                    }
                }
            }

                #endregion

            return funnelSlicesParms;
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Creates a LabelLine for Funnel Chart
        /// </summary>
        /// <param name="funnelSlice">TriangularChartSliceParms</param>
        /// <param name="topRadius">Top most radius of the funnel</param>
        /// <param name="animationEnabled">Whether animation is enabled</param>
        /// <returns>Canvas for labelline </returns>
        private static Canvas CreateLabelLine(TriangularChartSliceParms funnelSlice, Double topRadius, Boolean animationEnabled)
        {
            Canvas labelLineCanvas = null;
            Point topRightPoint = new Point(topRadius + funnelSlice.TopRadius, 0);
            Point bottomRightPoint = new Point(topRadius + funnelSlice.BottomRadius, funnelSlice.Height);
            funnelSlice.RightMidPoint = Graphics.MidPointOfALine(topRightPoint, bottomRightPoint);

            if (funnelSlice.DataPoint.Parent.RenderAs == RenderAs.StreamLineFunnel)
                funnelSlice.LabelLineEndPoint = new Point(2 * topRadius, (bottomRightPoint.Y - 1.5 * Chart.BEVEL_DEPTH) < 0 ? bottomRightPoint.Y * .9 : (bottomRightPoint.Y - 1.5 * Chart.BEVEL_DEPTH));
            else
                funnelSlice.LabelLineEndPoint = new Point(2 * topRadius, funnelSlice.RightMidPoint.Y);

            funnelSlice.OrginalLabelLineEndPoint = funnelSlice.LabelLineEndPoint;

            if ((Boolean)funnelSlice.DataPoint.LabelLineEnabled && funnelSlice.DataPoint.LabelStyle == LabelStyles.OutSide)
            {
                labelLineCanvas = new Canvas();

                labelLineCanvas.Width = topRadius * 2;
                labelLineCanvas.Height = funnelSlice.Height;

                funnelSlice.DataPoint.LabelLine = null;

                Path line = new Path()
                {
                    Stroke = funnelSlice.DataPoint.LabelLineColor,
                    Fill = funnelSlice.DataPoint.LabelLineColor,
                    StrokeDashArray = ExtendedGraphics.GetDashArray((LineStyles)funnelSlice.DataPoint.LabelLineStyle),
                    StrokeThickness = (Double)funnelSlice.DataPoint.LabelLineThickness,
                };

                PathGeometry linePathGeometry = new PathGeometry();

                // Set first point of the line
                PathFigure linePathFigure = new PathFigure()
                {
                    StartPoint = (funnelSlice.DataPoint.Parent.RenderAs == RenderAs.StreamLineFunnel) ? bottomRightPoint : funnelSlice.RightMidPoint
                };

                // Set second point of line
                linePathFigure.Segments.Add(new LineSegment() { Point = funnelSlice.LabelLineEndPoint });

                linePathGeometry.Figures.Add(linePathFigure);

                line.Data = linePathGeometry;

                funnelSlice.DataPoint.LabelLine = line;

                labelLineCanvas.Children.Add(line);

                if (animationEnabled)
                    funnelSlice.DataPoint.Parent.Storyboard = ApplyLabeLineAnimation(labelLineCanvas, funnelSlice.DataPoint.Parent, funnelSlice.DataPoint.Parent.Storyboard);
            }

            return labelLineCanvas;
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Returns the visual of a funnel slice
        /// </summary>
        /// <param name="finnelIndex">Slice index</param>
        /// <param name="topRadius">Top radius of the Funnel</param>
        /// <param name="is3D">Whether the chart is a 3D Chart</param>
        /// <param name="funnelSlice">Funnel Slice reference</param>
        /// <param name="yScaleTop">Top y-scale for 3D slice</param>
        /// <param name="yScaleBottom">Bottom y-scale for 3D slice</param>
        /// <param name="fillColor">Fill Color of the funnel slice</param>
        /// <param name="animationEnabled">Whether the animation is enabled</param>
        /// <returns>Funnel slice canvas</returns>
        private static Canvas GetFunnelSliceVisual(Int32 funnelSliceIndex, Double topRadius, Boolean is3D, TriangularChartSliceParms funnelSlice, Double yScaleTop, Double yScaleBottom, Brush fillColor, Boolean animationEnabled)
        {
            funnelSlice.Index = funnelSliceIndex;
            Canvas sliceCanvas = CreateFunnelSlice(false, topRadius, is3D, funnelSlice, yScaleTop, yScaleBottom, fillColor, fillColor, fillColor, animationEnabled);

            if ((Boolean)funnelSlice.DataPoint.LightingEnabled)
            {
                Brush highlightBrush4Stroke = GetLightingBrushForStroke(fillColor, funnelSlice.Index);
                Brush sideFillColor = (Boolean)funnelSlice.DataPoint.LightingEnabled ? GetSideLightingBrush(funnelSlice) : fillColor;
                Brush topFillColor = is3D ? GetTopBrush(fillColor, funnelSlice) : fillColor;
                Canvas gradientCanvas = CreateFunnelSlice(true, topRadius, is3D, funnelSlice, yScaleTop, yScaleBottom, sideFillColor, topFillColor, highlightBrush4Stroke, animationEnabled);
                sliceCanvas.Children.Add(gradientCanvas);
            }

            return sliceCanvas;
        }
Ejemplo n.º 20
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;
        }