Exemple #1
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]);
             * }*/
        }
Exemple #2
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]);
            }
        }
        private void _drawPerspectiveFunnel(
            Canvas fnlContainer,
            double quadWidth,
            double quadHeight,
            int iGroup)
        {
            ChartModel model = Model;

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

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

            // Number of segments
            int    nSeg  = yValues.GetUpperBound(1) + 1;
            double total = 0;

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

            List <UIElement> dataElems = DataElements;
            bool             animate   = (AnimationDuration > 0);

            string          funnelXAML = CurrentLookAndFeel.GetFunnelPathXAML();
            Path            pathElem;
            string          gradientXAML = CurrentLookAndFeel.GetElementGradientXAML();
            MatrixTransform defaultTransform;

            double x = 0, y = 0, slope = (quadWidth / 2.0) / quadHeight,
                   dx = quadWidth, dy, nextX, oldDx, nextY;

            // the ring height is 1/12 of the width
            double rx = dx / 2.0, ry = dx / 24.0, oldRx, oldRy;

            for (int i = nSeg - 1; i >= 0; --i)
            {
                double        valueRatio = (yValues[iGroup, i]) / (total);
                StringBuilder sb         = new StringBuilder();

                sb.Append("M").Append(x).Append(",").Append(y);
                sb.Append(" A").Append(rx).Append(",").Append(ry);
                sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(y);
                sb.Append(" A").Append(rx).Append(",").Append(ry);
                sb.Append(" 0 1,0 ").Append(x).Append(",").Append(y);

                oldDx = dx;
                oldRx = rx;
                oldRy = ry;
                dy    = (quadHeight) * valueRatio;
                nextY = y + dy;
                nextX = quadWidth / 2.0 - slope * (quadHeight - (nextY));
                dx    = quadWidth - nextX;
                rx    = (dx - nextX) / 2.0;
                ry    = rx / 12.0;

                if (i != 0)
                {
                    sb.Append("L").Append(nextX).Append(",").Append(nextY);
                    sb.Append("A").Append(rx).Append(",").Append(ry);
                    sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(nextY);
                    sb.Append("L").Append(oldDx).Append(",").Append(y);
                }
                else
                {
                    double startTipY = (dy / 3.0 <= _MAX_FUNNEL_TIP)?y + (dy - dy / 3.0):
                                       quadHeight - _MAX_FUNNEL_TIP;

                    nextX = quadWidth / 2.0 - slope * (quadHeight - (startTipY));
                    dx    = quadWidth - nextX;

                    rx = (dx - nextX) / 2.0;
                    ry = rx / 12.0;

                    sb.Append(" L").Append(nextX).Append(",").Append(startTipY);
                    sb.Append(" L").Append(nextX).Append(",").Append(quadHeight);
                    sb.Append(" A").Append(rx).Append(",").Append(ry);
                    sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(quadHeight);
                    sb.Append(" A").Append(rx).Append(",").Append(ry);
                    sb.Append(" 0 1,0 ").Append(nextX).Append(",").Append(quadHeight);
                    sb.Append(" A").Append(rx).Append(",").Append(ry);
                    sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(quadHeight);
                    sb.Append(" L").Append(dx).Append(",").Append(startTipY);
                    sb.Append(" L").Append(oldDx).Append(",").Append(y);
                }

                pathElem = CreatePathFromXAMLAndData(funnelXAML, sb);

                if (animate)
                {
                    dataElems.Add(pathElem);
                    defaultTransform = new MatrixTransform();
                    Matrix m = new Matrix(0, 0, 0, 0, 0, 0);
                    defaultTransform.Matrix  = m;
                    pathElem.RenderTransform = defaultTransform;
                }

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

                (pathElem.Data as PathGeometry).FillRule = FillRule.Nonzero;
                pathElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[i]));
                pathElem.SetValue(Canvas.ZIndexProperty, i + 1);

                SetExpandosOnElement(pathElem, iGroup, i, new Point(nextX + (dx - nextX) / 2.0, y + (nextY - y) / 2.0));
                if (DisplayToolTip)
                {
                    pathElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                    pathElem.MouseLeave += new MouseEventHandler(HideToolTip);
                }

                pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

                fnlContainer.Children.Add(pathElem);
                y = nextY;
                x = nextX;
            }
        }