Skip to content

Instantly share code, notes, and snippets.

@ademar
Last active October 14, 2021 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ademar/7ce6236124c7f3aa1639e5b760c8edb3 to your computer and use it in GitHub Desktop.
Save ademar/7ce6236124c7f3aa1639e5b760c8edb3 to your computer and use it in GitHub Desktop.
Dash Giraffe example
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<WarnOn>3390;$(WarnOn)</WarnOn>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Data" Version="4.2.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dash.NET.Giraffe" Version="0.2.0-alpha.5" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="5.0.0" />
</ItemGroup>
</Project>
open Dash.NET
open Feliz
open FSharp.Data
open Plotly.NET
open Dash.NET.DCC
open Dash.NET.Giraffe
open Microsoft.Extensions.Logging
open Plotly.NET.LayoutObjects
let df = CsvFile.Load("https://plotly.github.io/datasets/country_indicators.csv").Rows |> List.ofSeq
let available_indicators = df |> List.map (fun r -> r.Item "Indicator Name") |> List.distinct
let dslLayout =
Html.div [
Attr.children [
Html.div [
Attr.children [
Dropdown.dropdown "xaxis-column" [
Dropdown.Attr.options (available_indicators |> List.map (fun i -> DropdownOption.init( i, i,false, i)))
Dropdown.Attr.value "Fertility rate, total (births per woman)"
]
RadioItems.radioItems "xaxis-type" [
RadioItems.Attr.options (["Linear"; "Log"] |> List.map (fun i -> RadioItemsOption.init( i, i,false)))
RadioItems.Attr.value "Linear"
RadioItems.Attr.labelStyle [Css.displayInlineBlock]
]
]
Attr.style [Css.width (length.perc 48); Css.displayInlineBlock]
]
Html.div [
Attr.children [
Dropdown.dropdown "yaxis-column" [
Dropdown.Attr.options (available_indicators |> List.map (fun i -> DropdownOption.init( i, i,false, i)))
Dropdown.Attr.value "Life expectancy at birth, total (years)"
]
RadioItems.radioItems "yaxis-type" [
RadioItems.Attr.options (["Linear"; "Log"] |> List.map (fun i -> RadioItemsOption.init( i, i,false)))
RadioItems.Attr.value "Linear"
RadioItems.Attr.labelStyle [Css.displayInlineBlock]
]
]
Attr.style [Css.width (length.perc 48); Css.floatRight; Css.displayInlineBlock]
]
Graph.graph "indicator-graphic" []
Slider.slider "year-slider" [
Slider.Attr.min (df |> List.map (fun r -> r.Item "Year" |> float) |> List.min)
Slider.Attr.max (df |> List.map (fun r -> r.Item "Year" |> float) |> List.max)
Slider.Attr.value (df |> List.map (fun r -> r.Item "Year" |> float) |> List.min)
Slider.Attr.marks (
df
|> List.map (fun r -> r.Item "Year")
|> List.distinct
|> List.map (fun y -> (float y, Slider.Mark.Value (y)))
|> Map.ofList
//|> Slider.Marks
)
]
]
]
let updateFigureCallback =
Callback.singleOut (
[ "xaxis-column" @. Value
"yaxis-column" @. Value
"xaxis-type" @. Value
"yaxis-type" @. Value
"year-slider" @. Value ],
"indicator-graphic" @. (CustomProperty "figure"),
fun xaxisColumnName yaxisColumnName xaxisType yaxisType yearValue ->
let filteredDf = df |> List.filter (fun r -> r.Item "Year" = yearValue)
let xData = filteredDf |> List.filter (fun r -> r.Item "Indicator Name" = xaxisColumnName) |> List.map (fun r -> r.Item "Value")
let yData = filteredDf |> List.filter (fun r -> r.Item "Indicator Name" = yaxisColumnName) |> List.map (fun r -> r.Item "Value")
let countryData = filteredDf |> List.map (fun r -> r.Item "Country Name")
let fig =
Chart.Scatter(
xData,
yData,
StyleParam.Mode.Markers,
Labels = countryData
)
|> Chart.withXAxis(
LinearAxis.init(
AxisType = (if xaxisType = "Linear" then StyleParam.AxisType.Linear else StyleParam.AxisType.Log),
Title = Title.init(xaxisColumnName)
)
)
|> Chart.withYAxis(
LinearAxis.init(
AxisType = (if yaxisType = "Linear" then StyleParam.AxisType.Linear else StyleParam.AxisType.Log),
Title = Title.init(yaxisColumnName)
)
)
|> GenericChart.toFigure
"indicator-graphic" @. (CustomProperty "figure") => fig
, PreventInitialCall = false
)
// To listen in all IP addresses set IpAddress = "*"
let config =
{ HostName = "localhost"
; IpAddress = "*"
; Port = 8000
; LogLevel = LogLevel.Debug
; ErrorHandler = (fun ex -> Giraffe.Core.text ex.Message) }
[<EntryPoint>]
let main args =
DashApp.initDefault()
|> DashApp.withLayout dslLayout
|> DashApp.addCallback updateFigureCallback
|> DashApp.run args config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment