Первоначально я только попытался дополнить пример ssp здесь очень простым диалоговым окном формы окна, которое показывает круговую диаграмму. Но, попробовав это, я нашел ошибку в коде ssp: с одной стороны Seq.pairwise
работает на vals
вместо angles
, а с другой стороны, очевидно, что он не учитывает, что кусочки пирога будут нарисованы, начиная с начального угла вдоль угол развертки.
Я исправил ошибку, прокомментировал, переставил, переформатировал и переименовал некоторые вещи - и сделал так, что он #load
может быть 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
И последнее, но не менее важное: я хочу упомянуть два полезных совета, которые я нашел полезными