PDFSharpでレーダーチャートを作成してみる

PDFSharpでレーダーチャートを作成してみる。
環境はVisual Studio 2015、ASP.net だけど、他でも利用できると思う。
以下、サンプルソースコード。

```c#:c#
        /// <summary>
        /// レーダーチャートを描画する
        /// </summary>
        /// <param name="graphics">XGraphics</param>
        /// <param name="x">描画領域のX開始位置</param>
        /// <param name="y">描画領域のY開始位置</param>
        /// <param name="perfect">満点</param>
        /// <param name="score">各点数の配列(配列の個数だけ梯子を作成)</param>
        private void CrateRader(XGraphics graphics, double x, double y,double perfect, double[] score)
        {
            //ベースになる領域
            const double base_width = 200;//描画領域の幅
            const double base_hight = 200;//描画領域の高さ
            const double radius = 100;//半径
            const double ellipse = 10;//枠線カド丸サイズ

            double tick = radius / perfect;//目盛の幅
            double[,] pos = new double[2,score.GetLength(0)];//点数の位置

            XPen pen = new XPen(XColors.Gray, 1);//梯子
            XPen pen_tick = new XPen(XColors.Gray, 2);//目盛
            XPen pen_score = new XPen(XColors.Red, 4);//点数(頂点)
            XPen pen_bridge = new XPen(XColors.Red, 1);//点数と点数を結ぶ線

            XPen pen_frame = new XPen(XColors.Black, 1);//レーダーチャートを囲む枠

            //枠
            graphics.DrawRoundedRectangle(pen_frame, x, y, base_width, base_hight, ellipse, ellipse);

            //レーダーチャート
            double dec = 360 / score.GetLength(0);//角度の増分=360÷scoreの個数
            double deg = 0;//梯子を伸ばす角度
            for (int line = 0; line < score.GetLength(0); line++)
            {
                double x1 = x + radius + (get_sin(deg) * radius);//斜辺xSinθ
                double y1 = y + radius - (get_cos(deg) * radius);//Cosθ
                double x2 = x + base_width / 2;//中心位置は固定
                double y2 = y + base_hight / 2;//中心位置は固定
                graphics.DrawLine(pen, x1, y1, x2, y2);//放射状の線

                //点数の位置の初期化
                pos[0, line] = 0;
                pos[1, line] = 0;

                for (int j=1; j <= perfect; j++)//目盛
                {
                    double tickx = x + radius + (get_sin(deg) * (tick * j));
                    double ticky = y + radius - (get_cos(deg) * (tick * j));
                    graphics.DrawRectangle(pen_tick, tickx, ticky, 0, 0);

                    //点数
                    if (j == score[line])
                    {
                        pos[0, line] = tickx;//点数のx軸を保存
                        pos[1, line] = ticky;//点数のy軸を保存
                    }
                }//目盛
                deg += dec;//次の描画角度
            }//line

            //点数を線で結ぶ
            for (int line = 0; line < score.GetLength(0); line++)
            {
                if(line == score.GetLength(0) - 1)//最後の頂点と先頭の頂点を結ぶ
                {
                    graphics.DrawLine(pen_bridge, pos[0, line], pos[1, line], pos[0, 0], pos[1, 0]);
                }
                else//頂点と次の頂点を結ぶ
                {
                    graphics.DrawLine(pen_bridge, pos[0, line], pos[1, line], pos[0, line + 1], pos[1, line + 1]);
                }
                graphics.DrawEllipse(pen_score, pos[0, line], pos[1, line], 0, 0);//点数(頂点)
            }//点数を線で結ぶ
        }

        /// <summary>
        /// sin
        /// </summary>
        /// <param name="deg">角度</param>
        /// <returns></returns>
        private double get_sin(double deg)
        {
            double rad = System.Math.PI * deg / 180.0;//ラジアンに変換
            return System.Math.Sin(rad);
        }

        /// <summary>
        /// cos
        /// </summary>
        /// <param name="deg">角度</param>
        /// <returns></returns>
        private double get_cos(double deg)
        {
            double rad = System.Math.PI * deg / 180.0;//ラジアンに変換
            return System.Math.Cos(rad);
        }
    }

```

上記関数の使い方は、以下の事例を参照の事。

```c#:c#
        protected void CreateRader_Command(object sender, CommandEventArgs e)
        {
            string name = @"\" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";

            using (PdfDocument document = new PdfDocument())
            {
                PdfPage page = document.AddPage();
                page.Size = PageSize.A4; //用紙の大きさ
                page.Orientation = PageOrientation.Portrait; //用紙の向き

                using (XGraphics graphics = XGraphics.FromPdfPage(page))
                {
                    double[] score = new double[] { 1, 2, 3, 4, 5, 4, 3 };
                    CrateRader(graphics, 40, 120, 5, score);
                }

                string filepath = FilePath + @"pdf";
                string filename = filepath + name;
                document.Save(filename);
            }

            string openfilename = "./pdf/" + name;
            Response.Redirect(openfilename); //PDFに遷移
        }
```

こんな感じ。

斜めに線を引く時にsin、cosを使った。久し振りだなー。