承接長條圖教學,本文示範使用 Graphics.FillPie 繪製餅圖,同樣從 Access 資料庫讀取銷售資料動態生成。
FillPie(x, y, width, height, startAngle, sweepAngle):startAngle 從 x 軸順時針度數,sweepAngle 為扇形掃過角度。protected void Page_Load(object sender, EventArgs e)
{
DataTable dt = GetSalesData(); // 同長條圖資料
int total = dt.AsEnumerable().Sum(r => r.Field("SL"));
int size = 300, margin = 20;
using (Bitmap bmp = new Bitmap(size + 150, size)) // 右側留空給圖例
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.AntiAlias;
RectangleF pieRect = new RectangleF(margin, margin, size, size);
float startAngle = -90f; // 從頂部開始
Color[] colors = { Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Purple, Color.Brown,
Color.Teal, Color.Pink, Color.Gray, Color.Olive, Color.Maroon, Color.Navy };
// 繪製扇形
for (int i = 0; i < dt.Rows.Count; i++)
{
int val = (int)dt.Rows[i]["SL"];
float sweepAngle = (float)val / total * 360f;
using (SolidBrush brush = new SolidBrush(colors[i % colors.Length]))
g.FillPie(brush, pieRect, startAngle, sweepAngle);
g.DrawPie(Pens.White, pieRect, startAngle, sweepAngle); // 白色分隔線
startAngle += sweepAngle;
}
// 繪製圖例 (右側)
float legendX = size + margin * 2;
float legendY = margin;
for (int i = 0; i < dt.Rows.Count; i++)
{
string month = dt.Rows[i]["YF"].ToString() + "月";
int val = (int)dt.Rows[i]["SL"];
float pct = (float)val / total * 100f;
using (SolidBrush brush = new SolidBrush(colors[i % colors.Length]))
{
g.FillRectangle(brush, legendX, legendY, 12, 12);
g.DrawRectangle(Pens.Black, legendX, legendY, 12, 12);
}
g.DrawString($"{month} {val} ({pct:F1}%)", new Font("微軟正黑體", 9), Brushes.Black, legendX + 18, legendY);
legendY += 20;
}
Response.Clear();
Response.ContentType = "image/png";
bmp.Save(Response.OutputStream, ImageFormat.Png);
}
}
| 方法 | 用途 | 餅圖關鍵 |
|---|---|---|
| FillPie | 填充扇形 | 核心 |
| DrawPie | 繪製扇形邊框 | 分隔線 |
| FillEllipse | 填充橢圓/圓 | 背景圓 |
| DrawString | 繪製文字 | 標籤/圖例 |
| MeasureString | 測量文字尺寸 | 置中計算 |
sweepAngle 微調或位移半徑向量。<map><area> 熱區配合前端 JS 顯示明細。餅圖適合展示「部分佔整體比例」,搭配長條圖/折線圖可構建完整儀表板。