檔案狀態:    住戶編號:1665003
 辛巴ღAngelღ 的日記本
快速選單
到我的日記本
看他的最新日記
加入我的收藏
瀏覽我的收藏
08/04~08/05 《前一篇 回他的日記本 後一篇》 08/13 唱歌。。。
 切換閱讀模式  回應  給他日記貼紙   給他愛的鼓勵  檢舉
篇名: 挑戰~~
作者: 辛巴ღAngelღ 日期: 2010.08.13  天氣:  心情:
最近老闆不知道那一根筋不對了..突然說想分析我們公司訂單的狀況...可憐的我只好又跳入火坑啦..
老闆下了幾道題目...
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
標籤:
瀏覽次數:80    人氣指數:280    累積鼓勵:10
 切換閱讀模式  回應  給他日記貼紙   給他愛的鼓勵 檢舉
給本文愛的鼓勵:  最新愛的鼓勵
08/04~08/05 《前一篇 回他的日記本 後一篇》 08/13 唱歌。。。
 
給我們一個讚!