VegaHub


Getting Started

In this tutorial, we'll explore the basics of generating charts from F# Interactive with VegaHub.

To begin, create a new F# class library or console application. Remove the Script.fsx file, if one was created. Next, use NuGet to install the VegaHub package.

1: 
Install-Package VegaHub -Pre

NuGet will install VegaHub along with its required dependencies and place a number of files in your project, including:

  • index.html
  • Script.fsx
  • Scripts/app.js
  • Scripts/d3.geo.projection.min.js
  • Scripts/d3.layout.cloud.js
  • Scripts/d3.v3.min.js
  • Scripts/topojson.js
  • Scripts/vega.js

These files provide you with a bare-bones HTML page with the necessary JavaScript libraries to run visualizations. The Script.fsx is similar to the sample in the VegaHub.Samples project. This simple sample produces a bar chart using random values. A loop adds a new value and redraws the chart after a 100 ms sleep using both the old and new values. Basics.bar represents a Vega spec and accepts the data of tuples and two functions, one to retrieve the name of the column and another to retrieve the value for that column. The Vega.send function accepts a Vega spec and pushes the spec to the browser using the SignalR ChartHub.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
// Connect to the Vega hub.
let requestUrl = "http://localhost:8081"
let disposable = Vega.connect(requestUrl, __SOURCE_DIRECTORY__)

// Launch the browser using the system's default browser.
// If you would like to specify a browser, try [canopy](http://lefthandedgoat.github.io/canopy/)
// Note that you need to call this after you run `Vega.connect`.
System.Diagnostics.Process.Start(requestUrl + "/index.html")

// Simulate real-time updates.
let rand = Random(42)

// Define a loop function to generate and send the bar chart data.
let rec loop data iter = async {
    // Add a new, random value to the list on each iteration.
    let data' = List.append data [ (data.Length, rand.Next(0, 100)) ]
    // Create the bar chart spec.
    Basics.bar data' ((fun x -> fst x |> string), (fun x -> snd x |> float))
    // Send the spec to the browser.
    |> Vega.send
    // Delay for 100 ms.
    do! Async.Sleep 100
    // Stop when the counter reaches 0.
    if iter = 0 then () else
    // Keep running the loop, decrementing the counter on each iteration by 1.
    return! loop data' <| iter - 1
}

// Run the loop.
loop [] 25 |> Async.RunSynchronously

// Clean up.
disposable.Dispose()

TODO: Describe other samples

val requestUrl : string

Full name: Tutorial.requestUrl
val disposable : IDisposable

Full name: Tutorial.disposable
module Vega

from VegaHub
val connect : url:string * filePath:string -> IDisposable

Full name: VegaHub.Vega.connect
namespace System
namespace System.Diagnostics
Multiple items
type Process =
  inherit Component
  new : unit -> Process
  member BasePriority : int
  member BeginErrorReadLine : unit -> unit
  member BeginOutputReadLine : unit -> unit
  member CancelErrorRead : unit -> unit
  member CancelOutputRead : unit -> unit
  member Close : unit -> unit
  member CloseMainWindow : unit -> bool
  member EnableRaisingEvents : bool with get, set
  member ExitCode : int
  ...

Full name: System.Diagnostics.Process

--------------------
Diagnostics.Process() : unit
Diagnostics.Process.Start(startInfo: Diagnostics.ProcessStartInfo) : Diagnostics.Process
Diagnostics.Process.Start(fileName: string) : Diagnostics.Process
Diagnostics.Process.Start(fileName: string, arguments: string) : Diagnostics.Process
Diagnostics.Process.Start(fileName: string, userName: string, password: Security.SecureString, domain: string) : Diagnostics.Process
Diagnostics.Process.Start(fileName: string, arguments: string, userName: string, password: Security.SecureString, domain: string) : Diagnostics.Process
val rand : Random

Full name: Tutorial.rand
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
Random() : unit
Random(Seed: int) : unit
val loop : data:(int * int) list -> iter:int -> Async<unit>

Full name: Tutorial.loop
val data : (int * int) list
val iter : int
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val data' : (int * int) list
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val append : list1:'T list -> list2:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.append
property List.Length: int
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
module Basics

from VegaHub
val bar : dataset:'a list -> fx:Cat<'a> * fy:Num<'a> -> string

Full name: VegaHub.Basics.bar
val x : int * int
val fst : tuple:('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val send : spec:string -> unit

Full name: VegaHub.Vega.send
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
static member Async.Sleep : millisecondsDueTime:int -> Async<unit>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
IDisposable.Dispose() : unit
Fork me on GitHub