2009-11-28 60 views
6

我想在F#中使用構建功能或免費庫來做一些基本的製圖。 我會非常高興地看到它的一個非常基本的例子,如果可能的話,它是一個餅圖。F#圖表示例

實施例的數據:

[("John",34);("Sara",30);("Will",20);("Maria",16)] 

凡int爲在餡餅要表示百分比。

我最近安裝VSLab雖然我找到了很多3D的例子,我只想找一個簡單的餅圖...

這也是精細的方式使用Excel的功能,不是免費的,但儘管如此安裝..

回答

8

這裏的東西我一起搗爛使用谷歌圖表API, 我希望的代碼是沒有進一步的解釋不夠清楚:

//Built with F# 1.9.7.8 
open System.IO 
open System.Net 
open Microsoft.FSharp.Control.WebExtensions 
//Add references for the namespaces below if you're not running this code in F# interactive 
open System.Drawing 
open System.Windows.Forms 

let buildGoogleChartUri input = 
    let chartWidth, chartHeight = 250,100 

    let labels,data = List.unzip input 
    let dataString = 
     data 
     |> List.map (box>>string) //in this way, data can be anything for which ToString() turns it into a number 
     |> List.toArray |> String.concat "," 

    let labelString = labels |> List.toArray |> String.concat "|" 

    sprintf "http://chart.apis.google.com/chart?chs=%dx%d&chd=t:%s&cht=p3&chl=%s" 
      chartWidth chartHeight dataString labelString 

//Bake a bitmap from the google chart URI 
let buildGoogleChart myData = 
    async { 
     let req = HttpWebRequest.Create(buildGoogleChartUri myData) 
     let! response = req.AsyncGetResponse() 
     return new Bitmap(response.GetResponseStream()) 
    } |> Async.RunSynchronously 

//invokes the google chart api to build a chart from the data, and presents the image in a form 
//Excuse the sloppy winforms code 
let test() = 
    let myData = [("John",34);("Sara",30);("Will",20);("Maria",16)] 

    let image = buildGoogleChart myData 
    let frm = new Form() 
    frm.BackgroundImage <- image 
    frm.BackgroundImageLayout <- ImageLayout.Center 
    frm.ClientSize <- image.Size 
    frm.Show() 
+1

+1你的努力,沒有時間去到現在,我將它除了laterif它的工作原理 – Peter 2009-11-28 13:14:40

3

這很容易做到「在自制的」餅圖: 開放System.Drawing中

let red = new SolidBrush(Color.Red) in 
let green = new SolidBrush(Color.Green) in 
let blue = new SolidBrush(Color.Blue) in 
let rec colors = 
    seq { 
    yield red 
    yield green 
    yield blue 
    yield! colors 
    } 


let pie data (g: Graphics) (r: Rectangle) = 
    let vals = 0.0 :: List.map snd data 
    let total = List.sum vals 
    let angles = List.map (fun v -> v/total*360.0) vals 
    let p = new Pen(Color.Black,1) 
    Seq.pairwise vals |> Seq.zip colors |> Seq.iter (fun (c,(a1,a2)) -> g.DrawPie(p,r,a1,a2); g.FillPie(c,r,a1,a2)) 
+0

+1可能不是一個我會最終使用,但家庭烹飪的榮譽! – Peter 2009-11-29 07:17:30

1

本來我只是想在這裏有一個非常簡單的Windows補充SSP的例如形成對話框,顯示了一個餡餅。但是嘗試這個,我發現了ssp代碼中的一個錯誤:一方面Seq.pairwisevals上運行,而不是angles,另一方面,它顯然不認爲從開始角度沿着掃掠角開始繪製餅圖片。

我糾正錯誤,評論說,重新排列,重新格式化並重新命名爲一些事情 - 並使其既#load -able在fsi.exe編譯fsc.exe

#light 
module YourNamespace.PieExample 

open System 
open System.Drawing 
open System.ComponentModel 
open System.Windows.Forms 

(* (circular) sequence of three colors *) 
#nowarn "40" 
let red = new SolidBrush(Color.Red) 
let green = new SolidBrush(Color.Green) 
let blue = new SolidBrush(Color.Blue) 
let rec colors = 
    seq { yield red 
      yield green 
      yield blue 
      yield! colors } 

(* core function to build up and show a pie diagram *) 
let pie data (g: Graphics) (r: Rectangle) = 
    // a pen for borders of pie slices 
    let p = new Pen(Color.Black, 1.0f) 
    // retrieve pie shares from data and sum 'em up 
    let vals = List.map snd data 
    let total = List.sum vals 
    // baking a pie starts here with ... 
    vals 
    // scaling vals in total to a full circle 
    |> List.map (fun v -> v * 360.0/total) 
    // transform list of angles to list of pie slice delimiting angles 
    |> List.scan (+) 0.0 
    // turn them into a list of tuples consisting of start and end angles 
    |> Seq.pairwise 
    // intermix the colors successively 
    |> Seq.zip colors 
    // and at last do FillPies and DrawPies with these ingredients 
    |> Seq.iter (fun (c,(starta,enda)) 
        -> g.FillPie(c,r,(float32 starta) 
            ,(float32 (enda - starta))) 
         g.DrawPie(p,r,(float32 starta) 
            ,(float32 (enda - starta)))) 

(* demo data *) 
let demolist = [ ("a", 1.); ("b", 2.); ("c", 3.); 
       ("d", 2.); ("e", 2.); ("f", 2.) ] 

(* finally a simple resizable form showing demo data as pie with 6 slices *) 
let mainform = new Form(MinimumSize = Size(200,200)) 
// add two event handlers 
mainform.Paint.Add (fun e -> pie demolist e.Graphics mainform.ClientRectangle) 
mainform.Resize.Add (fun _ -> mainform.Invalidate()) 
#if COMPILED 
Application.Run(mainform) 
#else 
mainform.ShowDialog() |> ignore 
#endif 

最後但並非最不重要我想提兩個有用的提示,我發現有用

1

老問題,但技術變化。

在VS 2013,F#3,和安裝NuGet包

Install-Package FSharp.Charting 

添加參考:

System.Windows.Forms 
    System.Windows.Forms.DataVisualization 

,並用一個代碼行:

 Application.Run ((Chart.Pie data).ShowChart()) 

以下F#代碼生成統計圖表:

open System 
open System.Windows.Forms 
open FSharp.Charting 

[<EntryPoint>] 
let main argv = 
    Application.EnableVisualStyles() 
    Application.SetCompatibleTextRenderingDefault false 
    let data =[("John",34);("Sara",30);("Will",20);("Maria",16)]  
    Application.Run ((Chart.Pie data).ShowChart()) 
    0 

,你會得到如下圖:

enter image description here