Skip to content

Commit f33f600

Browse files
Merge pull request #39 from delsim/html_formation
Html formation to enable dash app without iframe
2 parents e1b2a51 + f751a6c commit f33f600

File tree

19 files changed

+536
-48
lines changed

19 files changed

+536
-48
lines changed

demo/demo/dash_apps.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
'''Dash demonstration application
2+
3+
TODO attribution here
4+
'''
5+
6+
# The linter doesn't like the members of the html and dcc imports (as they are dynamic?)
7+
#pylint: disable=no-member
8+
9+
import dash
10+
import dash_core_components as dcc
11+
import dash_html_components as html
12+
import plotly.graph_objs as go
13+
#import dpd_components as dpd
14+
import numpy as np
15+
from django_plotly_dash import DjangoDash
16+
17+
#from .urls import app_name
18+
app_name = "DPD demo application"
19+
20+
dashboard_name1 = 'dash_example_1'
21+
dash_example1 = DjangoDash(name=dashboard_name1,
22+
serve_locally=True,
23+
app_name=app_name
24+
)
25+
26+
# Below is a random Dash app.
27+
# I encountered no major problems in using Dash this way. I did encounter problems but it was because
28+
# I was using e.g. Bootstrap inconsistenyly across the dash layout. Staying consistent worked fine for me.
29+
dash_example1.layout = html.Div(id='main',
30+
children=[
31+
html.Div([dcc.Dropdown(id='my-dropdown1',
32+
options=[{'label': 'New York City', 'value': 'NYC'},
33+
{'label': 'Montreal', 'value': 'MTL'},
34+
{'label': 'San Francisco', 'value': 'SF'}
35+
],
36+
value='NYC',
37+
className='col-md-12',
38+
),
39+
html.Div(id='test-output-div')
40+
]),
41+
42+
dcc.Dropdown(
43+
id='my-dropdown2',
44+
options=[
45+
{'label': 'Oranges', 'value': 'Oranges'},
46+
{'label': 'Plums', 'value': 'Plums'},
47+
{'label': 'Peaches', 'value': 'Peaches'}
48+
],
49+
value='Oranges',
50+
className='col-md-12',
51+
),
52+
53+
html.Div(id='test-output-div2')
54+
55+
]) # end of 'main'
56+
57+
@dash_example1.expanded_callback(
58+
dash.dependencies.Output('test-output-div', 'children'),
59+
[dash.dependencies.Input('my-dropdown1', 'value')])
60+
def callback_test(*args, **kwargs): #pylint: disable=unused-argument
61+
'Callback to generate test data on each change of the dropdown'
62+
63+
# Creating a random Graph from a Plotly example:
64+
N = 500
65+
random_x = np.linspace(0, 1, N)
66+
random_y = np.random.randn(N)
67+
68+
# Create a trace
69+
trace = go.Scatter(x=random_x,
70+
y=random_y)
71+
72+
data = [trace]
73+
74+
layout = dict(title='',
75+
yaxis=dict(zeroline=False, title='Total Expense (£)',),
76+
xaxis=dict(zeroline=False, title='Date', tickangle=0),
77+
margin=dict(t=20, b=50, l=50, r=40),
78+
height=350,
79+
)
80+
81+
82+
fig = dict(data=data, layout=layout)
83+
line_graph = dcc.Graph(id='line-area-graph2', figure=fig, style={'display':'inline-block', 'width':'100%',
84+
'height':'100%;'})
85+
children = [line_graph]
86+
87+
return children
88+
89+
90+
@dash_example1.expanded_callback(
91+
dash.dependencies.Output('test-output-div2', 'children'),
92+
[dash.dependencies.Input('my-dropdown2', 'value')])
93+
def callback_test2(*args, **kwargs):
94+
'Callback to exercise session functionality'
95+
96+
print(args)
97+
print(kwargs)
98+
99+
children = [html.Div(["You have selected %s." %(args[0])]),
100+
html.Div(["The session context message is '%s'" %(kwargs['session_state']['django_to_dash_context'])])]
101+
102+
return children

demo/demo/plotly_apps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def callback_c(*args, **kwargs):
117117
return "Args are [%s] and kwargs are %s" %(",".join(args), str(kwargs))
118118

119119
liveIn = DjangoDash("LiveInput",
120-
serve_locally=True,
120+
serve_locally=False,
121121
add_bootstrap_links=True)
122122

123123
liveIn.layout = html.Div([

demo/demo/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
'django.middleware.csrf.CsrfViewMiddleware',
5252
'django.contrib.auth.middleware.AuthenticationMiddleware',
5353
'django.contrib.messages.middleware.MessageMiddleware',
54+
55+
'django_plotly_dash.middleware.BaseMiddleware',
56+
5457
'django.middleware.clickjacking.XFrameOptionsMiddleware',
5558
]
5659

demo/demo/templates/base.html

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
<!DOCTYPE HTML>
22
<html>
33
<head>
4-
{%load plotly_dash%}
5-
{%load staticfiles%}
6-
{%load bootstrap4%}
7-
{%bootstrap_css%}
8-
{%bootstrap_javascript jquery="full"%}
9-
{%block extra_header%}{%endblock%}
10-
{%block app_header_css%}
4+
{% load plotly_dash%}
5+
{% load staticfiles%}
6+
{% load bootstrap4%}
7+
{% bootstrap_css%}
8+
{% bootstrap_javascript jquery="full"%}
9+
{% block extra_header%}{% endblock%}
10+
{% block app_header_css%}
1111
<link rel="stylesheet" type="text/css" href="{%static "demo/demo.css"%}"></link>
12-
{%endblock%}
13-
<title>Django Plotly Dash Examples - {%block title%}{%endblock%}</title>
12+
{% endblock%}
13+
{% plotly_header%}
14+
<title>Django Plotly Dash Examples - {% block title%}{% endblock%}</title>
1415
</head>
1516
<body>
1617
<header>
@@ -19,26 +20,33 @@
1920
<a class="navbar-brand" href="#">
2021
<img src="{%static "demo/logo.svg"%}" alt="Logo"/>
2122
</a>
22-
{%block demo_items%}
23+
{% block demo_items %}
2324
<a class="nav-item nav-link btn btn-lg" href="{%url "home"%}">Contents</a>
24-
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-one"%}">Demo One - Simple Use</a>
25-
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-two"%}">Demo Two - Initial State</a>
26-
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-three"%}">Demo Three - Enhanced Callbacks</a>
27-
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-four"%}">Demo Four - Live Updating</a>
25+
{% block demo_menu_items %}
26+
{% if 0 %}
27+
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-one"%}">One - Simple Use</a>
28+
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-two"%}">Two - Initial State</a>
29+
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-three"%}">Three - Enhanced Callbacks</a>
30+
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-four"%}">Four - Live Updating</a>
31+
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-five"%}">Five - Direct Injection</a>
32+
<a class="nav-item nav-link btn btn-lg" href="{%url "demo-six"%}">Six - Simple Injection</a>
33+
{% endif %}
34+
{% endblock %}
2835
<a class="nav-item nav-link btn btn-lg"
2936
target="_blank"
3037
href="https://django-plotly-dash.readthedocs.io/en/latest/">Online Documentation</a>
31-
{%endblock%}
38+
{% endblock %}
3239
</div>
3340
</nav>
3441
</header>
3542
<main>
3643
<div class="container">
37-
{%block content%}{%endblock%}
44+
{% block content%}{% endblock%}
3845
</div>
3946
</main>
40-
{%block footer%}
41-
{%endblock%}
42-
</body>
43-
{%block post_body%}{%endblock%}
47+
{% block footer%}
48+
{% endblock%}
49+
</body>
50+
{% block post_body%}{% endblock%}
51+
{% plotly_footer%}
4452
</html>

demo/demo/templates/demo_five.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{%extends "base.html"%}
2+
{%load plotly_dash%}
3+
4+
{%block title%}Demo One - Simple Embedding{%endblock%}
5+
6+
{%block content%}
7+
<h1>Direct App Embedding</h1>
8+
<p>
9+
This is a simple example of use of a dash application within a Django template. Use of
10+
the plotly_direct template tag with the name of a dash application causes
11+
the Dash application to be directly embedded within the page.
12+
</p>
13+
<p>
14+
The plotly_class tag is also used to wrap the application in css class names based on the
15+
application (django-plotly-dash), the
16+
type of the embedding (here labelled "div-direct"), and the slugified version of the app name (simpleexample).
17+
</p>
18+
<div class="card bg-light border-dark">
19+
<div class="card-body">
20+
<p><span>{</span>% load plotly_dash %}</p>
21+
<p>&lt;div class="<span>{</span>% plotly_class name="SimpleExample" template_type="div-direct"%}">
22+
<p class="ml-3"><span>{</span>% plotly_direct name="SimpleExample" %}</p>
23+
<p>&lt;\div>
24+
</div>
25+
</div>
26+
<p></p>
27+
<div class="card border-dark">
28+
<div class="card-body">
29+
<div class="{%plotly_class name="SimpleExample" template_type="div-direct"%}">
30+
{%plotly_direct name="SimpleExample"%}
31+
</div>
32+
</div>
33+
</div>
34+
<p></p>
35+
{%endblock%}

demo/demo/templates/demo_four.html

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ <h1>Live Updating</h1>
1111
Live updating uses a websocket connection. The server pushes messages to the UI, and this is then translated into a
1212
callback through a dash component.
1313
</p>
14+
<p>
15+
Each press of a button causes a new random value to be added to that colour's time series in each
16+
chart. Separate values are generated for each chart. The top chart has values
17+
local to this page, and the bottom chart - including its values - is shared across all views of this
18+
page.
19+
</p>
20+
<p>
21+
Reloading this page, or viewing in a second browser window, will show a new and initially empty
22+
top chart and a copy of the bottom chart. Pressing any button in any window will cause all instances
23+
of the bottom chart to update with the same values. Note that button presses are throttled so that
24+
only one press per colour per second is processed.
25+
</p>
1426
<div class="card bg-light border-dark">
1527
<div class="card-body">
1628
<p><span>{</span>% load plotly_dash %}</p>
@@ -45,7 +57,7 @@ <h1>Live Updating</h1>
4557
</p>
4658
<p>
4759
Any http command
48-
can be used to send a message to the apps. This is equiavent to a press of
60+
can be used to send a message to the apps. This is equivalent to a press of
4961
the red button. Other colours can be specified, including yellow, cyan and black in
5062
addition to the three named in the LiveInput app.
5163
</p>

demo/demo/templates/demo_six.html

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{%extends "base.html"%}
2+
{%load plotly_dash%}
3+
4+
{%block title%}Demo Six - Simple Injection{%endblock%}
5+
6+
{%block content%}
7+
8+
<h1>Simple embedding</h1>
9+
10+
<p>
11+
Direct insertion of html into a web page.
12+
</p>
13+
14+
<p>
15+
This demo is based on a contribution by, and
16+
with thanks to, <a href="https://github.com/eddy-ojb">@eddy-ojb</a>
17+
</p>
18+
19+
<div class="card bg-light border-dark">
20+
<div class="card-body">
21+
<p><span>{</span>% load plotly_dash %}</p>
22+
<p>&lt;div class="<span>{</span>% plotly_class name="dash_example_1" template_type="div-direct"%}">
23+
<p class="ml-3"><span>{</span>% plotly_direct name="dash_example_1" %}</p>
24+
<p>&lt;\div>
25+
</div>
26+
</div>
27+
<p></p>
28+
<div class="card border-dark">
29+
<div class="card-body">
30+
<div class="{%plotly_class name="dash_example_1" template_type="div-direct"%}">
31+
{%plotly_direct name="dash_example_1"%}
32+
</div>
33+
</div>
34+
</div>
35+
<p></p>
36+
{%endblock%}

demo/demo/templates/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ <h1>Demonstration Application</h1>
1111
<li><a class="btn btn-primary btnspace" href="{%url "demo-two"%}">Demo Two</a> - storage of application initial state within Django</li>
1212
<li><a class="btn btn-primary btnspace" href="{%url "demo-three"%}">Demo Three</a> - adding Django features with enhanced callbacks</li>
1313
<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>
14+
<li><a class="btn btn-primary btnspace" href="{%url "demo-five"%}">Demo Five</a> - injection of a Dash application without embedding in an html iframe</li>
15+
<li><a class="btn btn-primary btnspace" href="{%url "demo-six"%}">Demo Six</a> - simple html injection example</li>
1416
</ul>
1517
{%endblock%}

demo/demo/tests/test_dpd_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
def test_template_tag_use(client):
1111
'Check use of template tag'
1212

13-
for name in ['demo-one', 'demo-two', 'demo-three', 'demo-four',]:
13+
for name in ['demo-one', 'demo-two', 'demo-three', 'demo-four', 'demo-five', 'demo-six',]:
1414
url = reverse(name, kwargs={})
1515

1616
response = client.get(url)

demo/demo/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,20 @@
2727

2828
# Load demo plotly apps - this triggers their registration
2929
import demo.plotly_apps # pylint: disable=unused-import
30+
import demo.dash_apps # pylint: disable=unused-import
3031

3132
from django_plotly_dash.views import add_to_session
3233

34+
from .views import dash_example_1_view
35+
3336
urlpatterns = [
3437
url('^$', TemplateView.as_view(template_name='index.html'), name="home"),
3538
url('^demo-one$', TemplateView.as_view(template_name='demo_one.html'), name="demo-one"),
3639
url('^demo-two$', TemplateView.as_view(template_name='demo_two.html'), name="demo-two"),
3740
url('^demo-three$', TemplateView.as_view(template_name='demo_three.html'), name="demo-three"),
3841
url('^demo-four$', TemplateView.as_view(template_name='demo_four.html'), name="demo-four"),
42+
url('^demo-five$', TemplateView.as_view(template_name='demo_five.html'), name="demo-five"),
43+
url('^demo-six', dash_example_1_view, name="demo-six"),
3944
url('^admin/', admin.site.urls),
4045
url('^django_plotly_dash/', include('django_plotly_dash.urls')),
4146

0 commit comments

Comments
 (0)