CUstom Report Item Report Service display arrow as the indictor of Range Chart

public class Spread
    {
        public string AssetClass { get; set; }
        public double StartValue { get; set; }
        public double EndValue { get; set; }

        public static List<Spread> GetSpreads()
        {
            Random r1 = new Random(), r2 = new Random();
            List<Spread> spreads = new List<Spread>();
            for (int i = 0; i < 20; i++)
            {
                int x=r1.Next(30,150);
                Spread s = new Spread {
                    AssetClass = "Asset " + i,
                    StartValue =x,
                    EndValue =(int)(x+ x*(r2.NextDouble()-0.5)/3)
                };
                spreads.Add(s);

            }
            return spreads;
        }
    }
  void DrawSpreadChart(Graphics g, Spread[] spreads)
        {
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
            DrawCaptial(g);
            DrawSubCaptial(g);
            DrawYLebal(g);
            DrawYAxis(spreads, g);
            DrawXLebal(g);
            DrawXAxis(spreads, g);
            DrawGrid(g);
            DrawIndictor(spreads, g); 
        }

        //15 properties can be set for Spread chart

        int spread_width = 600;//1.Width of Spread Chart
        int spread_hight = 400;//2.Hight of Spread Chart

        #region Captial

        string caption = "European GSM Week Spreads";//3.Caption of Spread Chart
        string fontFamily = "Times New Roman";//4.Font Family of Spread Chart
        int captionSize = 8;//5.Caption Size 
        int captionPxes = 8;
        void DrawCaptial(Graphics g)
        {
           
            using (Font font = new Font(fontFamily , captionSize , FontStyle.Bold, GraphicsUnit.Point))
            {
                captionPxes =(int)Math.Ceiling ( font.GetHeight()); 
                Rectangle rect = new Rectangle(0, 0, spread_width,captionPxes );

                // Create a StringFormat object with the each line of text, and the block 
                // of text centered on the page.
                StringFormat stringFormat = new StringFormat();
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center;

                // Draw the text and the surrounding rectangle.
               g.DrawString(caption, font, Brushes.Black , rect, stringFormat);
               //g.DrawRectangle(Pens.Black, rect);
            }
        }

        string subCaption = "(<200bps)";//6.Sub-Caption of Spread Chart
        int subCaptionSize = 6; //7.Sub-Caption size
        int subCpatialPxes = 6;
        void DrawSubCaptial(Graphics g)
        {

            using (Font font = new Font(fontFamily, subCaptionSize, FontStyle.Bold, GraphicsUnit.Point))
            {
                subCpatialPxes =(int)Math.Ceiling ( font.GetHeight());
                Rectangle rect = new Rectangle(0, captionPxes  , spread_width ,subCpatialPxes  );

                // Create a StringFormat object with the each line of text, and the block 
                // of text centered on the page.
                StringFormat stringFormat = new StringFormat();
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center  ;

                // Draw the text and the surrounding rectangle.
                g.DrawString(subCaption , font, Brushes.Black, rect, stringFormat);
                //g.DrawRectangle(Pens.Red, rect);
            }
        }

        #endregion 

        #region Y Label

        string ylabel = "Asset Class";//8.Label of Y Axis
        int yLabelSize = 8;//9.Label font size
        int yLabelPxes;
        void DrawYLebal(Graphics g)
        {
            
            using (Font font = new Font(fontFamily, yLabelSize, FontStyle.Bold , GraphicsUnit.Point))
            {
                yLabelPxes=(int)Math .Ceiling (font.GetHeight ());
                Rectangle rect = new Rectangle(0, captionPxes +subCpatialPxes,yLabelPxes   , spread_hight-captionPxes -subCpatialPxes  );

                StringFormat stringFormat = new StringFormat();
                stringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
                stringFormat.Alignment = StringAlignment.Center ;
                stringFormat.LineAlignment = StringAlignment.Center;

                g.ResetTransform();
                g.DrawString(ylabel , font, Brushes.Black , rect , stringFormat);
                //g.DrawRectangle(Pens.Black, rect);
            }
        }

        #endregion 

        #region Y Axis

        int yGradeSize = 6;//10.Font size of Y Axis Grade
        double yGradeHight = 10;
        int maxYGradePxes = 10;
        int gradeLen = 2;//11.Grade Length for X/Y Axis
        int endY;
        int startY;
        int startX;
        int yCount;
        void DrawYAxis( Spread[] spreads,Graphics g)
        {
            yCount = spreads.Length;
            maxYGradePxes = (int)Math.Ceiling(spreads.Max(x => MeasueLegth(x.AssetClass, yGradeSize, FontStyle.Bold , g).Width));
            startY = captionPxes + subCpatialPxes;
            startX = yLabelPxes + maxYGradePxes + gradeLen;
           endY = spread_hight - GetHightPxes(xLabelSize, FontStyle.Bold) - GetHightPxes(xGradeSize, FontStyle.Bold );
            yGradeHight = (endY -startY )*1.0/spreads .Count() ;
           
            g.DrawLine(Pens.Black,
                new Point(startX , startY), 
                new Point(startX , endY));
            
            using (Font font = new Font(fontFamily, yGradeSize , FontStyle.Bold , GraphicsUnit.Point))
            {
                for (int i = 0; i < spreads.Length; i++)
                {
                    int y = (int)(startY + yGradeHight * i);
                    Rectangle rect = new Rectangle(yLabelPxes, y, maxYGradePxes, (int)yGradeHight);
                    // Create a StringFormat object with the each line of text, and the block 
                    // of text centered on the page.
                    StringFormat stringFormat = new StringFormat();
                    stringFormat.Alignment = StringAlignment.Far;
                    stringFormat.LineAlignment = StringAlignment.Center;

                    // Draw the text and the surrounding rectangle.
                    g.DrawString(spreads[i].AssetClass, font, Brushes.Black, rect, stringFormat);
                    //g.DrawRectangle(Pens.Black, rect);
                    g.DrawLine(Pens.Black,
                        new Point(yLabelPxes + maxYGradePxes , y),
                        new Point(yLabelPxes + maxYGradePxes + gradeLen, y));
                }

                g.DrawLine(Pens.Black,
                       new Point(yLabelPxes + maxYGradePxes, endY ),
                       new Point(yLabelPxes + maxYGradePxes + gradeLen, endY ));
            }

        }


        #endregion 

        #region X Label

        string xLabel = "Spreads";//12.Label of X Axis
        int xLabelSize = 8;//13.Size of X Axis Label
        int xLabelHightPxes = 10;

        void DrawXLebal(Graphics g)
        {
            using (Font font = new Font(fontFamily, xLabelSize , FontStyle.Bold, GraphicsUnit.Point))
            {
                xLabelHightPxes = (int)Math.Ceiling(font.GetHeight());
                Rectangle rect = new Rectangle(yLabelPxes +maxYGradePxes +gradeLen , 
                    spread_hight -xLabelHightPxes , spread_width-yLabelPxes -maxYGradePxes -gradeLen , xLabelHightPxes );

                // Create a StringFormat object with the each line of text, and the block 
                // of text centered on the page.
                StringFormat stringFormat = new StringFormat();
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.LineAlignment = StringAlignment.Center;

                // Draw the text and the surrounding rectangle.
                g.DrawString(xLabel , font, Brushes.Black, rect, stringFormat);
                //g.DrawRectangle(Pens.Red, rect);
            }
        }

        #endregion 

        #region X Axis

        int xGradeSize = 6; //14.Size of X Grade
        int xInternal = 10; //15.The step length of X Axis
        double xgradwith;
        int xcount;
        int minX;
        int maxX;
        int endX;
        void DrawXAxis(Spread[] spreads, Graphics g)
        {
            var xs = spreads.SelectMany(x => new double[] { x.StartValue, x.EndValue }).ToArray();
            double _minX = xs.Min(), _maxX = xs.Max();
            minX = ((int)Math.Floor ( _minX / xInternal)) * xInternal;
            maxX = ((int)Math.Ceiling(_maxX / xInternal)) * xInternal;
            int margRight = (int)Math.Ceiling(MeasueLegth(maxX.ToString(), xGradeSize, FontStyle.Bold , g).Width / 2);
            endX = spread_width - margRight;
            xcount = (maxX - minX) / xInternal+1;
            xgradwith = (spread_width - margRight - startX)*1.0 / xcount;           
            g.DrawLine(Pens.Black,
                new Point(startX , endY ),
                new Point(spread_width -margRight , endY));

            using (Font font = new Font(fontFamily, xGradeSize , FontStyle.Bold , GraphicsUnit.Point))
            {
                for (int i = 0; i <= xcount; i++)
                {
                    string xg = (minX + i * xInternal).ToString();
                    var xgS = MeasueLegth(xg, xGradeSize, FontStyle.Regular, g) ;
                    double xv = startX + i * xgradwith;
                    
                    Rectangle rect = new Rectangle((int)(xv-xgS.Width/2), 
                        endY +gradeLen ,
                        (int) Math.Ceiling( xgS.Width) ,
                        (int) Math.Ceiling( xgS .Height));
                    // Create a StringFormat object with the each line of text, and the block 
                    // of text centered on the page.
                    StringFormat stringFormat = new StringFormat();
                    stringFormat.Alignment = StringAlignment.Center ;
                    stringFormat.LineAlignment = StringAlignment.Center;

                    // Draw the text and the surrounding rectangle.
                    g.DrawString(xg, font, Brushes.Black, rect, stringFormat);
                    //g.DrawRectangle(Pens.Black, rect);

                    g.DrawLine(Pens.Black,
                        new Point((int)xv , endY ),
                        new Point((int)xv  , endY +gradeLen ));
                } 
            }
        }
        #endregion 

        #region Grids
         
        void DrawGrid(Graphics g)
        {
            int gridMarg =(int) Math.Floor( yGradeHight /3);
            for (int r = 0; r <= yCount / 3; r++)
            {
                int y0 = (int)(startY + 3*r * yGradeHight +gridMarg );
                if (r == 0)
                    y0 = startY ;
                int y1 = (int)(startY + 3 * (r + 1) * yGradeHight - gridMarg);
                if (y1 > endY)
                    y1 = endY;
                
                for (int c = 1; c <= xcount; c++)
                {
                    int x =(int)( startX + c * xgradwith);
                    g.DrawLine(Pens.LightGray , x, y0, x, y1);
                }
            }
        }

        #endregion

        #region Indictor

        int arrow_rect_half_hight = 2; //a halft of the hight of the rectangle of the arrow
        int arrow_triangle_add_half_hight = 2;//a half of the triangle ofthe arrow  more than  arrow_rect_half_hight 
        int arrow_triagle_width = 8;//the width of the triangle ofthe arrow

        void DrawIndictor(Spread[] spreads, Graphics g)
        {
            double unit = (endX - startX) / (maxX - minX);
            for (int i = 0; i < spreads.Length; i++)
            {
                Spread s = spreads[i];
                int y = (int)(startY + (i + 0.5) * yGradeHight);
                int x0 = (int)(startX + (Math.Min(s.StartValue, s.EndValue) - minX) * unit);
                int x1 = (int)(startX + (Math.Max(s.StartValue, s.EndValue) - minX) * unit);
                Point[] ps;
                if (x1 - x0 < arrow_triagle_width)
                    ps = new Point[] { 
                        new Point(x0,y-arrow_rect_half_hight ),
                        new Point(x1,y-arrow_rect_half_hight ),
                        new Point(x1,y+arrow_rect_half_hight ),
                        new Point (x0,y+arrow_rect_half_hight ), 
                        new Point(x0,y-arrow_rect_half_hight )};
                else if (x1 - x0 == arrow_triagle_width)
                {
                    ps = new Point[] { 
                        new Point(x0,y-arrow_rect_half_hight-arrow_triangle_add_half_hight  ),
                        new Point(x1,y ), 
                        new Point (x0,y+arrow_rect_half_hight+arrow_triangle_add_half_hight  ),
                        new Point(x0,y-arrow_rect_half_hight-arrow_triangle_add_half_hight  )};
                }
                else if (s.EndValue > s.StartValue)
                {
                    ps = new Point[] {
                        new Point(x0, y-arrow_rect_half_hight ),
                        new Point(x1-arrow_triagle_width , y-arrow_rect_half_hight),
                        new Point(x1-arrow_triagle_width , y-arrow_rect_half_hight-arrow_triangle_add_half_hight),
                        new Point(x1, y) ,
                        new Point(x1-arrow_triagle_width , y+arrow_rect_half_hight+arrow_triangle_add_half_hight),                   
                        new Point(x1-arrow_triagle_width , y+arrow_rect_half_hight),
                        new Point(x0, y+arrow_rect_half_hight ), 
                        new Point(x0, y-arrow_rect_half_hight ),};
                }
                else
                {
                    ps = new Point[] {
                        new Point(x1, y-arrow_rect_half_hight ),
                        new Point(x0+arrow_triagle_width , y-arrow_rect_half_hight),
                        new Point(x0+arrow_triagle_width , y-arrow_rect_half_hight-arrow_triangle_add_half_hight),
                        new Point(x0, y) ,
                        new Point(x0+arrow_triagle_width , y+arrow_rect_half_hight+arrow_triangle_add_half_hight),                   
                        new Point(x0+arrow_triagle_width , y+arrow_rect_half_hight),
                        new Point(x1, y+arrow_rect_half_hight ), 
                        new Point(x1, y-arrow_rect_half_hight ),};
                }
                if (s.StartValue < s.EndValue)
                    g.FillPolygon(Brushes.Red, ps);
                else
                    g.FillPolygon(Brushes.Green, ps);
                
            }           
        }

        #endregion

        #region Helpers

        int GetHightPxes(int size, FontStyle style)
        {
            using (Font font = new Font(fontFamily, size ,style, GraphicsUnit.Point))
            {
                return (int)Math.Ceiling(font.GetHeight());
            }
        }

        SizeF MeasueLegth(string txt, int size, FontStyle style, Graphics g)
        { 
            using (Font font = new Font(fontFamily, size ,style, GraphicsUnit.Point))
            {
                return g.MeasureString (txt ,font ); 
            }
        }

        #endregion 
原文地址:https://www.cnblogs.com/mjgb/p/2952478.html