|
1 |
| -# Dash.NET |
| 1 | + |
2 | 2 |
|
3 |
| - |
| 3 | +[](https://www.nuget.org/packages/Dash.NET/) |
4 | 4 |
|
5 |
| -Dash.NET is a .NET interface to [Dash](https://plotly.com/dash/) - the most downloaded framework for building ML & data science web apps - written in F#. Built on top of Plotly.js, React and asp.netcore (via Giraffe), Dash.NET ties modern UI elements like dropdowns, sliders, and graphs directly to your analytical .NET code. |
| 5 | +Dash.NET is a .NET interface to [Dash](https://plotly.com/dash/) - the most downloaded framework for building ML & data science web apps - written in F#. Built on top of [Plotly.NET](https://github.com/plotly/Plotly.NET), React and asp.netcore (via Giraffe), Dash.NET ties modern UI elements like dropdowns, sliders, and graphs directly to your analytical .NET code. |
6 | 6 |
|
7 |
| -This library is under heavy development. Things might break. However, Dash.NET has a stable core and has already been used for [non trivial applications](https://github.com/CSBiology/TMEA). The current development goal is to implement all targets set in the [beta roadmap](https://github.com/plotly/Dash.NET/issues/4), where you can also see a summary of the state of the project. |
| 7 | +This library is under heavy development. Things might break. However, Dash.NET has a stable core and has already been used for non trivial applications ([example1](https://github.com/CSBiology/TMEA), [example2](https://github.com/TRR175/ExploreKinetics)). The current development goal is to implement all targets set in the [beta roadmap](https://github.com/plotly/Dash.NET/issues/4), where you can also see a summary of the state of the project. |
8 | 8 |
|
9 |
| -# Table of contents of this readme |
| 9 | +The documentation is WIP as well. |
10 | 10 |
|
11 | 11 | <!-- TOC -->
|
12 | 12 |
|
13 |
| -- [Usage](#usage) |
14 |
| - - [Basic application](#basic-application) |
15 |
| - - [Referencing content](#referencing-content) |
16 |
| - - [Dash Core components (DCC)](#dash-core-components-dcc) |
17 |
| - - [Basic callback](#basic-callback) |
18 |
| - - [Using state](#using-state) |
| 13 | +- [Installation](#installation) |
| 14 | +- [Documentation](#documentation) |
19 | 15 | - [Development](#development)
|
20 |
| - - [Windows](#windows) |
21 |
| - - [Linux/MacOS](#linuxmacos) |
22 |
| - - [Run the dev server application](#run-the-dev-server-application) |
| 16 | + - [build](#build) |
| 17 | + - [docs](#docs) |
| 18 | + - [release](#release) |
23 | 19 |
|
24 | 20 | <!-- /TOC -->
|
25 | 21 |
|
26 |
| -## Usage |
27 | 22 |
|
28 |
| -You can either use the [Dash.NET template](https://github.com/plotly/Dash.NET.Template) via the `dotnet new` templating engine to start from a new template dash application, or add Dash.NET to your existing project via our [preview nuget package](https://www.nuget.org/packages/Dash.NET) |
| 23 | +## Installation |
29 | 24 |
|
30 |
| -In Dash.NET, everything is basically about constructing a `DashApp` that holds all parts of your dash application, such as: |
31 |
| -- the `Layout`, which holds the UI components of your application |
32 |
| -- `Callbacks` that handle how different components in your `Layout` interact with each other |
33 |
| -- Various server and renderer configurations via `DashConfig` |
34 |
| -- The `IndexView` template that controls the html scaffold that holds the rendered application. |
| 25 | +Get the latest preview package via nuget: [](https://www.nuget.org/packages/Dash.NET/) |
35 | 26 |
|
36 |
| -The most simple (and boring) Dash.NET application looks like this: |
| 27 | +Use the `dotnet new` template: |
37 | 28 |
|
38 |
| -```F# |
39 |
| -open Dash.NET |
| 29 | +`dotnet new -i Dash.NET.Template::*` |
40 | 30 |
|
41 |
| -let myApp = DashApp.initDefault() |
42 |
| -``` |
43 |
| - |
44 |
| -Which creates a `DashApp` with all fields initialized with empty defaults. The http handler for a `DashApp` can be accessed via the `DashApp.toHttpHandler` function to plug it into your aps.netcore application configuration function via `UseGiraffe` (for more info, check out Giraffe docs or take a look at the [dev project in this repo](https://github.com/plotly/Dash.NET/blob/dev/dev/Program.fs#L104)) |
45 |
| - |
46 |
| -### Basic application |
47 |
| - |
48 |
| -To get actual content into the default application, it needs a `Layout`. `Layout`s can be created via Dash.NET's DSL for html components, where the first function parameter is always a list of properties (e.g. for setting css classes), and the second a list of children. |
49 |
| - |
50 |
| -```F# |
51 |
| -open Dash.NET.HTML |
52 |
| -
|
53 |
| -//Will create the following html: |
54 |
| -//<div> |
55 |
| -// <h1>"Hello world from Dash.NET!"</h1> |
56 |
| -//</div> |
57 |
| -// |
58 |
| -let myLayout = |
59 |
| - Div.div [] [ |
60 |
| - H1.h1 [] [str "Hello world from Dash.NET!"] |
61 |
| - ] |
62 |
| -let test = |
63 |
| - DashApp.initDefault() |
64 |
| - |> DashApp.withLayout myLayout |
65 |
| -``` |
66 |
| - |
67 |
| - |
68 |
| - |
69 |
| ---- |
70 |
| - |
71 |
| -<br> |
72 |
| - |
73 |
| -### Referencing content |
74 |
| - |
75 |
| -You can include internal and external stylesheets and scripts via `DashApp.appendCSSLinks` and `DashApp.appendScripts`: |
76 |
| - |
77 |
| -Let's say you have the following `main.css` file in your wwwroot directory (served from `/main.css`) |
78 |
| - |
79 |
| -```CSS |
80 |
| -h1 { |
81 |
| - font-size: 1.5em; |
82 |
| - color: green; |
83 |
| -} |
84 |
| -``` |
85 |
| - |
86 |
| -you can reference it from your `DashApp` like this (using the basic example from above): |
87 |
| - |
88 |
| -```F# |
89 |
| -let test = |
90 |
| - DashApp.initDefault() |
91 |
| - |> DashApp.withLayout myLayout |
92 |
| - |> DashApp.appendCSSLinks ["main.css"] |
93 |
| -
|
94 |
| -``` |
| 31 | +(watch out, this template might not use the latest Dash.NET package, take a look at the referenced version and update if needed ) |
95 | 32 |
|
96 |
| - |
| 33 | +## Documentation |
97 | 34 |
|
98 |
| ---- |
| 35 | +The landing page of our docs contains everything to get you started fast, check it out [📖 here](http://plotly.github.io/Dash.NET/) |
99 | 36 |
|
100 |
| -If you want to reference external content (e.g. a CSS framework like [Bulma](https://bulma.io/)), you can do that as well. To use the classes defined there, set the `ClassName` accordingly: |
101 |
| - |
102 |
| -```F# |
103 |
| -let myLayout = |
104 |
| - Div.div [] [ |
105 |
| - H1.h1 [ClassName "title is-1"] [str "Hello world from Dash.NET!"] |
106 |
| - ] |
107 |
| -
|
108 |
| -
|
109 |
| -let test = |
110 |
| - DashApp.initDefault() |
111 |
| - |> DashApp.withLayout myLayout |
112 |
| - |> DashApp.appendCSSLinks [ |
113 |
| - "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.1/css/bulma.min.css" |
114 |
| - ] |
115 |
| -``` |
116 |
| - |
117 |
| - |
118 |
| - |
119 |
| ---- |
| 37 | +## Development |
120 | 38 |
|
121 |
| -### Dash Core components (DCC) |
| 39 | +_Note:_ The `release` and `prerelease` build targets assume that there is a `NUGET_KEY` environment variable that contains a valid Nuget.org API key. |
122 | 40 |
|
123 |
| -You can also use most dash core components. The following example uses the Plotly.NET to create a plotly graph component. Note that all core components must have a nunique id, and therefore have the mandatory id parameter: |
| 41 | +### build |
124 | 42 |
|
125 |
| -```F# |
126 |
| -open Dash.NET.HTML |
127 |
| -open Dash.NET.DCC |
128 |
| -open Plotly.NET |
| 43 | +Check the [build.fsx file](https://github.com/plotly/Dash.NET/blob/dev/build.fsx) to take a look at the build targets. Here are some examples: |
129 | 44 |
|
130 |
| -let myGraph = Chart.Line([(1,1);(2,2)]) |
| 45 | +```shell |
| 46 | +# Windows |
131 | 47 |
|
132 |
| -let myLayout = |
133 |
| - Div.div [] [ |
134 |
| - H1.h1 [] [str "Hello world from Dash.NET!"] |
135 |
| - H2.h2 [] [str "Take a look at this graph:"] |
136 |
| - Graph.graph "my-ghraph-id" [Graph.Figure (myGraph |> GenericChart.toFigure)] [] |
137 |
| - ] |
138 |
| -let test = |
139 |
| - DashApp.initDefault() |
140 |
| - |> DashApp.withLayout myLayout |
141 |
| -``` |
| 48 | +# Build only |
| 49 | +./build.cmd |
142 | 50 |
|
143 |
| - |
| 51 | +# Full release buildchain: build, test, pack, build the docs, push a git tag, publsih thze nuget package, release the docs |
| 52 | +./build.cmd -t release |
144 | 53 |
|
145 |
| ---- |
| 54 | +# The same for prerelease versions: |
| 55 | +./build.cmd -t prerelease |
146 | 56 |
|
147 |
| -<br> |
148 | 57 |
|
149 |
| -### Basic callback |
| 58 | +# Linux/mac |
150 | 59 |
|
151 |
| -Callbacks describe the interactive part of your `DashApp`. In the most basic case, you have one input component, which updates one output component. For both you need to assign the property of the component that will be part of the callback. Additionally, a function is needed that takes the input and returns the output: |
| 60 | +# Build only |
| 61 | +build.sh |
152 | 62 |
|
153 |
| -```F# |
154 |
| -open Dash.NET.HTML |
155 |
| -open HTMLPropTypes |
156 |
| -open Dash.NET.DCC |
157 |
| -open ComponentPropTypes |
| 63 | +# Full release buildchain: build, test, pack, build the docs, push a git tag, publsih thze nuget package, release the docs |
| 64 | +build.sh -t release |
158 | 65 |
|
159 |
| -let myLayout = |
160 |
| - Div.div [] [ |
161 |
| - H1.h1 [] [str "Hello world from Dash.NET!"] |
162 |
| - H2.h2 [] [str "Tell us something!"] |
163 |
| - Input.input "test-input" [Input.Type InputType.Text] [] |
164 |
| - H2.h2 [Id "test-output"] [] |
165 |
| - ] |
| 66 | +# The same for prerelease versions: |
| 67 | +build.sh -t prerelease |
166 | 68 |
|
167 |
| -let testCallback = |
168 |
| - Callback( |
169 |
| - [CallbackInput.create("test-input","value")], // <- Input of the callback is the `value` property of the component with the id "test-input" |
170 |
| - CallbackOutput.create("test-output","children"), // <- Output of the callback is the `children` property of the component with the id "test-output" |
171 |
| - |
172 |
| - (fun (input:string) -> // this function takes a string as input and returns another message. |
173 |
| - sprintf "You said : %s" input |
174 |
| - ) |
175 |
| - ) |
176 |
| -
|
177 |
| -let test = |
178 |
| - DashApp.initDefault() |
179 |
| - |> DashApp.withLayout myLayout |
180 |
| - |> DashApp.addCallback testCallback |
181 | 69 | ```
|
182 | 70 |
|
183 |
| -Note that it is currently necessary to provide the component properties in string form. You will have to take care of the correct amount and types of the callback function parameters. Binding a function with two parameters to above example would cause a runtime error. |
184 |
| - |
185 |
| - |
186 |
| - |
187 |
| ---- |
188 |
| - |
189 |
| -### Using state |
190 |
| - |
191 |
| -Use states as non-triggering input for callbacks. You can use the optional `State` constructor parameter of `Callback`. Just keep in mind that the state will be used for your callback function parameters _after_ the callback inputs: |
192 |
| - |
193 |
| -```F# |
194 |
| -let myLayout = |
195 |
| - Div.div [] [ |
196 |
| - H1.h1 [] [str "Hello world from Dash.NET!"] |
197 |
| - H2.h2 [] [str "Tell us something!"] |
198 |
| - Input.input "test-input" [Input.Type InputType.Text] [] |
199 |
| - H3.h3 [] [str "Input below will not trigger the callback"] |
200 |
| - Input.input "test-input-state" [Input.Type InputType.Text] [] |
201 |
| - H2.h2 [Id "test-output"] [] |
202 |
| - ] |
203 |
| -
|
204 |
| -let testCallback = |
205 |
| - Callback( |
206 |
| - [CallbackInput.create("test-input","value")], |
207 |
| - CallbackOutput.create("test-output","children"), |
208 |
| - (fun (input:string) (state:string) -> |
209 |
| - sprintf "You said : '%s' and we added the state: '%s'" input state |
210 |
| - ), |
211 |
| - State = [CallbackState.create("test-input-state","value")] |
212 |
| - ) |
213 |
| -
|
214 |
| -let test = |
215 |
| - DashApp.initDefault() |
216 |
| - |> DashApp.withLayout myLayout |
217 |
| - |> DashApp.addCallback testCallback |
218 |
| -``` |
| 71 | +### docs |
219 | 72 |
|
220 |
| - |
| 73 | +The docs are contained in `.fsx` and `.md` files in the `docs` folder. To develop docs on a local server with hot reload, run the following in the root of the project: |
221 | 74 |
|
222 |
| ---- |
| 75 | +```shell |
| 76 | +# Windows |
| 77 | +./build.cmd -t watchdocs |
223 | 78 |
|
224 |
| -## Development |
225 |
| - |
226 |
| -To build the project and dev server application, run the `fake.cmd` script in order to restore and build |
227 |
| - |
228 |
| -### Windows |
229 |
| -``` |
230 |
| -> ./fake.cmd build |
| 79 | +# Linux/mac |
| 80 | +./build.sh -t watchdocs |
231 | 81 | ```
|
232 | 82 |
|
233 |
| -### Linux/MacOS |
234 |
| -``` |
235 |
| -$ ./fake.sh build |
236 |
| -``` |
237 |
| - |
238 |
| -### Run the dev server application |
239 | 83 |
|
240 |
| -The dev server is useful to test new components/code. After a successful build |
241 |
| -you can start the dev server application by executing the following command in your terminal: |
| 84 | +### release |
242 | 85 |
|
243 |
| -``` |
244 |
| -dotnet run -p ./dev/Dash.NET.Dev.fsproj |
245 |
| -``` |
| 86 | +Library license |
| 87 | +=============== |
246 | 88 |
|
247 |
| -After the application has started visit [https://localhost:5001/](https://localhost:5001/) or [http://localhost:5000/](http://localhost:5000/) in your preferred browser. |
| 89 | +The library is available under the [MIT license](https://github.com/plotly/Dash.NET/blob/dev/LICENSE). |
0 commit comments