Beispiel #1
0
        /// <summary>
        /// Get visual object for stacked area100 chart
        /// </summary>
        /// <param name="width">Width of the PlotArea</param>
        /// <param name="height">Height of the PlotArea</param>
        /// <param name="plotDetails">PlotDetails</param>
        /// <param name="seriesList">List of DataSeries with render as StackedArea100 chart</param>
        /// <param name="chart">Chart</param>
        /// <param name="plankDepth">PlankDepth</param>
        /// <param name="animationEnabled">Whether animation is enabled for chart</param>
        /// <returns>StackedArea100 chart canvas</returns>
        internal static Canvas GetVisualObjectForStackedArea100Chart(Panel preExistingPanel,Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled)
        {
            if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0)
                return null;

            DataSeries currentDataSeries;
            Boolean plankDrawn = false;
            Double depth3d = plankDepth / plotDetails.Layer3DCount * (chart.View3D ? 1 : 0);
            Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1);

            if (Double.IsNaN(visualOffset) || Double.IsInfinity(visualOffset))
                return null;

            Canvas visual, labelCanvas, areaCanvas;
            RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out areaCanvas, width, height);
           
            //Canvas visual = new Canvas() { Width = width, Height = height };
            //Canvas labelCanvas = new Canvas() { Width = width, Height = height };
            //Canvas areaCanvas = new Canvas() { Width = width, Height = height };

            visual.SetValue(Canvas.TopProperty, visualOffset);
            visual.SetValue(Canvas.LeftProperty, -visualOffset);

            labelCanvas.SetValue(Canvas.TopProperty, (Double)0);
            labelCanvas.SetValue(Canvas.LeftProperty, (Double)0);
            labelCanvas.SetValue(Canvas.ZIndexProperty, (Int32)1);

            var plotgroups = (from series in seriesList where series.PlotGroup != null select series.PlotGroup);

            if (plotgroups.Count() == 0)
                return visual;

            PlotGroup plotGroup = plotgroups.First();

            Dictionary<Double, List<Double>> dataPointValuesInStackedOrder = plotDetails.GetDataPointValuesInStackedOrder4StackedArea(plotGroup);

            Dictionary<Double, List<DataPoint>> dataPointInStackedOrder = plotDetails.GetDataPointInStackOrder4StackedArea(plotGroup);

            //Double[] xValues = RenderHelper.GetXValuesUnderViewPort(dataPointValuesInStackedOrder.Keys.ToList(), plotGroup.AxisX, plotGroup.AxisY, true);
            Double[] xValues = dataPointValuesInStackedOrder.Keys.ToArray();

            Double minimumXValue = plotGroup.MinimumX;
            Double maximumXValue = plotGroup.MaximumX;

            Double limitingYValue = 0;

            if (plotGroup.AxisY.InternalAxisMinimum > 0)
                limitingYValue = (Double)plotGroup.AxisY.InternalAxisMinimum;
            if (plotGroup.AxisY.InternalAxisMaximum < 0)
                limitingYValue = (Double)plotGroup.AxisY.InternalAxisMaximum;

            foreach (DataSeries ds in seriesList)
            {
                ds.Faces = null;

                if (ds.ToolTipElement != null)
                    ds.ToolTipElement.Hide();
            }

            Double limitingYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue);

            Marker marker;

            for (Int32 i = 0; i < xValues.Length - 1; i++)
            {
                List<Double> curYValues = dataPointValuesInStackedOrder[xValues[i]];
                List<Double> nextYValues = dataPointValuesInStackedOrder[xValues[i + 1]];

                Double curBase = limitingYValue;
                Double nextBase = limitingYValue;
                Double curAbsoluteSum = plotGroup.XWiseStackedDataList[xValues[i]].AbsoluteYValueSum;
                Double nextAbsoluteSum = plotGroup.XWiseStackedDataList[xValues[i + 1]].AbsoluteYValueSum;

                List<DataPoint> curDataPoints = dataPointInStackedOrder[xValues[i]];
                List<DataPoint> nextDataPoints = dataPointInStackedOrder[xValues[i + 1]];

                if (Double.IsNaN(curAbsoluteSum))
                    curAbsoluteSum = 1;

                if (Double.IsNaN(nextAbsoluteSum))
                    nextAbsoluteSum = 1;

                Double totalOfCurrBase = 0;
                Double totalOfNextBase = 0;
                Double currTot = 0;
                Double nextTot = 0;

                for (Int32 index = 0; index < curYValues.Count; index++)
                {
                    if (index >= nextYValues.Count || index >= curYValues.Count || curDataPoints[index] == null || nextDataPoints[index] == null)
                        continue;

                    Double curPercentageY = 0;
                    Double nextPercentageY = 0;

                    if (Double.IsNaN(nextPercentageY) || Double.IsNaN(curPercentageY))
                        continue;

                    Double percentOfCurrSucessiveDpValues = 0;
                    Double percentOfNextSucessiveDpValues = 0;

                    if (index == 0 && Double.IsNaN(curYValues[index]))
                        continue;

                    if (plotGroup.AxisY.Logarithmic)
                    {
                        curPercentageY = curYValues[index] / curAbsoluteSum * 100;
                        nextPercentageY = nextYValues[index] / nextAbsoluteSum * 100;

                        curPercentageY = Double.IsNaN(curPercentageY) ? 0 : curPercentageY;
                        nextPercentageY = Double.IsNaN(nextPercentageY) ? 0 : nextPercentageY;

                        percentOfCurrSucessiveDpValues = Math.Log(curPercentageY + curBase, plotGroup.AxisY.LogarithmBase);

                        if (Double.IsNegativeInfinity(percentOfCurrSucessiveDpValues))
                            percentOfCurrSucessiveDpValues = 0;

                        percentOfNextSucessiveDpValues = Math.Log(nextPercentageY + nextBase, plotGroup.AxisY.LogarithmBase);

                        if (Double.IsNegativeInfinity(percentOfNextSucessiveDpValues))
                            percentOfNextSucessiveDpValues = 0;
                    }
                    else
                    {
                        curPercentageY = curYValues[index] / curAbsoluteSum * 100;
                        nextPercentageY = nextYValues[index] / nextAbsoluteSum * 100;

                        curPercentageY = Double.IsNaN(curPercentageY) ? 0 : curPercentageY;
                        nextPercentageY = Double.IsNaN(nextPercentageY) ? 0 : nextPercentageY;

                        percentOfCurrSucessiveDpValues = curBase + curPercentageY;
                        percentOfNextSucessiveDpValues = nextBase + nextPercentageY;

                        totalOfCurrBase = curBase;
                        totalOfNextBase = nextBase;
                    }

                    Double curXPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, xValues[i]);
                    Double nextXPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, xValues[i + 1]);
                    Double curYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, percentOfCurrSucessiveDpValues);
                    Double nextYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, percentOfNextSucessiveDpValues);
                    Double curYBase = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, totalOfCurrBase);
                    Double nextYBase = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, totalOfNextBase);
                    
                    Point intersect = GetIntersection(new Point(curXPosition, curYBase), new Point(nextXPosition, nextYBase),
                                                new Point(curXPosition, curYPosition), new Point(nextXPosition, nextYPosition));

                    if (plotGroup.AxisY.Logarithmic)
                    {
                        currTot += curPercentageY;
                        nextTot += nextPercentageY;

                        totalOfCurrBase = Math.Log(currTot, plotGroup.AxisY.LogarithmBase);

                        if (Double.IsNegativeInfinity(totalOfCurrBase))
                            totalOfCurrBase = 0;

                        totalOfNextBase = Math.Log(nextTot, plotGroup.AxisY.LogarithmBase);

                        if (Double.IsNegativeInfinity(totalOfNextBase))
                            totalOfNextBase = 0;
                    }

                    marker = GetMarkerForDataPoint(chart, height, false, curDataPoints[index], curYPosition, curDataPoints[index].InternalYValue > 0);
                    if (marker != null)
                    {
                        if (curDataPoints[index].Parent.Storyboard == null)
                            curDataPoints[index].Parent.Storyboard = new Storyboard();

                        currentDataSeries = curDataPoints[index].Parent;

                        marker.AddToParent(labelCanvas, curXPosition, curYPosition, new Point(0.5, 0.5));
                        // Apply marker animation
                        if (animationEnabled)
                            curDataPoints[index].Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, currentDataSeries, curDataPoints[index].Parent.Storyboard, 1, (Double)curDataPoints[index].Opacity * (Double)curDataPoints[index].Parent.Opacity);
                    }

                    curDataPoints[index]._visualPosition = new Point(curXPosition, curYPosition);

                    if (i + 1 == xValues.Length - 1)
                    {
                        marker = GetMarkerForDataPoint(chart, height, false, nextDataPoints[index], nextYPosition, nextDataPoints[index].InternalYValue > 0);
                        if (marker != null)
                        {
                            if (curDataPoints[index].Parent.Storyboard == null)
                                curDataPoints[index].Parent.Storyboard = new Storyboard();

                            currentDataSeries = curDataPoints[index].Parent;

                            marker.AddToParent(labelCanvas, nextXPosition, nextYPosition, new Point(0.5, 0.5));
                            // Apply marker animation
                            if (animationEnabled)
                                nextDataPoints[index].Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, currentDataSeries, nextDataPoints[index].Parent.Storyboard, 1, (Double)nextDataPoints[index].Opacity * (Double)nextDataPoints[index].Parent.Opacity);
                        }

                        nextDataPoints[index]._visualPosition = new Point(nextXPosition, nextYPosition);
                    }

                    if (curDataPoints[index].Parent.Faces == null)
                    {
                        curDataPoints[index].Parent.Faces = new Faces();
                    }

                    List<PointCollection> pointSet = null;
                    if ((!Double.IsNaN(intersect.X) && !Double.IsInfinity(intersect.X)) && (intersect.X >= curXPosition && intersect.X <= nextXPosition))
                    {
                        List<PointCollection> set1 = GeneratePointsCollection(curXPosition, curYPosition, curYBase, intersect.X, intersect.Y, intersect.Y, limitingYPosition);

                        List<PointCollection> set2 = GeneratePointsCollection(intersect.X, intersect.Y, intersect.Y, nextXPosition, nextYPosition, nextYBase, limitingYPosition);

                        pointSet = set1;
                        pointSet.InsertRange(pointSet.Count, set2);
                    }
                    else
                    {
                        pointSet = GeneratePointsCollection(curXPosition, curYPosition, curYBase, nextXPosition, nextYPosition, nextYBase, limitingYPosition);
                    }

                    DataSeries series = curDataPoints[index].Parent;
                    Brush areaBrush = series.Color;

                    currentDataSeries = series;

                    PolygonalChartShapeParams areaParams = GetAreaParms(series, areaBrush, depth3d);

                    Faces faces = curDataPoints[index].Parent.Faces;
                    if (faces.Parts == null)
                        faces.Parts = new List<DependencyObject>();

                    // This is used to set some pixel padding for the last two points of a PointCollection
                    Double pixelPadding = 0.8;

                    foreach (PointCollection points in pointSet)
                    {
                        points[points.Count - 2] = new Point(points[points.Count - 2].X + pixelPadding, points[points.Count - 2].Y);
                        points[points.Count - 1] = new Point(points[points.Count - 1].X + pixelPadding, points[points.Count - 1].Y);

                        areaParams.Points = points;

                        if (chart.View3D)
                        {
                            Point centroid = GetCentroid(points);
                            areaParams.IsPositive = centroid.Y < limitingYPosition;
                            Canvas frontface = GetStacked3DAreaFrontFace(ref faces, areaParams);
                            Canvas sideface = GetStacked3DSideFaces(ref faces, areaParams);
                            sideface.SetValue(Canvas.ZIndexProperty, GetStackedAreaZIndex(centroid.X, centroid.Y, areaParams.IsPositive, index));
                            frontface.SetValue(Canvas.ZIndexProperty, 50000);
                            areaCanvas.Children.Add(sideface);
                            areaCanvas.Children.Add(frontface);
                            curDataPoints[index].Parent.Faces.VisualComponents.Add(sideface);
                            curDataPoints[index].Parent.Faces.VisualComponents.Add(frontface);

                            // Apply Animation
                            if (animationEnabled)
                            {
                                if (curDataPoints[index].Parent.Storyboard == null)
                                    curDataPoints[index].Parent.Storyboard = new Storyboard();
                                Storyboard storyboard = curDataPoints[index].Parent.Storyboard;

                                // apply animation to the various faces
                                storyboard = ApplyStackedAreaAnimation(currentDataSeries, sideface, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)) + 0.05, 1.0 / seriesList.Count);
                                storyboard = ApplyStackedAreaAnimation(currentDataSeries, frontface, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)), 1.0 / seriesList.Count);
                            }
                        }
                        else
                        {
                            Canvas area2d = Get2DArea(currentDataSeries, ref faces, areaParams);
                            areaCanvas.Children.Add(area2d);
                            curDataPoints[index].Parent.Faces.VisualComponents.Add(area2d);
                            if (animationEnabled)
                            {
                                if (curDataPoints[index].Parent.Storyboard == null)
                                    curDataPoints[index].Parent.Storyboard = new Storyboard();
                                Storyboard storyboard = curDataPoints[index].Parent.Storyboard;

                                // apply animation to the various faces
                                storyboard = ApplyStackedAreaAnimation(currentDataSeries, area2d, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)), 1.0 / seriesList.Count);
                            }
                        }

                        curDataPoints[index].Parent.Faces.Visual = visual;

                        #if !WP

                        if (VisifireControl.IsMediaEffectsEnabled)
                        {
                            if ((Boolean)series.ShadowEnabled)
                            {
                                if (series.Faces != null && series.Faces.Visual != null)
                                {
                                    series.Faces.Visual.Effect = ExtendedGraphics.GetShadowEffect(135, 2, 1);
                                }
                            }
                        }

                        #endif
                    }

                    curBase += curPercentageY;
                    nextBase += nextPercentageY;
                }

            }

            if (xValues.Count() > 0)
            {
                if (!plankDrawn && chart.View3D && plotGroup.AxisY.InternalAxisMinimum < 0 && plotGroup.AxisY.InternalAxisMaximum > 0)
                {
                    //RectangularChartShapeParams columnParams = new RectangularChartShapeParams();
                    //columnParams.BackgroundBrush = new SolidColorBrush(Color.FromArgb((Byte)255, (Byte)255, (Byte)255, (Byte)255));
                    //columnParams.Lighting = true;
                    //columnParams.Size = new Size(width, 1);
                    //columnParams.Depth = depth3d;

                    Brush frontBrush, topBrush, rightBrush;
                    ExtendedGraphics.GetBrushesForPlank(chart, out frontBrush, out topBrush, out rightBrush, true);

                    Faces zeroPlank = ColumnChart.Get3DPlank(width, 1, depth3d, frontBrush, topBrush, rightBrush);
                    Panel zeroPlankVisual = zeroPlank.Visual as Panel;

                    Double top = height - Graphics.ValueToPixelPosition(0, height, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, 0);
                    zeroPlankVisual.SetValue(Canvas.LeftProperty, (Double)0);
                    zeroPlankVisual.SetValue(Canvas.TopProperty, top);
                    zeroPlankVisual.SetValue(Canvas.ZIndexProperty, 0);
                    zeroPlankVisual.Opacity = 0.7;
                    visual.Children.Add(zeroPlankVisual);
                }
            }

            chart.ChartArea.DisableIndicators();

            //visual.Children.Add(areaCanvas);
            //visual.Children.Add(labelCanvas);

            // Remove old visual and add new visual in to the existing panel
            if (preExistingPanel != null)
            {
                visual.Children.RemoveAt(1);
                visual.Children.Add(areaCanvas);
            }
            else
            {
                labelCanvas.SetValue(Canvas.ZIndexProperty, 1);
                visual.Children.Add(labelCanvas);
                visual.Children.Add(areaCanvas);
            }

            PlotArea plotArea = chart.PlotArea;

            RectangleGeometry clipRectangle = new RectangleGeometry();
            clipRectangle.Rect = new Rect(0, plotArea.BorderThickness.Top - depth3d, width + depth3d, height + depth3d + chart.ChartArea.PLANK_THICKNESS - plotArea.BorderThickness.Bottom - plotArea.BorderThickness.Top);
            areaCanvas.Clip = clipRectangle;

            // Clip the label canvas

            clipRectangle = new RectangleGeometry();

            Double clipLeft = 0;
            Double clipTop = -depth3d - 4;
            Double clipWidth = width + depth3d;
            Double clipHeight = height + depth3d + chart.ChartArea.PLANK_THICKNESS + 10;

            GetClipCoordinates(chart, ref clipLeft, ref clipTop, ref clipWidth, ref clipHeight, minimumXValue, maximumXValue);

            clipRectangle.Rect = new Rect(clipLeft, clipTop, clipWidth, clipHeight);
            labelCanvas.Clip = clipRectangle;

            return visual;
        }