예제 #1
0
        public override AxisLimits2D GetLimits()
        {
            var limits = new AxisLimits2D();

            foreach (var box in boxAndWhiskers)
            {
                limits.ExpandX(box.xPosition - box.box.width / 2, box.xPosition + box.box.width / 2);
                limits.ExpandX(box.xPosition - box.whisker.width / 2, box.xPosition + box.whisker.width / 2);
                limits.ExpandX(box.xPosition - box.midline.width / 2, box.xPosition + box.midline.width / 2);
                limits.ExpandY(box.box.min, box.box.max);
                limits.ExpandY(box.whisker.min, box.whisker.max);
                limits.ExpandY(box.midline.position, box.midline.position);

                if (box.points.Count() > 0) //Cannot call Min() or Max() on empty list
                {
                    limits.ExpandY(box.points.Min(), box.points.Max());
                }
            }
            return(limits);
        }
예제 #2
0
        public override AxisLimits2D GetLimits()
        {
            var limits = new AxisLimits2D();

            foreach (var box in boxAndWhiskers)
            {
                double pointSpread = (Math.Abs(box.dataPoints.offsetFraction) + box.dataPoints.spreadFraction) * box.box.width / 2;
                limits.ExpandX(box.xPosition - pointSpread, box.xPosition + pointSpread);
                limits.ExpandX(box.xPosition - box.box.width / 2, box.xPosition + box.box.width / 2);
                limits.ExpandX(box.xPosition - box.whisker.width / 2, box.xPosition + box.whisker.width / 2);
                limits.ExpandX(box.xPosition - box.midline.width / 2, box.xPosition + box.midline.width / 2);
                limits.ExpandY(box.box.min, box.box.max);
                limits.ExpandY(box.whisker.min, box.whisker.max);
                limits.ExpandY(box.midline.position, box.midline.position);

                if (box.dataPoints.values.Count() > 0) //Cannot call Min() or Max() on empty list
                {
                    limits.ExpandY(box.dataPoints.values.Min(), box.dataPoints.values.Max());
                }
            }
            return(limits);
        }
예제 #3
0
        public override void Render(Settings settings)
        {
            double[] proportions = values.Select(x => x / values.Sum()).ToArray();

            int outlineWidth      = 1;
            int sliceOutlineWidth = 0;

            if (explodedChart)
            {
                pen.Color         = settings.misc.dataBackgroundColor;
                outlineWidth      = 20;
                sliceOutlineWidth = 1;
            }

            double       minAxisScale   = Math.Min(settings.xAxisScale, settings.yAxisScale);
            AxisLimits2D limits         = GetLimits();
            double       centreX        = (limits.x1 + limits.x2) / 2;
            double       centreY        = (limits.y1 + limits.y2) / 2;
            double       diameter       = 2; // Unit circle
            float        diameterPixels = (float)(minAxisScale * diameter);
            string       fontName       = Config.Fonts.GetSansFontName();
            float        fontSize       = 12;

            // record label details and draw them after slices to prevent cover-ups
            double[] labelXs      = new double[values.Length];
            double[] labelYs      = new double[values.Length];
            string[] labelStrings = new string[values.Length];

            RectangleF boundingRectangle = new RectangleF((float)settings.GetPixelX(centreX) - diameterPixels / 2, (float)settings.GetPixelY(centreY) - diameterPixels / 2, diameterPixels, diameterPixels);

            double start = -90;

            for (int i = 0; i < values.Length; i++)
            {
                // determine where the slice is to be drawn
                double sweep       = proportions[i] * 360;
                double sweepOffset = explodedChart ? -1 : 0;
                double angle       = (Math.PI / 180) * ((sweep + 2 * start) / 2);
                double xOffset     = explodedChart ? 3 * Math.Cos(angle) : 0;
                double yOffset     = explodedChart ? 3 * Math.Sin(angle) : 0;

                // record where and what to label the slice
                double sliceLabelR = 0.5 * minAxisScale;
                labelXs[i] = (boundingRectangle.X + diameterPixels / 2 + xOffset + Math.Cos(angle) * sliceLabelR);
                labelYs[i] = (boundingRectangle.Y + diameterPixels / 2 + yOffset + Math.Sin(angle) * sliceLabelR);
                string sliceLabelValue      = (showValues) ? $"{values[i]}" : "";
                string sliceLabelPercentage = (showPercentages) ? $"{proportions[i] * 100:f1}%" : "";
                string sliceLabelName       = (showLabels) ? groupNames[i] : "";
                labelStrings[i] = $"{sliceLabelValue}\n{sliceLabelPercentage}\n{sliceLabelName}".Trim();

                brush.Color = colors[i];
                settings.gfxData.FillPie(brush, (int)(boundingRectangle.X + xOffset), (int)(boundingRectangle.Y + yOffset), boundingRectangle.Width, boundingRectangle.Height, (float)start, (float)(sweep + sweepOffset));

                if (explodedChart)
                {
                    pen.Width = sliceOutlineWidth;
                    settings.gfxData.DrawPie(pen, (int)(boundingRectangle.X + xOffset), (int)(boundingRectangle.Y + yOffset), boundingRectangle.Width, boundingRectangle.Height, (float)start, (float)(sweep + sweepOffset));
                }
                start += sweep;
            }

            brush.Color = Color.White;
            var font = new Font(fontName, fontSize);

            for (int i = 0; i < values.Length; i++)
            {
                if (!string.IsNullOrWhiteSpace(labelStrings[i]))
                {
                    settings.gfxData.DrawString(labelStrings[i], font, brush,
                                                (float)labelXs[i], (float)labelYs[i], settings.misc.sfCenterCenter);
                }
            }

            pen.Width = outlineWidth;
            settings.gfxData.DrawEllipse(pen, boundingRectangle.X, boundingRectangle.Y, boundingRectangle.Width, boundingRectangle.Height);
        }
예제 #4
0
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            using (Graphics gfx = GDI.Graphics(bmp, lowQuality))
                using (Pen backgroundPen = GDI.Pen(dataBackgroundColor))
                    using (Pen outlinePen = GDI.Pen(outlineColor, outlineSize))
                        using (Brush brush = GDI.Brush(Color.Black))
                            using (Brush fontBrush = GDI.Brush(centerTextColor))
                                using (Font sliceFont = GDI.Font(null, sliceFontSize))
                                    using (Font centerFont = GDI.Font(null, centerFontSize))
                                        using (StringFormat sfCenter = new StringFormat()
                                        {
                                            LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center
                                        })
                                        {
                                            double[] proportions = values.Select(x => x / values.Sum()).ToArray();

                                            AxisLimits2D limits         = GetLimits();
                                            double       centreX        = limits.xCenter;
                                            double       centreY        = limits.yCenter;
                                            float        diameterPixels = .9f * Math.Min(dims.DataWidth, dims.DataHeight);

                                            // record label details and draw them after slices to prevent cover-ups
                                            double[] labelXs      = new double[values.Length];
                                            double[] labelYs      = new double[values.Length];
                                            string[] labelStrings = new string[values.Length];

                                            RectangleF boundingRectangle = new RectangleF(
                                                dims.GetPixelX(centreX) - diameterPixels / 2,
                                                dims.GetPixelY(centreY) - diameterPixels / 2,
                                                diameterPixels,
                                                diameterPixels);

                                            if (donutSize > 0)
                                            {
                                                GraphicsPath graphicsPath               = new GraphicsPath();
                                                float        donutDiameterPixels        = (float)donutSize * diameterPixels;
                                                RectangleF   donutHoleBoundingRectangle = new RectangleF(
                                                    dims.GetPixelX(centreX) - donutDiameterPixels / 2,
                                                    dims.GetPixelY(centreY) - donutDiameterPixels / 2,
                                                    donutDiameterPixels,
                                                    donutDiameterPixels);
                                                graphicsPath.AddEllipse(donutHoleBoundingRectangle);
                                                Region excludedRegion = new Region(graphicsPath);
                                                gfx.ExcludeClip(excludedRegion);
                                            }

                                            double start = -90;
                                            for (int i = 0; i < values.Length; i++)
                                            {
                                                // determine where the slice is to be drawn
                                                double sweep       = proportions[i] * 360;
                                                double sweepOffset = explodedChart ? -1 : 0;
                                                double angle       = (Math.PI / 180) * ((sweep + 2 * start) / 2);
                                                double xOffset     = explodedChart ? 3 * Math.Cos(angle) : 0;
                                                double yOffset     = explodedChart ? 3 * Math.Sin(angle) : 0;

                                                // record where and what to label the slice
                                                double sliceLabelR = 0.35 * diameterPixels;
                                                labelXs[i] = (boundingRectangle.X + diameterPixels / 2 + xOffset + Math.Cos(angle) * sliceLabelR);
                                                labelYs[i] = (boundingRectangle.Y + diameterPixels / 2 + yOffset + Math.Sin(angle) * sliceLabelR);
                                                string sliceLabelValue      = (showValues) ? $"{values[i]}" : "";
                                                string sliceLabelPercentage = showPercentages ? $"{proportions[i] * 100:f1}%" : "";
                                                string sliceLabelName       = (showLabels && groupNames != null) ? groupNames[i] : "";
                                                labelStrings[i] = $"{sliceLabelValue}\n{sliceLabelPercentage}\n{sliceLabelName}".Trim();

                                                ((SolidBrush)brush).Color = colors[i];
                                                gfx.FillPie(brush: brush,
                                                            x: (int)(boundingRectangle.X + xOffset),
                                                            y: (int)(boundingRectangle.Y + yOffset),
                                                            width: boundingRectangle.Width,
                                                            height: boundingRectangle.Height,
                                                            startAngle: (float)start,
                                                            sweepAngle: (float)(sweep + sweepOffset));

                                                if (explodedChart)
                                                {
                                                    gfx.DrawPie(
                                                        pen: backgroundPen,
                                                        x: (int)(boundingRectangle.X + xOffset),
                                                        y: (int)(boundingRectangle.Y + yOffset),
                                                        width: boundingRectangle.Width,
                                                        height: boundingRectangle.Height,
                                                        startAngle: (float)start,
                                                        sweepAngle: (float)(sweep + sweepOffset));
                                                }
                                                start += sweep;
                                            }

                                            ((SolidBrush)brush).Color = Color.White;
                                            for (int i = 0; i < values.Length; i++)
                                            {
                                                if (!string.IsNullOrWhiteSpace(labelStrings[i]))
                                                {
                                                    gfx.DrawString(labelStrings[i], sliceFont, brush, (float)labelXs[i], (float)labelYs[i], sfCenter);
                                                }
                                            }

                                            if (outlineSize > 0)
                                            {
                                                gfx.DrawEllipse(
                                                    outlinePen,
                                                    boundingRectangle.X,
                                                    boundingRectangle.Y,
                                                    boundingRectangle.Width,
                                                    boundingRectangle.Height);
                                            }

                                            gfx.ResetClip();

                                            if (centerText != null)
                                            {
                                                gfx.DrawString(centerText, centerFont, fontBrush, dims.GetPixelX(0), dims.GetPixelY(0), sfCenter);
                                            }

                                            if (explodedChart)
                                            {
                                                // draw a background-colored circle around the perimeter to make it look like all pieces are the same size
                                                backgroundPen.Width = 20;
                                                gfx.DrawEllipse(
                                                    pen: backgroundPen,
                                                    x: boundingRectangle.X,
                                                    y: boundingRectangle.Y,
                                                    width: boundingRectangle.Width,
                                                    height: boundingRectangle.Height);
                                            }
                                        }
        }
예제 #5
0
        public override void Render(Settings settings)
        {
            double[] proportions = values.Select(x => x / values.Sum()).ToArray();

            int sliceOutlineWidth = 0;

            if (explodedChart)
            {
                pen.Color         = settings.DataBackground.Color; // TODO: will fail if data background is transparent
                sliceOutlineWidth = 1;
            }

            AxisLimits2D limits         = GetLimits();
            double       centreX        = limits.xCenter;
            double       centreY        = limits.yCenter;
            float        diameterPixels = .9f * Math.Min(settings.dataSize.Width, settings.dataSize.Height);
            string       fontName       = Config.Fonts.GetSansFontName();
            float        fontSize       = 12;

            // record label details and draw them after slices to prevent cover-ups
            double[] labelXs      = new double[values.Length];
            double[] labelYs      = new double[values.Length];
            string[] labelStrings = new string[values.Length];

            RectangleF boundingRectangle = new RectangleF((float)settings.GetPixelX(centreX) - diameterPixels / 2, (float)settings.GetPixelY(centreY) - diameterPixels / 2, diameterPixels, diameterPixels);

            if (donutSize > 0)
            {
                GraphicsPath graphicsPath               = new GraphicsPath();
                float        donutDiameterPixels        = (float)donutSize * diameterPixels;
                RectangleF   donutHoleBoundingRectangle = new RectangleF((float)settings.GetPixelX(centreX) - donutDiameterPixels / 2, (float)settings.GetPixelY(centreY) - donutDiameterPixels / 2, donutDiameterPixels, donutDiameterPixels);
                graphicsPath.AddEllipse(donutHoleBoundingRectangle);
                Region excludedRegion = new Region(graphicsPath);
                settings.gfxData.ExcludeClip(excludedRegion);
            }

            double start = -90;

            for (int i = 0; i < values.Length; i++)
            {
                // determine where the slice is to be drawn
                double sweep       = proportions[i] * 360;
                double sweepOffset = explodedChart ? -1 : 0;
                double angle       = (Math.PI / 180) * ((sweep + 2 * start) / 2);
                double xOffset     = explodedChart ? 3 * Math.Cos(angle) : 0;
                double yOffset     = explodedChart ? 3 * Math.Sin(angle) : 0;

                // record where and what to label the slice
                double sliceLabelR = 0.35 * diameterPixels;
                labelXs[i] = (boundingRectangle.X + diameterPixels / 2 + xOffset + Math.Cos(angle) * sliceLabelR);
                labelYs[i] = (boundingRectangle.Y + diameterPixels / 2 + yOffset + Math.Sin(angle) * sliceLabelR);
                string sliceLabelValue      = (showValues) ? $"{values[i]}" : "";
                string sliceLabelPercentage = showPercentages ? $"{proportions[i] * 100:f1}%" : "";
                string sliceLabelName       = (showLabels) ? groupNames[i] : "";
                labelStrings[i] = $"{sliceLabelValue}\n{sliceLabelPercentage}\n{sliceLabelName}".Trim();

                brush.Color = colors[i];
                settings.gfxData.FillPie(brush: brush,
                                         x: (int)(boundingRectangle.X + xOffset),
                                         y: (int)(boundingRectangle.Y + yOffset),
                                         width: boundingRectangle.Width,
                                         height: boundingRectangle.Height,
                                         startAngle: (float)start,
                                         sweepAngle: (float)(sweep + sweepOffset));

                if (explodedChart)
                {
                    pen.Color = settings.DataBackground.Color; // TODO: will fail if data background is transparent
                    pen.Width = sliceOutlineWidth;
                    settings.gfxData.DrawPie(
                        pen: pen,
                        x: (int)(boundingRectangle.X + xOffset),
                        y: (int)(boundingRectangle.Y + yOffset),
                        width: boundingRectangle.Width, boundingRectangle.Height,
                        startAngle: (float)start,
                        sweepAngle: (float)(sweep + sweepOffset));
                }
                start += sweep;
            }

            brush.Color = Color.White;
            var font = new Font(fontName, fontSize);

            for (int i = 0; i < values.Length; i++)
            {
                if (!string.IsNullOrWhiteSpace(labelStrings[i]))
                {
                    settings.gfxData.DrawString(labelStrings[i], font, brush,
                                                (float)labelXs[i], (float)labelYs[i], settings.misc.sfCenterCenter);
                }
            }

            if (outlineSize > 0)
            {
                pen.Width = outlineSize;
                pen.Color = outlineColor;
                settings.gfxData.DrawEllipse(pen, boundingRectangle.X, boundingRectangle.Y, boundingRectangle.Width, boundingRectangle.Height);
            }

            settings.gfxData.ResetClip();

            if (centerText != null)
            {
                brush.Color = centerTextColor;
                Font donutHoleFont = new Font(fontName, centerTextSize);
                settings.gfxData.DrawString(centerText, donutHoleFont, brush, settings.GetPixel(0, 0), settings.misc.sfCenterCenter);
                donutHoleFont.Dispose();
            }

            if (explodedChart)
            {
                // draw a background-colored circle around the perimeter to make it look like all pieces are the same size
                pen.Width = 20;
                settings.gfxData.DrawEllipse(
                    pen: pen,
                    x: boundingRectangle.X,
                    y: boundingRectangle.Y,
                    width: boundingRectangle.Width,
                    height: boundingRectangle.Height);
            }
        }
예제 #6
0
 public void SetLimits(AxisLimits2D limits, int xAxisIndex, int yAxisIndex)
 {
     XAxes[xAxisIndex].SetLimits(limits.X1, limits.X2);
     YAxes[yAxisIndex].SetLimits(limits.Y1, limits.Y2);
 }