Share via


FSharpChart and WPF

The new version of FSharp.Chart (formely FSharpChart) can now be found on GitHib at: https://fsharp.github.io/FSharp.Charting/

In the recent version of FSharpChart several examples are given around using FSharpChart and Windows Presentation Foundation (WPF).

The first sample is included in the sample script file SampleChartingForms.fsx. This sample demonstrates how to render a FSharpChart using WPF from within a fsx script file:

// standard WPF DLLs
#r "WindowsBase"
#r "PresentationCore"
#r "PresentationFramework"
#r "WindowsFormsIntegration" // WPF/Forms integration DLL
#r "System.Xaml" // needed only because of F# IntelliSense issue...

open MSDN.FSharp
open System.Windows

// create a chart
let area = Charting.FSharpChart.Area [for x in 1 .. 10 -> sprintf "Column %i" x, x*x]
// create a WPF host control containing it
let host = new Forms.Integration.WindowsFormsHost(Child = new Charting.ChartControl(area))
// create and show a WPF form with the control
let wnd = Window(Content = host, Title = "WPF/Forms Interop", Visibility = Visibility.Visible)

Thanks to Keith Battocchi for this code snippet.

The second sample is a WPF project that demonstrates how to use FSharpChart through Windows Forms Integration. A sample is given with and without the use of a XAML file. Thanks to Ryan Simpson for these samples.

The code to render a FSharpChart without XAML is very similar to that of the scripting sample:

let getChartControl =
    let chart =
        FSharpChart.Combine
            [ FSharpChart.Line([ for f in 0.0 .. 0.1 .. 10.0 -> sin f ], Name = "Sin Wave")
              FSharpChart.Line([ for f in 0.0 .. 0.1 .. 10.0 -> cos f ], Name = "Cosine Wave") ]
            |> FSharpChart.WithArea.AxisX(MajorGrid = Grid(LineColor = Color.LightGray))
            |> FSharpChart.WithArea.AxisY(Minimum = -1.0, Maximum = 1.0, MajorGrid = Grid(LineColor = Color.LightGray))
            |> FSharpChart.WithMargin(5.0f, 5.0f, 5.0f, 5.0f)

    new ChartControl(chart, Dock = DockStyle.Fill)

// Sample without the use of XAML
let mainNoXaml() =   

    let formsHost = new WindowsFormsHost(Child = getChartControl)
    let graphWindow = new Window(Content = formsHost, Title = "Chart Sin/Cosine")
    
    let wpfApp = new System.Windows.Application()
    wpfApp.Run(graphWindow) |> ignore

// Application Entry Point
[<STAThread>]
do
    mainNoXaml()

When using a XAML file things are a little different.

Firstly one has to define the XAML that will be loaded:

<Window xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
    Width="600" Height="600" Title="Chart Sin/Cosine">
    <Grid>
        <WindowsFormsHost Name="chartHost"></WindowsFormsHost>
    </Grid>
</Window>

The idea is that the WindowsFormsHost element is defined with the ChartControl:

let mainWithXaml() =

    let (?) (window : Window) name = window.FindName name |> unbox

    let uri = new System.Uri("/FSharp.Charting.Wpf;component/FSharpChartWpf.xaml", UriKind.Relative)
    let window = Application.LoadComponent(uri) :?> Window

    let formsHost : WindowsFormsHost = window?chartHost
    formsHost.Child <- getChartControl

    let wpfApp = new System.Windows.Application()
    wpfApp.Run(window) |> ignore

As you can see rendering a FSharpChart is easily rendered within a WPF application.