Dash.jl

Dash for Julia - A Julia interface to the Dash ecosystem for creating analytic web applications in Julia. No JavaScript required.
Popularity
486 Stars
Updated Last
2 Months Ago
Started In
April 2020

Dash for Julia

Juila tests CircleCI GitHub GitHub commit activity

Create beautiful, analytic applications in Julia

Built on top of Plotly.js, React and HTTP.jl, Dash ties modern UI elements like dropdowns, sliders, and graphs directly to your analytical Julia code.

Just getting started? Check out the Dash for Julia User Guide! If you can't find documentation there, then check out the unofficial contributed examples or check out source code from demo applications in Python and then reference the Julia syntax style.

Other resources

Project Status

Julia components can be generated in tandem with Python and R components. Interested in getting involved with the project? Sponsorship is a great way to accelerate the progress of open source projects like this one; please feel free to reach out to us!

Installation

To install the most recently released version:

pkg> add Dash

To install the latest (stable) development version instead:

pkg> add Dash#dev

Usage

Basic application

using Dash

app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div() do
    html_h1("Hello Dash"),
    html_div("Dash.jl: Julia interface for Dash"),
    dcc_graph(id = "example-graph",
              figure = (
                  data = [
                      (x = [1, 2, 3], y = [4, 1, 2], type = "bar", name = "SF"),
                      (x = [1, 2, 3], y = [2, 4, 5], type = "bar", name = "Montréal"),
                  ],
                  layout = (title = "Dash Data Visualization",)
              ))
end

run_server(app)

then go to http://127.0.0.1:8050 in your browser to view the Dash app!

Basic Callback

using Dash

app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div() do
    dcc_input(id = "my-id", value = "initial value", type = "text"),
    html_div(id = "my-div")
end

callback!(app, Output("my-div", "children"), Input("my-id", "value")) do input_value
    "You've entered $(input_value)"
end

run_server(app)
  • You can make your Dash app interactive by registering callbacks with the callback! function.
  • Outputs and inputs (and states, see below) of callback can be Output, Input, State objects or splats / vectors of this objects.
  • Callback functions must have the signature (inputs..., states...), and provide a return value with the same number elements as the number of Outputs to update.

States and Multiple Outputs

using Dash

app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div() do
    dcc_input(id = "my-id", value = "initial value", type = "text"),
    html_div(id = "my-div"),
    html_div(id = "my-div2")
end

callback!(app,
          Output("my-div","children"),
          Output("my-div2","children"),
          Input("my-id", "value"),
          State("my-id", "type")) do input_value, state_value
    return ("You've entered $(input_value) in input with type $(state_value)",
            "You've entered $(input_value)")
end

run_server(app)

Comparison with original Python syntax

Component naming

  • Python:
import dash

dash.html.Div
dash.dcc.Graph
dash.dash_table.DataTable
  • Dash.jl:
using Dash

html_div
dcc_graph
dash_datatable

Component creation

Just as in Python, functions for declaring components have keyword arguments, which are the same as in Python. html_div(id = "my-id", children = "Simple text").

For components which declare children, two additional signatures are available:

  • (children; kwargs..) and
  • (children_maker::Function; kwargs...)

So one can write html_div("Simple text", id = "my-id") for simple elements, or choose an abbreviated syntax with do syntax for complex elements:

html_div(id = "outer-div") do
    html_h1("Welcome"),
    html_div(id = "inner-div") do
        #= inner content =#
    end
end

Application and layout

  • Python:
app = dash.Dash(external_stylesheets=["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html.Div(children=[....])
  • Dash.jl:
app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div() do
    #= inner content =#
end

Callbacks

  • Python:
@app.callback(Output('output', 'children'),
              Input('submit-button', 'n_clicks')],
              State('state-1', 'value'),
              State('state-2', 'value'))
def update_output(n_clicks, state1, state2):
    # logic
  • Dash.jl:
callback!(app,
          Output("output", "children"),
          Input("submit-button", "n_clicks")],
          State("state-1", "value"),
          State("state-2", "value")) do n_clicks, state1, state2
    # logic
end

JSON

Dash apps transfer data between the browser (aka the frontend) and the Julia process running the app (aka the backend) in JSON. Dash.jl uses JSON3.jl for JSON serialization/deserialization.

Note that JSON3.jl converts

  • Vectors and Tuples to JSON arrays
  • Dicts and NamedTuples to JSON objects