Getting Started with Dash.NET!

Getting started with Dash.NET

Hello!

This post is meant to be used as a jumping off point to get you up and running with Dash.NET and point you in the direction of useful resources to continue exploring.

We will be using version 0.2.0-alpha.1, so some parts of this may change in future releases.

This post also assumes you are already at least somewhat familiar with F# and the .NET ecosystem.If you are new to F# then there are wonderful resources on the official F# website (link) as well as in Microsoft’s F# documentation (link) to help you get started.

Creating a new project

There are two ways to get started on a new Dash.NET project:

Creating a project from the Dash.NET template

This is the method that I would recommend you use if you are new to Dash. To download and install the template use the command:

dotnet new -i Dash.NET.Template::*

You can then create a new project with the template using:

dotnet new dash

This will create a new project containing a sample Dash.NET app that has examples of how to lay out your app, how to create a Plotly.NET graph, and an example of how to use callbacks.

Creating a project from scratch

This method is more for if you are familiar with the structure of a Dash app from another language and just want to start with a clean slate, or have an existing app you want to integrate Dash.NET into. If you aren’t integrating it into an existing project you first need to create one with either Visual Studio or the command:

dotnet new console -lang F#

You can then add the latest version of Dash.NET to the project with:

dotnet add package Dash.NET --prerelease

Note that we need to use the --prerelease flag while Dash.NET is in alpha.

Now you are ready to make your first Dash.NET app. Here is a hello world example to get you started:

open Dash.NET
open Dash.NET.Giraffe
open Microsoft.Extensions.Logging
open Giraffe.Core

let dslLayout = 
    Html.div [
        Attr.children "Hello World!"
    ]

[<EntryPoint>]
let main args =
    DashApp.initDefault()
    |> DashApp.withLayout dslLayout
    |> DashApp.run args {HostName = "localhost"; LogLevel = LogLevel.Debug; ErrorHandler = ((fun ex ->  ex.Message) >> text)}

When you compile and run the app you can then navigate to http:\\localhost:5001 to view it. A handy trick if you are using Visual Studio is to go into the *.fsproj file and change <Project Sdk="Microsoft.NET.Sdk"> to <Project Sdk="Microsoft.NET.Sdk.Web"> and reload the project, this will let you run the application with IIS Express and hitting run will automatically open a browser to your application.

Structure of a Dash.NET app

The following example outlines the basic structure of a Dash.NET. I have also included extra comments pointing out some notable quirks and small differences from the python version of Dash that may be useful.

open Dash.NET
open Dash.NET.Giraffe
open Microsoft.Extensions.Logging
open Giraffe.Core

// This describes the layout of the page served by Dash
// All elements and components use Feliz style constructors
let dslLayout =
    Html.div [
        Attr.children [
            Html.h6 [ 
                // For elements and components that just contain text you 
                // can call Attr.children with just a string
                Attr.children "Change the value in the text box to see callbacks in action!" 
            ]
            Html.div [
                Attr.children [
                    Html.text "Input: "
                    
                    // Input is a component in Dash.NET.DCC
                    // also unlike Html elements, Dash components require an id
                    // as their first argument, seen here as "my-input"
                    DCC.Input.input "my-input" [

                        // Unlike Html element's shared Attr definition, component 
                        // specific Attr definitions are included in the component's 
                        // module
                        DCC.Input.Attr.inputType ComponentPropTypes.Text

                        // Callbacks require any input values to be defined when they
                        // are called. Because PreventInitialCall is false in the callback
                        // it would throw an exception if this value was not set right when
                        // the page loaded
                        DCC.Input.Attr.value "initial value"
                    ]
                ]
            ]
            Html.br []
            Html.div [
                Attr.id "my-output"
                // Inline styles use the Dash.NET.Css module
                Attr.style [Css.color "red"]
            ]
        ]
    ]
// This describes a dash callback
let updateOutputDivCallback =
    // Callbacks are described with inputs listed first followed by outputs,
    // this is opposite to the python version
    Callback.singleOut (
        
        // Input:
        // For multiple inputs this can be replaces with a list
        "my-input" @. Value,
        
        // Output:
        // For multiple outputs use Callback.multiOut instead
        "my-output" @. Children,
        // Callback function:
        fun (inputValue:string) -> 
            // The left side of the => must match the output argument
            // The right side doesn't have to be a string, it can be any JSON convertible 
            // object such as another Dash component, Html element, or Plotly.NET figure.
            "my-output" @. Children => sprintf "Output: %s" inputValue
        // PreventInitialCall is true by default, unlike the python version of Dash where it is false
        , PreventInitialCall = false
    )

[<EntryPoint>]
let main args =
    // In Dash.NET the app is created blank and any properties you 
    // want to add like the layout definition, callbacks, or external files
    // are added with decorators
    DashApp.initDefault()
    |> DashApp.withLayout dslLayout
    |> DashApp.addCallback updateOutputDivCallback
    |> DashApp.appendCSSLinks [
        // All local files must be somewhere in a folder called "WebRoot"
        // at the root of your project, and this folder must be also copied 
        // to the build directory. The template sets this up for you.
        "main.css"
        // You can add external files in the same way you add local ones
        // CORS is enabled by default
        "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.1/css/bulma.min.css" 
    ]
    |> DashApp.run args {HostName = "localhost"; LogLevel = LogLevel.Debug; ErrorHandler = ((fun ex ->  ex.Message) >> text)}

Where to go from here

  • You can find further reading on how to use Dash.NET, as well as an API reference in the official documentation: Dash.NET documentation (link)

  • If you would like to contribute to Dash.NET, or need to dive into more technical details, you can find the source code on github: Dash.NET on Github (link)

1 Like