Esempio n. 1
0
        /// <summary>
        /// Calculate the values needed to properly display this <see cref="PieItem"/>.
        /// </summary>
        /// <param name="pane">
        /// A graphic device object to be drawn into.  This is normally e.Graphics from the
        /// PaintEventArgs argument to the Paint() method.
        /// </param>
        /// <param name="maxDisplacement">maximum slice displacement</param>
        private static void CalculatePieChartParams(GraphPane pane, ref double maxDisplacement)
        {
            string lblStr = " ";

            //loop thru slices and get total value and maxDisplacement
            double pieTotalValue = 0;

            foreach (PieItem curve in pane.CurveList)
            {
                if (curve.IsPie)
                {
                    pieTotalValue += curve._pieValue;
                    if (curve.Displacement > maxDisplacement)
                    {
                        maxDisplacement = curve.Displacement;
                    }
                }
            }

            double nextStartAngle = 0;

            //now loop thru and calculate the various angle values
            foreach (PieItem curve in pane.CurveList)
            {
                lblStr           = curve._labelStr;
                curve.StartAngle = (float)nextStartAngle;
                curve.SweepAngle = (float)(360 * curve.Value / pieTotalValue);
                curve.MidAngle   = curve.StartAngle + curve.SweepAngle / 2;
                nextStartAngle   = curve._startAngle + curve._sweepAngle;
                PieItem.BuildLabelString(curve);
            }
        }
Esempio n. 2
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="PieItem"/> object from which to copy</param>
 public PieItem(PieItem rhs)
     : base(rhs)
 {
     _pieValue             = rhs._pieValue;
     _fill                 = rhs._fill.Clone();
     this.Border           = rhs._border.Clone();
     _displacement         = rhs._displacement;
     _labelDetail          = rhs._labelDetail.Clone();
     _labelType            = rhs._labelType;
     _valueDecimalDigits   = rhs._valueDecimalDigits;
     _percentDecimalDigits = rhs._percentDecimalDigits;
 }
Esempio n. 3
0
        /// <summary>
        /// Build the string that will be displayed as the slice label as determined by
        /// <see cref="LabelType"/>.
        /// </summary>
        /// <param name="curve">reference to the <see cref="PieItem"/></param>
        private static void BuildLabelString(PieItem curve)
        {
            //set up label string formatting
            NumberFormatInfo labelFormat = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();

            labelFormat.NumberDecimalDigits    = curve._valueDecimalDigits;
            labelFormat.PercentPositivePattern = 1;                                             //no space between number and % sign
            labelFormat.PercentDecimalDigits   = curve._percentDecimalDigits;

            switch (curve._labelType)
            {
            case PieLabelType.Value:
                curve._labelStr = curve._pieValue.ToString("F", labelFormat);
                break;

            case PieLabelType.Percent:
                curve._labelStr = (curve._sweepAngle / 360).ToString("P", labelFormat);
                break;

            case PieLabelType.Name_Value:
                curve._labelStr = curve._label._text + ": " + curve._pieValue.ToString("F", labelFormat);
                break;

            case PieLabelType.Name_Percent:
                curve._labelStr = curve._label._text + ": " + (curve._sweepAngle / 360).ToString("P", labelFormat);
                break;

            case PieLabelType.Name_Value_Percent:
                curve._labelStr = curve._label._text + ": " + curve._pieValue.ToString("F", labelFormat) +
                                  " (" + (curve._sweepAngle / 360).ToString("P", labelFormat) + ")";
                break;

            case PieLabelType.Name:
                curve._labelStr = curve._label._text;
                break;

            case PieLabelType.None:
            default:
                break;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Calculate the <see cref="RectangleF"/> that will be used to define the bounding rectangle of
        /// the Pie.
        /// </summary>
        /// <remarks>This rectangle always lies inside of the <see cref="Chart.Rect"/>, and it is
        /// normally a square so that the pie itself is not oval-shaped.</remarks>
        /// <param name="g">
        /// A graphic device object to be drawn into.  This is normally e.Graphics from the
        /// PaintEventArgs argument to the Paint() method.
        /// </param>
        /// <param name="pane">
        /// A reference to the <see cref="GraphPane"/> object that is the parent or
        /// owner of this object.
        /// </param>
        /// <param name="scaleFactor">
        /// The scaling factor to be used for rendering objects.  This is calculated and
        /// passed down by the parent <see cref="GraphPane"/> object using the
        /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust
        /// font sizes, etc. according to the actual size of the graph.
        /// </param>
        /// <param name="chartRect">The <see cref="RectangleF"/> (normally the <see cref="Chart.Rect"/>)
        /// that bounds this pie.</param>
        /// <returns></returns>
        public static RectangleF CalcPieRect(Graphics g, GraphPane pane, float scaleFactor, RectangleF chartRect)
        {
            //want to draw the largest pie possible within ChartRect
            //but want to leave  5% slack around the pie so labels will not overrun clip area
            //largest pie is limited by the smaller of ChartRect.height or ChartRect.width...
            //this rect (nonExplRect)has to be re-positioned so that it's in the center of ChartRect.
            //Where ChartRect is almost a square - low Aspect Ratio -, need to contract pieRect so that there's some
            //room for labels, if they're visible.
            double     maxDisplacement = 0;
            RectangleF tempRect;               //= new RectangleF(0,0,0,0);

            RectangleF nonExplRect = chartRect;

            if (pane.CurveList.IsPieOnly)
            {
                if (nonExplRect.Width < nonExplRect.Height)
                {
                    //create slack rect
                    nonExplRect.Inflate(-(float)0.05F * nonExplRect.Height, -(float)0.05F * nonExplRect.Width);
                    //get the difference between dimensions
                    float delta = (nonExplRect.Height - nonExplRect.Width) / 2;
                    //make a square	so we end up with circular pie
                    nonExplRect.Height = nonExplRect.Width;
                    //keep the center point  the same
                    nonExplRect.Y += delta;
                }
                else
                {
                    nonExplRect.Inflate(-(float)0.05F * nonExplRect.Height, -(float)0.05F * nonExplRect.Width);
                    float delta = (nonExplRect.Width - nonExplRect.Height) / 2;
                    nonExplRect.Width = nonExplRect.Height;
                    nonExplRect.X    += delta;
                }
                //check aspect ratio
                double aspectRatio = chartRect.Width / chartRect.Height;
                //make an adjustment in rect size,as aspect ratio varies
                if (aspectRatio < 1.5)
                {
                    nonExplRect.Inflate(-(float)(.1 * (1.5 / aspectRatio) * nonExplRect.Width),
                                        -(float)(.1 * (1.5 / aspectRatio) * nonExplRect.Width));
                }

                //modify the rect to determine if any of the labels need to be wrapped....
                //first see if there's any exploded slices and if so, what's the max displacement...
                //also, might as well get all the display params we can
                PieItem.CalculatePieChartParams(pane, ref maxDisplacement);

                if (maxDisplacement != 0)                                        //need new rectangle if any slice exploded
                {
                    CalcNewBaseRect(maxDisplacement, ref nonExplRect);
                }

                foreach (PieItem slice in pane.CurveList)
                {
                    slice._boundingRectangle = nonExplRect;
                    //if exploded, need to re-calculate rectangle for slice
                    if (slice.Displacement != 0)
                    {
                        tempRect = nonExplRect;
                        slice.CalcExplodedRect(ref tempRect);
                        slice._boundingRectangle = tempRect;
                    }
                    //now get all the other slice specific drawing details, including need for wrapping label
                    slice.DesignLabel(g, pane, slice._boundingRectangle, scaleFactor);
                }
            }
            return(nonExplRect);
        }