Skip to content

Commit

Permalink
Merge pull request #11 from delsim/doc_tweaks
Browse files Browse the repository at this point in the history
Prerelease 0.4.3
  • Loading branch information
GibbsConsulting committed Jun 28, 2018
2 parents bcafcd4 + cc6767c commit 92a35de
Show file tree
Hide file tree
Showing 21 changed files with 292 additions and 88 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Then, just add `django_plotly_dash` to `INSTALLED_APPS` in your Django `settings
...
]

Note that this package requires version 2.0 or greater of Django, due to the use of the `path` function for registering routes.

## Demonstration

The source repository contains a demo application. To clone the repo and lauch the demo:
Expand Down
8 changes: 8 additions & 0 deletions demo/demo/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import os
import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo.settings")
django.setup()
application = get_default_application()

16 changes: 16 additions & 0 deletions demo/demo/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ def __init__(self, *args, **kwargs):
global ALL_CONSUMERS
ALL_CONSUMERS.append(self)

print("Creating a MessageConsumer")
print(len(ALL_CONSUMERS))

self.callcount = 0

def connect(self):
self.accept()

Expand All @@ -20,6 +25,7 @@ def disconnect(self, close_code):
if c != self:
ac.append(c)
ALL_CONSUMERS = ac
return super(MessageConsumer, self).disconnect(close_code)

def send_to_widgets(self, channel_name, label, value):
message = json.dumps({'channel_name':channel_name,
Expand All @@ -30,6 +36,16 @@ def send_to_widgets(self, channel_name, label, value):
for c in ALL_CONSUMERS:
c.send(message)

self.callcount += 1
if self.callcount > 10:
import gc
print("Running collection")
gc.collect()
self.callcount = 0

import objgraph
objgraph.show_most_common_types()

def receive(self, text_data):
message = json.loads(text_data)

Expand Down
15 changes: 14 additions & 1 deletion demo/demo/plotly_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ def callback_size(dropdown_color, dropdown_size):
)
def callback_c(*args,**kwargs):
da = kwargs['dash_app']

session_state = kwargs['session_state']

calls_so_far = session_state.get('calls_so_far',0)
session_state['calls_so_far'] = calls_so_far + 1

user_counts = session_state.get('user_counts',None)
user_name = str(kwargs['user'])
if user_counts is None:
user_counts = {user_name:1}
session_state['user_counts'] = user_counts
else:
user_counts[user_name] = user_counts.get(user_name,0) + 1

return "Args are [%s] and kwargs are %s" %(",".join(args),str(kwargs))

a3 = DjangoDash("Connected")
Expand All @@ -67,7 +81,6 @@ def callback_c(*args,**kwargs):
label="momentum",
channel_name="test_widget_channel",
uid="and_this_one"),
dpd.DPDirectComponent(id="direct"),
dcc.RadioItems(id="dropdown-one",options=[{'label':i,'value':j} for i,j in [
("O2","Oxygen"),("N2","Nitrogen"),("CO2","Carbon Dioxide")]
],value="Oxygen"),
Expand Down
25 changes: 17 additions & 8 deletions demo/demo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
'django.contrib.staticfiles',

'channels',
'bootstrap4',

'django_plotly_dash.apps.DjangoPlotlyDashConfig',
]
Expand Down Expand Up @@ -126,14 +127,22 @@
STATIC_ROOT = os.path.join(BASE_DIR,'static')

STATICFILES_DIRS = [
os.path.join(BASE_DIR,'demo','static'),
]

import dash_core_components as dcc
_rname = os.path.join(os.path.dirname(dcc.__file__),'..')
for dash_module_name in ['dash_core_components',
'dash_html_components',
'dash_renderer',]:
STATICFILES_DIRS.append( ("dash/%s"%dash_module_name, os.path.join(_rname,dash_module_name)) )
# In order to serve dash components locally - not recommended in general, but
# can be useful for development especially if offline - we add in the root directory
# of each module. This is a bit of fudge and only needed if serve_locally=True is
# set on a DjangoDash instance.

if DEBUG:

import dash_core_components as dcc
_rname = os.path.join(os.path.dirname(dcc.__file__),'..')

for dash_module_name in ['dash_core_components',
'dash_html_components',
'dash_renderer',
'dpd_components',]:
STATICFILES_DIRS.append( ("dash/%s"%dash_module_name, os.path.join(_rname,dash_module_name)) )

# Fudge to work with channels in debug mode
STATICFILES_DIRS.append(("dash/dpd_components","/home/mark/local/dpd-components/lib"))
6 changes: 6 additions & 0 deletions demo/demo/static/demo/demo.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* Extra CSS markup for demo pages */

.btnspace { margin-bottom: 10px; }

.dpd-example-wrapper { background-color: #e0e0e0; padding: 10px; }
.dpd-example { background-color: white; }
30 changes: 30 additions & 0 deletions demo/demo/templates/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<html>
<head>
{%load plotly_dash%}
{%load staticfiles%}
{%load bootstrap4%}
{%bootstrap_css%}
{%bootstrap_javascript jquery="full"%}
<link rel="stylesheet" type="text/css" href="{%static "demo/demo.css"%}"></link>
<title>Django Plotly Dash Examples - {%block title%}{%endblock%}</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="navbar-nav">
<a class="navbar-brand" href="#">
<img src="{%static "demo/logo.svg"%}" alt="Logo"/>
</a>
<a class="nav-item nav-link btn btn-lg" href="{%url "home"%}">Contents</a>
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-one"%}">Demo One - Simple Use</a>
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-two"%}">Demo Two - Initial State</a>
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-three"%}">Demo Three - Enhanced Callbacks</a>
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-four"%}">Demo Four - Live Updating</a>
</div>
</nav>
<div class="container">
{%block content%}{%endblock%}
</div>
</body>
{%block post_body%}{%endblock%}
</html>
34 changes: 34 additions & 0 deletions demo/demo/templates/demo_four.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{%extends "base.html"%}
{%load plotly_dash%}

{%block post_body%}{%plotly_message_pipe%}{%endblock%}

{%block title%}Demo Four - Live Updating{%endblock%}

{%block content%}
<h1>Live Updating</h1>
<p>
Live updating uses a websocket connection. The server pushes messages to the UI, and this is then translated into a
callback through a dash component.
</p>
<div class="card bg-light border-dark">
<div class="card-body">
<p><span>{</span>% load plotly_dash %}</p>
<p><span>{</span>% plotly_app slug="connected-2" %}</p>
</div>
</div>
<p>
</p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app slug="connected-2"%}
</div>
</div>
<p>
</p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app slug="connected-2"%}
</div>
</div>
{%endblock%}
26 changes: 26 additions & 0 deletions demo/demo/templates/demo_one.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{%extends "base.html"%}
{%load plotly_dash%}

{%block title%}Demo One - Simple Embedding{%endblock%}

{%block content%}
<h1>Simple App Embedding</h1>
<p>
This is a simple example of use of a dash application within a Django template. Use of
the plotly_app template tag with the name of a dash application represents the simplest use of
the django_plotly_dash framework.
</p>
<div class="card bg-light border-dark">
<div class="card-body">
<p><span>{</span>% load plotly_dash %}</p>
<p><span>{</span>% plotly_app name="SimpleExample" %}</p>
</div>
</div>
<p></p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app name="SimpleExample"%}
</div>
</div>
{%endblock%}

42 changes: 42 additions & 0 deletions demo/demo/templates/demo_three.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{%extends "base.html"%}
{%load plotly_dash%}

{%block title%}Demo Three - Additional Callback Functionality{%endblock%}

{%block content%}
<h1>Enhanced Callback Functionality</h1>
<p>
If any callback is registered as an enhanced one, then all of the callbacks receive extra values
as kwargs. These include the Dash application instance, a per-session dictionary that can contain anything
suitable for inclusion in a standard Django session, and the Django User instance.
The session state is per user session at the Django level, so it is shared across all of the Dash applications.
</p>
<p>
Changes made to any values contained within the initial state can also be persisted when using enhanced callbacks. This is a
per-app-instance flag and, when set, the response of every callback is checked and persisted if it has changed. The second
of the two apps below is configured in this manner; any changes made on this page should reappear if one visits a different page and
then reloads this one. These changes can also be observed in the update timestamp or initial content json content of
the <a href="{%url "admin:django_plotly_dash_dashapp_changelist" %}">model</a>.
</p>
<div class="card bg-light border-dark">
<div class="card-body">
<p><span>{</span>% load plotly_dash %}</p>
<p><span>{</span>% plotly_app name="Ex2" ratio=0.15 %}</p>
<p><span>{</span>% plotly_app slug="ex2-3" ratio=0.15 %}</p>
</div>
</div>
<p>
</p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app name="Ex2" ratio=0.15 %}
</div>
</div>
<p>
</p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app slug="ex2-3" ratio=0.15 %}
</div>
</div>
{%endblock%}
30 changes: 30 additions & 0 deletions demo/demo/templates/demo_two.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{%extends "base.html"%}
{%load plotly_dash%}

{%block title%}Demo Two - Initial State{%endblock%}

{%block content%}
<h1>Initial State</h1>
<p>
Referring to an instance of a dash application, uniquely identified by a slug, will use the persisted
representation of that app along with its initial state.
</p>
<p>
Each time this page is reloaded, the application will revert to its stored intial state. This initial
state is persisted in a standard
Django <a href="{%url "admin:django_plotly_dash_dashapp_changelist" %}">model</a>.
</p>
<div class="card bg-light border-dark">
<div class="card-body">
<p><span>{</span>% load plotly_dash %}</p>
<p><span>{</span>% plotly_app slug="simpleexample-1" ratio=0.2 %}</p>
</div>
</div>
<p>
</p>
<div class="card border-dark">
<div class="card-body">
{%plotly_app slug="simpleexample-1" ratio=0.2 %}
</div>
</div>
{%endblock%}
51 changes: 15 additions & 36 deletions demo/demo/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
<!DOCTYPE HTML>
<html>
<head>
{%load plotly_dash%}
<title>Simple stuff</title>
</head>
<body>
<div>
<p>Navigational links :
<a href="{%url "home"%}">Main Page</a>
<a href="{%url "second"%}">Second Page</a>
</p>
</div>
<div>
Content here
{%plotly_app slug="simpleexample-1" ratio=0.2 %}
</div>
<div>
Content here
{%plotly_app name="SimpleExample"%}
</div>
<div>
Content here
{%plotly_app name="Ex2"%}
</div>
<div>
WS Content here
{%plotly_app name="Connected"%}
</div>
<div>
WS Content here
{%plotly_app slug="connected-2"%}
</div>
</body>
{%plotly_message_pipe%}
</html>
{%extends "base.html"%}
{%block title%} Index{%endblock%}
{%block content%}
<h1>Demonstration Application</h1>
<div>
This is the django_plotly_dash demo application. It contains a number of separate pages that
exhibit different features of the integration of Plotly Dash into the Django framework.
</div>
<ul class="btnspace">
<li><a class="btn btn-primary btnspace" href="{%url "demo-one"%}">Demo One</a> - direct insertion of one or more Dash applications into a Django template</li>
<li><a class="btn btn-primary btnspace" href="{%url "demo-two"%}">Demo Two</a> - storage of application initial state within Django</li>
<li><a class="btn btn-primary btnspace" href="{%url "demo-three"%}">Demo Three</a> - adding Django features with enhanced callbacks</li>
<li><a class="btn btn-primary btnspace" href="{%url "demo-four"%}">Demo Four</a> - live updating of apps by pushing from the Django server</li>
</ul>
{%endblock%}
23 changes: 0 additions & 23 deletions demo/demo/templates/second_page.html

This file was deleted.

0 comments on commit 92a35de

Please sign in to comment.