最近老闆不知道那一根筋不對了..突然說想分析我們公司訂單的狀況...可憐的我只好又跳入火坑啦..
老闆下了幾道題目...
1.把訂單依照地區來分析,看每個地區各有幾張訂單,佔多少百分比..(北部.中部.南部.東部.離島)
2.把訂單依職業類別來分析,看每種職業類別各有幾張訂單,佔多少百分比
3.把訂單依性別來分析,看每種性別各有幾張訂單,佔多少百分比(男.女)
4.把訂單依年齡來分析,看每種年齡層各有幾張訂單,佔多少百分比
基本上..要分析資料都沒什麼問題,指令打一打,結果就出來了..
可是邪惡的老闆..竟然說要畫出圓餅圖出來...這可真是難倒我了..所以第一個想到的方法就是用EXECL來做
首先把數據都KEY入EXECL中..並用 插入->圖表->圓餅圖
哈哈...畫出圖餅圖來了..趕快拿去給老闆看...
老闆說:很好..就是這樣..可是不準用EXECL畫...你去用程式自動畫出來...
真是晴天霹靂阿~~~完全不知道該怎麼下手..
趕快上奇摩打"VB.NET 圓餅圖"....查不到有用的資料..
再打"VB.NET 圓形圖"...有一些資料..可是還是沒什麼用
看來VB.NET並沒有設計圖餅圖的元件可以直接使用..看來只好靠自己來畫圖了..
打上"VB.NET 圓形",查到了一個網站,VB.net的繪圖 [Part I]
裡面介紹了一些畫圖的指令,趕快來試試看...
嗯.......畫圖....OK....還蠻簡單的..
嗯.......畫弧形....OK....
可是...問題來了...依照數據的不同..每個地區所佔的弧度都不同...畫的顏色也要不同..
所以要先把每個地區的角度算出來...因為一個圓有360度..依據地區所佔的百分比不同來相乘..
例:北區 = 360*0.3138 = 112.968 =>113度
中區 = 360*0.1884 = 67.824 =>68度
南區 = 360*0.4339 = 156.204 =>156度
花東 = 360*0.0504 = 18.144 =>18度
離島 = 360-114-69-157-19 = 1度
算出每個地區的角度後,就可以開始畫弧形了..
從0度開始畫,第一個弧從0~113度,第二個弧從114~182度,第三個弧從183~339度,第四個弧從340~358度,第五個弧從359~359度
再來是不同弧形要有不同的顏色...
原本想用陣列來做的..可是我太笨了..研究不出來..
所以只好算了..反正只有5個地區..就讓程式跑5遍吧..
好囉..讓程式跑跑看吧..
最後..最大的問題來了...再在圖上標註 北部.中部.南部.東部.離島...這樣才看的懂
問題是...要怎麼知道畫出來後..每個區塊的位置在那裡...
目前只知道每個區塊所佔的角度為何.....那要算出X.Y軸就得用三角函數..SIN COS來算了...
高中畢業後,早就把三角函數還給老師了...左思右想..就是想不出來公式...
那只好來模擬一下了...照上圖來看原點我是設定300,150..直徑為200..
紅色區塊的角度為0~67度,藍色為68~180度,粉紅色為181~199度,黃色為200~356度,綠色為357~359度
紅色區塊的中間角為33.5度,藍色為124度 粉紅色為190度 黃色為278度 綠色為358度
把圖拉去小畫家中看了一下座標,紅色大約要標在184,155 藍色要標在48,188 粉紅色標在2,81 黃色要標在121,3 綠色標在199,96
因為在小畫家的原點為100,100,所以各區塊的偏移量為 紅色84,55 藍色 -52,88 粉紅色 -98,-19 黃色 21,-97 綠色 99,-4
打開小算盤來算了一下..COS(33.5)=0.833..SIN(33.5)=0.551...COS(124)=-0.559..SIN(124)=0.829...好像很接近我要的值..
看來應該是不需要複雜的公式就可以算出來了..只是正負數有問題,應該是所以象限不同的關係
把他寫入程式中...執行...
怪怪的..位置會亂跑..這麼簡單的程式應該沒寫錯阿..查了一下數據..System.Math.Cos(33.5)的值是-0.491
奇怪..怎麼會跟小算盤上算的不一樣...想了想..還是想不出來..趕快上奇摩查查看..
輸入了很多關鍵字..都找不到答案..最後..看到了一句話...三角函數必須用徑度來算...
我的小算盤設定的是Deg(角度)..所以他會自動轉化成徑度後求出答案...
所以趕快去奇摩查....角度轉徑度.....找到答案為 公式: 徑度=(角度*3.14159)/180
帶入程式中...終於跑出正確位置了...
以下為程式碼,提供給有興趣的人參考..寫的很爛..請會的人不要笑我笨哦...呵呵..
Dim Table As New DataTable
Sub 畫圓餅圖(ByRef PL As Panel)
If Table.Rows.Count = 0 Then Exit Sub
For i As Integer = Panel1.Controls.Count - 1 To 0 Step -1
If Mid(Panel1.Controls(i).Name, 1, 2) = "LB" Then Panel1.Controls(i).Dispose()
Next
Dim X As Integer = 300 '設定圓心的X軸
Dim Y As Integer = 150 '設定圓心的Y軸
Dim 直徑 As Integer = 200 '設定圓的直徑
Dim g As Graphics = PL.CreateGraphics '把圖畫在Panel元件中
g.Clear(Color.White) '把圖清空,底圖設成白色
Dim p As New Pen(Color.Black, 2) '設定一支畫筆,黑色,2個單位粗
Dim 起始角 As Integer = 0
Dim 角度 As Integer = 0
For i As Integer = 0 To Table.Rows.Count - 1
If i <> Table.Rows.Count - 1 Then
角度 = 360 * Table.Rows(i).Item("百分比")
Else
角度 = 360 - 起始角
End If
Dim 備註角 As Integer = 起始角 + (角度 / 2)
Select Case i
Case 0
g.DrawPie(p, 0 + X, 0 + Y, 直徑, 直徑, 起始角, 角度)
g.FillPie(Brushes.Red, 1 + X, 1 + Y, 直徑 - 2, 直徑 - 2, 起始角, 角度)
Color1.Visible = True
Color1.BackColor = Color.Red
Name1.Visible = True
Name1.Text = Table.Rows(i).Item("名稱")
Case 1
g.DrawPie(p, 0 + X, 0 + Y, 直徑, 直徑, 起始角, 角度)
g.FillPie(Brushes.Blue, 1 + X, 1 + Y, 直徑 - 2, 直徑 - 2, 起始角, 角度)
Color2.Visible = True
Color2.BackColor = Color.Blue
Name2.Visible = True
Name2.Text = Table.Rows(i).Item("名稱")
Case 2
g.DrawPie(p, 0 + X, 0 + Y, 直徑, 直徑, 起始角, 角度)
g.FillPie(Brushes.Pink, 1 + X, 1 + Y, 直徑 - 2, 直徑 - 2, 起始角, 角度)
Color3.Visible = True
Color3.BackColor = Color.Pink
Name3.Visible = True
Name3.Text = Table.Rows(i).Item("名稱")
Case 3
g.DrawPie(p, 0 + X, 0 + Y, 直徑, 直徑, 起始角, 角度)
g.FillPie(Brushes.Yellow, 1 + X, 1 + Y, 直徑 - 2, 直徑 - 2, 起始角, 角度)
Color4.Visible = True
Color4.BackColor = Color.Yellow
Name4.Visible = True
Name4.Text = Table.Rows(i).Item("名稱")
Case 4
g.DrawPie(p, 0 + X, 0 + Y, 直徑, 直徑, 起始角, 角度)
g.FillPie(Brushes.Green, 1 + X, 1 + Y, 直徑 - 2, 直徑 - 2, 起始角, 角度)
Color5.Visible = True
Color5.BackColor = Color.Green
Name5.Visible = True
Name5.Text = Table.Rows(i).Item("名稱")
End Select
Dim LB As New Label
LB.Parent = PL
LB.BackColor = Color.Transparent
LB.Text = Table.Rows(i).Item("名稱") & vbNewLine & Table.Rows(i).Item("訂單數") & "張" & Mid(vbNewLine & Table.Rows(i).Item("百分比") * 100, 1, CStr(vbNewLine & Table.Rows(i).Item("百分比") * 100).IndexOf(".") + 3) & "%"
LB.Width = 50
LB.Name = "LB" & i
LB.Height = 50
LB.ForeColor = Color.Red
LB.BackColor = Color.White
'角度需先轉成徑度 公式: 徑度=(角度*3.14159)/180
Dim 大直徑 As Integer = 250
Dim 弧度 As Single = (備註角 * 3.14159) / 180
Select Case 備註角
Case 0 To 89
LB.Location = New Point(X + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度))), Y + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度))))
g.DrawLine(p, CSng(X + 直徑 / 2 + System.Math.Abs((直徑 / 4 * System.Math.Cos(弧度)))), CSng(Y + 直徑 / 2 + System.Math.Abs((直徑 / 4 * System.Math.Sin(弧度)))), CSng(X + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度)))), CSng(Y + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度)))))
Case 90 To 179
LB.Location = New Point(X + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度))) - LB.Width, Y + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度))))
g.DrawLine(p, CSng(X + 直徑 / 2 - System.Math.Abs((直徑 / 4 * System.Math.Cos(弧度)))), CSng(Y + 直徑 / 2 + System.Math.Abs((直徑 / 4 * System.Math.Sin(弧度)))), CSng(X + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度))) - LB.Width / 2), CSng(Y + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度)))))
Case 180 To 269
LB.Location = New Point(X + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度))) - LB.Width, Y + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度))) - LB.Height)
g.DrawLine(p, CSng(X + 直徑 / 2 - System.Math.Abs((直徑 / 4 * System.Math.Cos(弧度)))), CSng(Y + 直徑 / 2 - System.Math.Abs((直徑 / 4 * System.Math.Sin(弧度)))), CSng(X + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度))) - LB.Width), CSng(Y + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度))) - LB.Height / 2))
Case 270 To 359
LB.Location = New Point(X + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度))), Y + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度))) - LB.Height)
g.DrawLine(p, CSng(X + 直徑 / 2 + System.Math.Abs((直徑 / 4 * System.Math.Cos(弧度)))), CSng(Y + 直徑 / 2 - System.Math.Abs((直徑 / 4 * System.Math.Sin(弧度)))), CSng(X + 直徑 / 2 + System.Math.Abs((大直徑 / 2 * System.Math.Cos(弧度)))), CSng(Y + 直徑 / 2 - System.Math.Abs((大直徑 / 2 * System.Math.Sin(弧度))) - LB.Height / 2))
End Select
起始角 += 角度
Next
End Sub
|