首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

ASP.NET 使用 GDI+ 繪製圓餅圖與長條圖完整範例

     編輯:關於C語言

核心類別:DrawChart

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.UI;

namespace Xcrm.Module.Report
{
    public class DrawChart : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // 依需求切換:DrawBarChart() 或 DrawPieChart()
            DrawBarChart();
        }

        // 長條圖
        private void DrawBarChart()
        {
            Bitmap bmp = new Bitmap(400, 300);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.Snow);

                string[] labels = { "很好", "好", "普通", "差" };
                int[] values = { 1000, 69, 90, 2000 };
                int count = values.Length;
                int barWidth = 40;
                float[] heights = new float[count];

                // 計算相對高度 (最大值對應 200 像素)
                int total = 0;
                foreach (int v in values) total += v;
                for (int i = 0; i < count; i++)
                    heights[i] = 200f * values[i] / total;

                // 標題
                g.DrawString("調查統計結果一覽圖", new Font("微軟正黑體", 12, FontStyle.Bold), Brushes.Black, 75, 10);

                // 圖例區域
                Point legendRect = new Point(300, 40);
                Point legendText = new Point(320, 40);

                for (int i = 0; i < count; i++)
                {
                    Color c = GetColor(i);

                    // 圖例色塊
                    g.DrawRectangle(Pens.Black, legendRect.X, legendRect.Y, 20, 10);
                    g.FillRectangle(new SolidBrush(c), legendRect.X, legendRect.Y, 20, 10);
                    g.DrawString(" " + labels[i], new Font("微軟正黑體", 9), Brushes.Black, legendText);
                    legendRect.Y += 15;
                    legendText.Y += 15;

                    // 長條圖 (從底部 290 向上畫)
                    float h = heights[i];
                    int x = i * barWidth + 15;
                    int y = 290 - (int)h;
                    g.DrawRectangle(Pens.Black, x, y, 20, (int)h + 5);
                    g.FillRectangle(new SolidBrush(c), x, y, 20, (int)h + 5);
                    g.DrawString(values[i].ToString(), new Font("微軟正黑體", 9), Brushes.Black, x + 5, y - 15);
                }

                // 邊框
                g.DrawRectangle(Pens.Black, 1, 1, 398, 298);

                // 輸出 JPEG
                Response.ContentType = "image/jpeg";
                bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
            }
        }

        // 圓餅圖
        private void DrawPieChart()
        {
            Bitmap bmp = new Bitmap(400, 300);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.Snow);

                string[] labels = { "很好", "好", "普通", "差" };
                int[] values = { 1000, 69, 90, 20 };
                int count = values.Length;
                float[] angles = new float[count];

                int total = 0;
                foreach (int v in values) total += v;
                for (int i = 0; i < count; i++)
                    angles[i] = 360f * values[i] / total;

                g.DrawString("調查統計結果一覽圖", new Font("微軟正黑體", 12, FontStyle.Bold), Brushes.Black, 75, 10);
                g.DrawString("單位:次", new Font("微軟正黑體", 9), Brushes.Black, 300, 25);

                Point legendRect = new Point(300, 40);
                Point legendText = new Point(320, 40);

                float startAngle = 0;
                Rectangle pieRect = new Rectangle(50, 50, 200, 200);

                for (int i = 0; i < count; i++)
                {
                    Color c = GetColor(i);
                    float sweep = (i == count - 1) ? 360 - startAngle : angles[i]; // 修正累積誤差

                    // 圖例
                    g.DrawRectangle(Pens.Black, legendRect.X, legendRect.Y, 20, 10);
                    g.FillRectangle(new SolidBrush(c), legendRect.X, legendRect.Y, 20, 10);
                    g.DrawString($" {labels[i]} {values[i]}", new Font("微軟正黑體", 9), Brushes.Black, legendText);
                    legendRect.Y += 15;
                    legendText.Y += 15;

                    // 扇形
                    g.FillPie(new SolidBrush(c), pieRect, startAngle, sweep);
                    g.DrawPie(Pens.Black, pieRect, startAngle, sweep);

                    startAngle += sweep;
                }

                g.DrawRectangle(Pens.Black, 1, 1, 398, 298);
                Response.ContentType = "image/jpeg";
                bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
            }
        }

        private Color GetColor(int index)
        {
            Color[] colors = { Color.Red, Color.Blue, Color.Yellow, Color.Green,
                               Color.Pink, Color.Plum, Color.Gray, Color.Salmon,
                               Color.RosyBrown, Color.Teal, Color.Orange, Color.Thistle, Color.Maroon };
            return colors[index % colors.Length];
        }
    }
}

前端呼叫方式

<img src="DrawChart.aspx" alt="統計圖表" />

或動態切換:DrawChart.aspx?type=pie 在 Page_Load 判斷 Request["type"]。

關鍵技術點

  • Bitmap + Graphics.FromImage 離屏繪圖。
  • FillRectangle/DrawRectangle 繪製長條;FillPie/DrawPie 繪製扇形。
  • 座標系:原點 (0,0) 在左上角,Y 軸向下;長條圖從底部向上畫需計算 y = bottom - height。
  • Response.OutputStream 直接輸出二進位圖片,無需暫存檔。
  • using 確保 Graphics/Bitmap 及時釋放非受控 GDI 資源。

生產環境建議

  • 改用成熟圖表庫:Chart.js (前端)、EPPlus/ClosedXML (匯出 Excel 圖表)、Syncfusion/DevExpress (伺服端渲染)。
  • GDI+ 在高併發下效能與記憶體壓力大,ASP.NET Core 建議避免直接使用 System.Drawing.Common (僅支援 Windows)。
  • 資料來源應從資料庫/服務動態取得,而非硬編碼陣列。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved