Giter Club home page Giter Club logo

tom_dash's Introduction

tom_dash

This module supplements the TOM Toolkit module with Plotly Dash support for more responsive plotting.

Please note that this module is a proof-of-concept and should be considered to be in alpha.

Installation

Install the module into your TOM environment:

`pip install git+https://github.com/TOMToolkit/tom_dash`

Add tom_dash and django_plotly_dash.apps.DjangoPlotlyDashConfig to the INSTALLED_APPS in your TOM's settings.py:

    INSTALLED_APPS = [
        'django.contrib.admin',
        ...
        'tom_dataproducts',
        'tom_dash',
        'django_plotly_dash.apps.DjangoPlotlyDashConfig'
    ]

Add STATIC_ROOT = os.path.join(BASE_DIR, '_static') and the following STATICFILES_FINDERS configuration to your settings.py, ideally in the Static files (CSS, JavaScript, Images) section:

    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, '_static')
    MEDIA_ROOT = os.path.join(BASE_DIR, 'data')
    MEDIA_URL = '/data/'

    STATICFILES_FINDERS = [

        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',

        'django_plotly_dash.finders.DashAssetFinder',
        'django_plotly_dash.finders.DashComponentFinder',
        'django_plotly_dash.finders.DashAppDirectoryFinder',
    ]

Add django_plotly_dash.middleware.BaseMiddleware to MIDDLEWARE in your settings.py:

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        ...
        'django_plotly_dash.middleware.BaseMiddleware',
        'tom_common.middleware.Raise403Middleware',
        ...
    ]

Add the following Django Plotly Dash configuration to your settings.py:

# django-plotly-dash configuration

X_FRAME_OPTIONS = 'SAMEORIGIN'

PLOTLY_COMPONENTS = [
    # Common components
    'dash_core_components',
    'dash_html_components',
    'dash_renderer',

    # django-plotly-dash components
    'dpd_components',
    # static support if serving local assets
    # 'dpd_static_support',

    # Other components, as needed
    'dash_bootstrap_components',
    'dash_table'
]

Add the django_plotly_dash.urls paths to your base urls.py:

    url_patterns = [
        path('', include('tom_common.urls')),
        path('django_plotly_dash/', include('django_plotly_dash.urls')),
    ]

Finally, run the following to run the django-plotly-dash migrations:

    ./manage.py migrate

Including a plot in your TOM

As of 8/27/2021, the sole plot offered by this library is the target_distribution plot, which is a good example for integration.

In order to integrate the target_distribution plot, first override the target_list.html template by copying target_list.html from the base TOM Toolkit and placing it in <project>/templates/tom_targets/target_list.html.

Add dash_extras to the {% load bootstrap4 target_extras ... %} templatetag near the top of the file.

Replace {% target_distribution filter.qs %} with {% dash_target_distribution filter.qs %}

Writing a dash component

With the setup followed above, a dash component can be written with no further setup, but requires a bit of knowhow.

The three files needed for a dash component are as follows:

  • Templatetag module to write the templatetag
  • templates/<app_name>/partials/<file_name.html>
  • Module for the dash app

The partial is very simple, consisting of a minimum of the following:

{% load plotly_dash dash_extras static bootstrap4 %}
{% plotly_app name="TargetDistributionView" ratio=0.2 initial_arguments=dash_context %}

The templatetag should use partial that was created, and use the takes_context=True kwarg, as well as any additional values necessary. It should return, at minimum, the request from the context. In order to provide any additional context to the dash app itself, the return dictionary should include a dash_context key with a dict as the value. Each key/value pair in dash_context will need to correspond with a component in the dash app module.

@register.inclusion_tag('tom_dash/partials/target_distribution.html', takes_context=True)
def dash_target_distribution(context):
    return {
        'request': context['request'],
        'dash_context': {
            'username': {'value': context['request'].user.username},
            'target-filter': {'data': target_ids}
        }
    }

The last piece is the dash app itself. The full target_distribution example can be found here. Please refer to the Plotly Dash and Django Plotly Dash documentation for specific implementation documentation. However, in the context of writing a Dash app to work with the previously shown templatetag and partial, it should be noted that any components defined in the dash_context in the templatetag must match the IDs and property keys of the corresponding dash components:

app.layout = dhc.Div([
    dcc.Graph(
        id='target-distribution',
        figure=Figure(data=[], layout=layout)
    ),
    dcc.Input(id='username', type='hidden', value=''),
    dcc.Store(id='target-filter', data={})
])

@app.callback(
    Output('target-distribution', 'figure'),
    [Input('username', 'value')],
    [State('target-filter', 'data')]
)
def get_target_distribution_plot(username, target_filter_data):
    ...

Because the get_target_distribution_plot callback is triggered on page load, the username and target_filter dictionary entries will provide initial values to the dcc.Input(id='username') and dcc.Store(id='target-filter') that will be used to load the target distribution plot. Note that the nested dictionaries for each item in the dash_context includes a key/value pair that corresponds with the properties on the component type--username is an Input component that has a value property, while target-filter is a State component that has a data property.

While this plot doesn't have any visible inputs that would alter the state, custom components can include callbacks that fire on interactive inputs.

tom_dash's People

Contributors

dmcollom avatar

Watchers

James Cloos avatar Mark Bowman avatar  avatar Rachel Street avatar

tom_dash's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.