Пример #1
0
        private void _draw3DPies(
            Canvas pieContainer,
            double quadWidth,
            double quadHeight,
            int iGroup)
        {
            ChartModel model = Model;

            double[,] yValues = model.YValues;
            string[] groupLabels  = model.GroupLabels;
            Color[]  seriesColors = model.SeriesColors;

            var pieSize = Math.Min(quadWidth / 2, quadHeight / 2);

            if (iGroup == -1)
            {
                iGroup = 0;
            }

            int    nPies    = yValues.GetUpperBound(1) + 1;
            double pieTotal = 0;

            for (int i = 0; i < nPies; ++i)
            {
                pieTotal += yValues[iGroup, i];
            }

            string           pathXAML = CurrentLookAndFeel.GetPiePathXAML();
            Path             pathElem;
            double           pieStart  = 0;
            List <UIElement> dataElems = null;
            bool             animate   = (AnimationDuration > 0);

            if (animate)
            {
                dataElems = DataElements;
            }

            double perspectiveHeight = pieSize / 4;

            Path[] pieElems = new Path[nPies],
            ringElems = new Path[nPies],
            edgeElems = new Path[nPies];

            if (perspectiveHeight > _MAX_PERSPECTIVE_HEIGHT)
            {
                perspectiveHeight = _MAX_PERSPECTIVE_HEIGHT;
            }

            string             gradientXAML = CurrentLookAndFeel.GetElementGradientXAML();
            TranslateTransform defaultTransform;

            for (int i = 0; i < nPies; ++i)
            {
                double valueRatio = 1 - (yValues[iGroup, i]) / (pieTotal);

                double arcBeginX, arcBeginY, arcEndX, arcEndY;
                arcBeginX = pieSize * Math.Cos(pieStart * Math.PI * 2);
                arcBeginY = pieSize * Math.Sin(pieStart * Math.PI * 2);

                StringBuilder sb = new StringBuilder();
                sb.Append("M0,0L").Append(arcBeginX).Append(",").Append(arcBeginY);

                arcEndX = pieSize * Math.Cos((pieStart + valueRatio) * Math.PI * 2);
                arcEndY = pieSize * Math.Sin((pieStart + valueRatio) * Math.PI * 2);

                if (valueRatio >= .5)
                {
                    sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 0 0 ");
                }
                else
                {
                    sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 1 0 ");
                }

                sb.Append(arcEndX).Append(",").Append(arcEndY);
                sb.Append(" z");

                pathElem = CreatePathFromXAMLAndData(pathXAML, sb);
                if (animate)
                {
                    dataElems.Add(pathElem);

                    defaultTransform   = new TranslateTransform();
                    defaultTransform.X = defaultTransform.Y = -10000;
                    pathElem.SetValue(Canvas.RenderTransformProperty, defaultTransform);

                    _pieAnimAngles.Add(pieStart + valueRatio / 2);
                }

                if (gradientXAML != null)
                {
                    SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0xe5);
                }
                else
                {
                    SetFillOnElement(pathElem, seriesColors[i]);
                }

                pathElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i]));

                // centroid of the pie triangle
                Point centroid = new Point((arcBeginX + arcEndX) / 3, (arcBeginY + arcEndY) / 3);
                SetExpandosOnElement(pathElem, iGroup, i, centroid);
                if (DisplayToolTip)
                {
                    pathElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                    pathElem.MouseLeave += new MouseEventHandler(HideToolTip);
                }

                pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);



                sb = new StringBuilder();
                sb.Append("M").Append(arcBeginX).Append(",").Append(arcBeginY);
                if (valueRatio >= .5) // major arc
                {
                    sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 0 0 ");
                }
                else
                {
                    sb.Append(" A").Append(pieSize).Append(" ").Append(pieSize).Append(" 1 1 0 ");
                }

                sb.Append(arcEndX).Append(",").Append(arcEndY);

                sb.Append(" v").Append(perspectiveHeight);
                sb.Append(" M").Append(arcEndX).Append(",").Append(arcEndY + perspectiveHeight);

                if (valueRatio >= .5) // major arc
                {
                    sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 0 1 ");
                }
                else
                {
                    sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 1 1 ");
                }

                sb.Append(arcBeginX).Append(",").Append(arcBeginY + perspectiveHeight);
                sb.Append(" v").Append(-perspectiveHeight);

                Path pathRingElem = CreatePathFromXAMLAndData(pathXAML, sb);

                if (gradientXAML != null)
                {
                    SetGradientOnElement(pathRingElem, gradientXAML, seriesColors[i], 0xe5);
                }
                else
                {
                    SetFillOnElement(pathRingElem, seriesColors[i]);
                }

                pathRingElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i]));

                sb = new StringBuilder();
                sb.Append("M0,0L");
                sb.Append(arcBeginX).Append(",").Append(arcBeginY);
                sb.Append("v").Append(perspectiveHeight);
                sb.Append("L").Append(0).Append(",").Append(perspectiveHeight);
                sb.Append("z");
                sb.Append("M0,0L");
                sb.Append(arcEndX).Append(",").Append(arcEndY);
                sb.Append("v").Append(perspectiveHeight);
                sb.Append("L").Append(0).Append(",").Append(perspectiveHeight);
                sb.Append("z");


                Path pathEdgeElem = CreatePathFromXAMLAndData(pathXAML, sb);

                if (animate)
                {
                    dataElems.Add(pathRingElem);

                    defaultTransform   = new TranslateTransform();
                    defaultTransform.X = defaultTransform.Y = -10000;
                    pathRingElem.SetValue(Canvas.RenderTransformProperty, defaultTransform);
                    dataElems.Add(pathEdgeElem);

                    defaultTransform   = new TranslateTransform();
                    defaultTransform.X = defaultTransform.Y = -10000;
                    pathEdgeElem.SetValue(Canvas.RenderTransformProperty, defaultTransform);
                }

                (pathEdgeElem.Data as PathGeometry).FillRule = FillRule.Nonzero;

                if (gradientXAML != null)
                {
                    SetGradientOnElement(pathEdgeElem, gradientXAML, seriesColors[i], 0xe5);
                }
                else
                {
                    SetFillOnElement(pathEdgeElem, seriesColors[i]);
                }

                pathEdgeElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i]));

                if (DisplayToolTip)
                {
                    pathRingElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                    pathRingElem.MouseLeave += new MouseEventHandler(HideToolTip);
                    pathEdgeElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                    pathEdgeElem.MouseLeave += new MouseEventHandler(HideToolTip);
                }
                SetExpandosOnElement(pathRingElem, iGroup, i, centroid);
                SetExpandosOnElement(pathEdgeElem, iGroup, i, centroid);

                pieStart    += valueRatio;
                pieElems[i]  = pathElem;
                ringElems[i] = pathRingElem;
                edgeElems[i] = pathEdgeElem;
            }

            UIElementCollection children = pieContainer.Children;

            // For the top half, edges have preference over rings
            double totalRatio = 0;

            for (int i = 0; i < nPies; ++i)
            {
                if (totalRatio <= .5)
                {
                    children.Add(ringElems[i]);
                }
                totalRatio += (yValues[iGroup, i]) / (pieTotal);
            }

            totalRatio = 0;
            for (int i = 0; i < nPies; ++i)
            {
                if (totalRatio <= .5)
                {
                    children.Add(edgeElems[i]);
                }
                totalRatio += (yValues[iGroup, i]) / (pieTotal);
            }

            // For the bottom half, rings have preference over edges
            totalRatio = 0;
            for (int i = 0; i < nPies; ++i)
            {
                if (totalRatio > .5)
                {
                    children.Add(edgeElems[i]);
                }
                totalRatio += (yValues[iGroup, i]) / (pieTotal);
            }

            totalRatio = 0;
            for (int i = 0; i < nPies; ++i)
            {
                if (totalRatio > .5)
                {
                    children.Add(ringElems[i]);
                }
                totalRatio += (yValues[iGroup, i]) / (pieTotal);
            }

            for (int i = 0; i < nPies; ++i)
            {
                children.Add(pieElems[i]);
            }
        }
Пример #2
0
        private void _drawPies(
            Canvas pieContainer,
            double quadWidth,
            double quadHeight,
            int iGroup)
        {
            ChartModel model = Model;

            double[,] yValues = model.YValues;
            string [] groupLabels  = model.GroupLabels;
            Color[]   seriesColors = model.SeriesColors;

            var pieSize = Math.Min(quadWidth / 2, quadHeight / 2);

            if (iGroup == -1)
            {
                iGroup = 0;
            }

            double nPies    = yValues.GetUpperBound(1) + 1;
            double pieTotal = 0;

            for (int i = 0; i < nPies; ++i)
            {
                pieTotal += yValues[iGroup, i];
            }

            string           pathXAML = CurrentLookAndFeel.GetPiePathXAML();
            Path             pathElem;
            double           pieStart = 0, animAngleStart = 0;
            List <UIElement> dataElems = null;
            bool             animate   = (AnimationDuration > 0);

            if (animate)
            {
                dataElems = DataElements;
            }

            string             gradientXAML = CurrentLookAndFeel.GetElementGradientXAML();
            TranslateTransform defaultTransform;

            for (int i = 0; i < nPies; ++i)
            {
                double valueRatio = 1 - (yValues[iGroup, i]) / (pieTotal);

                double x1 = pieSize * Math.Cos(pieStart * Math.PI * 2),
                       y1 = pieSize * Math.Sin(pieStart * Math.PI * 2);

                StringBuilder sb = new StringBuilder();
                sb.Append("M0,0 L");
                sb.Append(x1);
                sb.Append(",").Append(y1);

                double x2 = pieSize * Math.Cos((pieStart + valueRatio) * Math.PI * 2),
                       y2 = pieSize * Math.Sin((pieStart + valueRatio) * Math.PI * 2);

                if (valueRatio >= .5) // major arc
                {
                    sb.Append(" A").Append(pieSize).Append(" ").Append(pieSize).Append(" 1 0 0 ");
                }
                else
                {
                    sb.Append(" A").Append(pieSize).Append(" ").Append(pieSize).Append(" 1 1 0 ");
                }
                sb.Append(x2);
                sb.Append(",").Append(y2);
                sb.Append(" z");

                pathElem = CreatePathFromXAMLAndData(pathXAML, sb);
                if (animate)
                {
                    dataElems.Add(pathElem);

                    defaultTransform   = new TranslateTransform();
                    defaultTransform.X = defaultTransform.Y = -10000;
                    pathElem.SetValue(Canvas.RenderTransformProperty, defaultTransform);

                    double curAnimRatio = (yValues[iGroup, i]) / (pieTotal);
                    _pieAnimAngles.Add(animAngleStart + curAnimRatio / 2);
                    animAngleStart += curAnimRatio;
                }

                if (gradientXAML != null)
                {
                    SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0xe5);
                }
                else
                {
                    SetFillOnElement(pathElem, seriesColors[i]);
                }

                pathElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i]));

                // centroid of the triangle used for tooltips
                Point centroid = new Point((x1 + x2) / 3, (y1 + y2) / 3);
                SetExpandosOnElement(pathElem, iGroup, i, centroid);

                if (DisplayToolTip)
                {
                    pathElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                    pathElem.MouseLeave += new MouseEventHandler(HideToolTip);
                }

                pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

                pieStart += valueRatio;
                pieContainer.Children.Add(pathElem);
            }


            /*for (var i = 0; i< nPies; ++i)
             * {
             * // calculate the pie gradient:
             * pieContainer.appendChild(pieElems[i]);
             * }*/
        }