2009-11-28 8 views
6

Je voudrais effectuer une représentation de base en F # en utilisant des fonctions intégrées ou une bibliothèque gratuite. Et je serais très très heureux avec un exemple très basique, un camembert si possible.Exemple de représentation graphique F #

données Exemple:

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

Lorsque les ints sont des pourcentages d'être représentés dans la tarte.

J'ai récemment installé VSLab et si je trouve beaucoup d'exemples 3D, je suis à la recherche que pour un simple diagramme circulaire ...

Il est également bon d'utiliser les fonctionnalités d'Excel en passant, pas libre, mais installé néanmoins ..

Répondre

8

est ici quelque chose que je fracassé ensemble en utilisant l'API Google chart, J'espère que le code est assez clair sans autre explication:

//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 pour votre effort, pas le temps d'aller dans maintenant, je vais sauf qu'il laterif cela fonctionne – Peter

3

Il est facile de faire « made in home » camembert : System.Drawing ouvert

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 probablement pas celle que je finir par utiliser, mais félicitations pour la cuisine à domicile! – Peter

1

Au départ, je n'essayé de compléter exemple de ssp ici avec une fenêtre très simple forme de dialogue qui montre une tarte. Mais en essayant cela j'ai trouvé un bug dans le code de ssp: d'une part Seq.pairwise fonctionne sur vals au lieu de angles et d'autre part il ne considère évidemment pas que les tranches de tarte seront dessinées en commençant par l'angle de départ le long de l'angle de balayage.

Je corrige le bug, a commenté, réarrangées, reformaté et rebaptisés certaines choses - et fait à la fois #load able dans fsi.exe et compilable avec 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 

Last but not least, je tiens à mentionner deux conseils utiles que j'ai trouvé utiles

1

, mais changement de technologie.

dans vs 2013, F # 3, et l'installation du package NuGet

Install-Package FSharp.Charting 

Ajouter référence à:

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

et avec une ligne de code:

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

ci-dessous Le code F # génère le graphique Bie:

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 

et vous obtenez le tableau suivant:

enter image description here

Questions connexes