本文示範如何在 ASP.NET Web Forms 中使用 System.Drawing 命名空間(GDI+)動態生成折線圖並直接輸出至瀏覽器。適用於無法引入第三方圖表庫的舊版專案維護場景。
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.UI;
public partial class ChartDemo : Page
{
protected void Page_Load(object sender, EventArgs e)
{
GenerateChart();
}
private void GenerateChart()
{
// 1. 準備測試數據
DataTable dt = new DataTable("ChartData");
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Value", typeof(int));
dt.Columns.Add("Label", typeof(string));
Random rnd = new Random();
for (int i = 0; i < 61; i++)
{
DataRow row = dt.NewRow();
row["ID"] = i;
row["Value"] = rnd.Next(10, 140);
row["Label"] = i.ToString();
dt.Rows.Add(row);
}
// 2. 繪圖參數設定
const int imgWidth = 450;
const int imgHeight = 180;
const int plotLeft = 50;
const int plotTop = 15;
const int plotWidth = 360;
const int plotHeight = 150;
Rectangle plotArea = new Rectangle(plotLeft, plotTop, plotWidth, plotHeight);
// 3. 建立畫布與繪圖物件
using (Bitmap bitmap = new Bitmap(imgWidth, imgHeight, PixelFormat.Format24bppRgb))
using (Graphics g = Graphics.FromImage(bitmap))
{
g.Clear(Color.White);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// 繪製邊框
using (Pen borderPen = new Pen(Color.Black, 1))
g.DrawRectangle(borderPen, plotArea);
// 4. 計算數據點座標
Point[] dataPoints = new Point[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
int x = plotLeft + (int)(dt.Rows[i].Field("ID") * 6);
int y = plotTop + plotHeight - (int)(dt.Rows[i].Field("Value") * 1.0);
dataPoints[i] = new Point(x, y);
}
// 5. 繪製折線
using (Pen linePen = new Pen(Color.Red, 2))
g.DrawCurve(linePen, dataPoints);
// 6. 繪製網格線
using (Pen gridPen = new Pen(Color.Gray, 1))
{
// 橫向網格線
for (int i = 1; i < 5; i++)
{
int y = plotTop + i * 30;
g.DrawLine(gridPen, plotLeft, y, plotLeft + plotWidth, y);
}
// 縱向網格線
for (int i = 1; i < 12; i++)
{
int x = plotLeft + i * 30;
g.DrawLine(gridPen, x, plotTop, x, plotTop + plotHeight);
}
}
// 7. 繪製標題
using (SolidBrush brush = new SolidBrush(Color.RoyalBlue))
using (Font titleFont = new Font("Franklin Gothic Demi", 12, FontStyle.Italic))
g.DrawString("折線圖測試", titleFont, brush, new PointF(200, 0));
// 8. 輸出至 Response 流
Response.Clear();
Response.ContentType = "image/gif";
bitmap.Save(Response.OutputStream, ImageFormat.Gif);
Response.End();
}
}
}
<img src="ChartDemo.aspx" alt="動態折線圖" />
| 技術點 | 說明 |
|---|---|
| Graphics.FromImage | 從 Bitmap 建立繪圖介面,所有繪圖操作均在記憶體中進行 |
| DrawCurve | 繪製平滑曲線(Cardinal Spline),比 DrawLines 視覺效果更佳 |
| 座標系轉換 | GDI+ 原點在左上角,Y 軸向下;數據座標需轉換為螢幕座標 |
| using 區塊 | 確保非託管資源(GDI+ 物件)及時釋放,防止記憶體洩漏 |
System.Drawing 在伺服器端使用的限制: Microsoft 官方不建議在 ASP.NET Core / 非 Windows 環境使用 System.Drawing.Common,可能發生 GDI+ 通用錯誤。生產環境建議遷移至跨平台繪圖庫(如 SkiaSharp、ImageSharp)或改用前端渲染方案。