Non-blocking Chart.Show in FSharp.Charting

80 Views Asked by At

Using FSharp.Charting from a .fs program, when a plot is displayed it blocks the execution of rest of the program. Is there a way to generate non blocking charts? E.g. I would want both the following to be displayed in separate windows and also have the rest of the program execute.

Chart.Line(Series1) |> Chart.Show // Chart 1
// do some work
Chart.Line(Series2) |> Chart.Show // display this in a second window
// continue executing the rest while the above windows are still open.
1

There are 1 best solutions below

2
s952163 On

Can you provide more details on how you are calling Chart.Line? E.g. in the REPL, via FSLab, in winforms, in wpf?

The following doesn't block for me when working in an fsx file. The other way would be to wrap it in an async block, which is useful if you're doing some long-running computation or accessing a database.

#load @"..\..\FSLAB\packages\FsLab\FsLab.fsx"
open Deedle
open FSharp.Charting
open System

let rnd = System.Random()
let xs = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
let xs' =  List.init 100 (fun _ -> rnd.NextDouble() - 0.5)

Chart.Line(xs) // |> Chart.Show 
Chart.Line(xs') //|> Chart.Show

Add:

async {Chart.Line(xs)  |> Chart.Show } |> Async.Start 
async {Chart.Line(xs') |> Chart.Show } |> Async.Start

MS Docs and F# Fun&Profit

Compiled example:

open System
open FSharp.Charting
open System.Threading
open System.Threading.Tasks
open System.Drawing
open FSharp.Charting
open FSharp.Charting.ChartTypes



[<STAThread>]
[<EntryPoint>]
let main argv = 
    let rnd = System.Random()
    let xs = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
    let xs' =  List.init 100 (fun _ -> rnd.NextDouble() - 0.5)


    Chart.Line(xs)  |> Chart.Show 
    printfn "%A" "Chart 1"
    Chart.Line(xs') |> Chart.Show
    printfn "%A" "Chart 2"

    async {Chart.Line(xs)  |> Chart.Show } |> Async.Start 
    printfn "%A" "Chart 3"
    async {Chart.Line(xs') |> Chart.Show } |> Async.Start
    printfn "%A" "Chart 4"
    Console.Read() |> ignore
    printfn "%A" argv
    0 // return an integer exit code

Related Questions in F#