F# Interactive Tips and Tricks: Visualizing Data in a Grid

The demos in my F# talks use a number of coding snippets to acquire, generate and display data interactively. Some of these little snippets are not so well known, but they are useful :-)

One pattern is displaying tabular data interactively using a DataGrid view. For example, this is used to show the progressive results of

  • web crawls (both synchronous and asynchronous)
  • parallel background image processing
  • results of analyzing log files

and can be used for just about any purpose where you need to quickly view tabular data.

The basic snippet is very simple, e.g. consider the following:

open System.Drawing

open System.Windows.Forms

let form = new Form(Visible = true, Text = "A Simple F# Form",

                    TopMost = true, Size = Size(600,600))

let data = new DataGridView(Dock = DockStyle.Fill, Text = "F# Programming is Fun!",

                            Font = new Font("Lucida Console",12.0f),

                            ForeColor = Color.DarkBlue)

form.Controls.Add(data)

data.DataSource <- [| ("www.bing.com",0);

                      ("www.google.com",0) |]

data.Columns.[0].Width <- 400

When run from F# Interactive, this displays a data grid as follows:

You can update the contents of the grid at any time by setting the DataSource property, normally just to some list of tuples.

For example, this is the result after updating with a list of tuples in the synchronous web crawl example (Tutorial\Intro Scripting\BasicIntroAndSyncWebCrawl.fsx) from the F# JAOO Tutorial I posted a few days ago, showing the initial pages reached by a depth-first crawl starting at the Google home page and the number of links found at each step:

                  data.DataSource <-

                      [| for KeyValue(key,value) in visited -> (key,value.Length) |]

Giving

 

There are lots of other tricks you can play with grids from F# Interactive, and you can use them as the basis for very smart object displays. For example:

  • If you add record values, then the titles of the columns are taken from the names of the record properties. Very nice!
  • You can have data automatically update by using other kinds of data source obejcts besides collections. I don't tend to use this myself, but consult the DataGrid MSDN pages for more information
  • If you creatively add display handlers to fsi.AddPrinter you can automatically pop up this kind of "rich" obejct display each time a value is evaluated/displayed in F# Interactive. But that may need to be used with some caution, lest you get a sea of windows! :-)