【问题标题】:F# charting exampleF# 图表示例
【发布时间】:2009-11-28 10:18:36
【问题描述】:

我想使用内置功能或免费库在 F# 中制作一些基本图表。 如果可能的话,我会非常高兴有一个非常基本的例子,一个饼图。

示例数据:

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

整数是要在饼图中表示的百分比。

我最近安装了 VSLab,虽然我找到了很多 3D 示例,但我只是在寻找一个简单的饼图...

顺便用excel功能也不错,不是免费的,不过还是安装好了..

【问题讨论】:

    标签: f# charts


    【解决方案1】:

    这是我使用 Google Chart 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,现在没有时间进入,如果它有效,我会在以后排除它
    【解决方案2】:

    制作“自制”饼图很容易: 打开 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))
    

    【讨论】:

    • +1 可能不是我最终会使用的那个,但是对于家庭烹饪的赞誉!
    【解决方案3】:

    老问题,但技术正在改变。

    在 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
    

    你会得到下面的图表:

    【讨论】:

      【解决方案4】:

      最初我只是尝试用一个非常简单的显示饼图​​的窗体对话框来补充 ssp 的 示例。但是尝试这个我在 ssp 的代码中发现了一个错误:一方面Seq.pairwisevals 而不是angles 上运行,另一方面它显然不认为饼片将从起始角度开始绘制后掠角。

      我更正了错误、注释、重新排列、重新格式化和重命名了一些内容 - 并使其在 fsi.exe可编译 中的 #load-able 和 >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
      

      最后但同样重要的是,我想提两个我发现有用的提示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-07
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多