Last active
October 14, 2021 19:00
-
-
Save ademar/7ce6236124c7f3aa1639e5b760c8edb3 to your computer and use it in GitHub Desktop.
Dash Giraffe example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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