Wednesday, December 15, 2010

What Protovis might look like through an F# Lens

Recently, the development team received the ComponentOne Studio for WPF control suite.
Since I love F# and data visualizations I thought to myself that it might be cool to have a Protovis style API for the Charting controls. So I started hacking and surprisingly came up with the following  F# Script :

#r @"C:\Program Files (x86)\ComponentOne\Studio for WPF\bin\Design\C1.WPF.C1Chart.dll"
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.dll"
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll"
#r @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll"
open System

(* ==== Charting references ==== *)
open System.Windows
open System.Windows.Controls
open C1.WPF.C1Chart

(* create a panel (or blank charting control) *)
let Panel = new C1Chart()

(* Panel Width *)
let width (w: float) (p: C1Chart) = 
    p.Width <- w 

(* Panel Height *)
let height (h: float) (p: C1Chart)  = 
    p.Height <- h 

(* Chart Type *)
let add  (ct: ChartType) (p: C1Chart) = 
    p.ChartType <- ct

(* Data *)
let data  (d: List) (p: C1Chart) =
    let ds = new DataSeries()
    ds.Values <- new Media.DoubleCollection(Seq.ofList d)
    p.Data.Children.Add ds

(* Render *)
let render (c: C1Chart) = 
    let content = c
    let grd = new Grid()
    grd.Children.Add(content) |> ignore
    new Window(Title = "Protovis Via F#", Content = grd)
let vis = 
        |> width 150.0
        |> height 150.0
        |> add ChartType.Column
        |> data [1.0; 1.2; 1.7; 1.5; 0.7; 0.3]
        |> render

  [] ignore <| (new Application()).Run vis

As you can see from the above script, it really isn't all that difficult to get the same style API.
I just replaced the . or (Dot) function from the Protovis API with the standard F# pipeline operator / function.
Below is a screen shot of the above script which is the first sample in the "Getting Started" section on the Protovis site.