Skip to content

Commit e299dc6

Browse files
delsimGibbsConsulting
authored andcommitted
Responsive template using Bootstrap (#201)
* Add a plotly_app_bootstrap template that uses Bootstrap4 to make the iframe containing the app responsive.
1 parent dbe423e commit e299dc6

File tree

6 files changed

+74
-6
lines changed

6 files changed

+74
-6
lines changed

demo/demo/templates/demo_seven.html

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,25 @@ <h1>Dash Bootstrap Components</h1>
1111
<div class="card bg-light border-dark">
1212
<div class="card-body">
1313
<p><span>{</span>% load plotly_dash %}</p>
14-
<p>&lt;div class="<span>{</span>% plotly_class name="BootstrapApplication"%}">
15-
<p class="ml-3"><span>{</span>% plotly_app name="BootstrapApplication" ratio=0.2 %}</p>
16-
<p>&lt;\div>
14+
<p>&lt;div class="container"></p>
15+
<p>&lt;div class="row"> &lt;div class="col-sm-6"></p>
16+
<p class="ml-2">&lt;div class="<span>{</span>% plotly_class name="BootstrapApplication"%}"></p>
17+
<p class="ml-3"><span>{</span>% plotly_app_bootstrap name="BootstrapApplication" aspect="21by9" %}</p>
18+
<p class="ml-2">&lt;\div></p>
19+
<p>&lt;\div> &lt;\div></p>
1720
</div>
1821
</div>
1922
<p></p>
2023
<div class="card border-dark">
2124
<div class="card-body">
22-
<div class="{%plotly_class name="BootstrapApplication"%}">
23-
{%plotly_app name="BootstrapApplication" ratio=0.2 %}
25+
<div class="container">
26+
<div class="row">
27+
<div class="col-sm-6">
28+
<div class="{%plotly_class name="BootstrapApplication"%}">
29+
{%plotly_app_bootstrap name="BootstrapApplication" aspect="21by9" %}
30+
</div>
31+
</div>
32+
</div>
2433
</div>
2534
</div>
2635
</div>

django_plotly_dash/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ def __str__(self):
5454
def save(self, *args, **kwargs): # pylint: disable=arguments-differ
5555
if not self.slug or len(self.slug) < 2:
5656
self.slug = slugify(self.app_name)
57+
exist_count = StatelessApp.objects.filter(slug__startswith=self.slug).count()
58+
if exist_count > 0:
59+
self.slug = self.slug + str(exist_count+1)
5760
return super(StatelessApp, self).save(*args, **kwargs)
5861

5962
def as_dash_app(self):
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<div style="{{dstyle}}">
2-
<iframe src="{{app.base_url}}" style="{{istyle}}"frameborder="{{fbs}}"></iframe>
2+
<iframe src="{{app.base_url}}" style="{{istyle}}" frameborder="{{fbs}}"></iframe>
33
</div>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="embed-responsive embed-responsive-{{aspect}}">
2+
<iframe src="{{app.base_url}}" class="embed-responsive-item"></iframe>
3+
</div>

django_plotly_dash/templatetags/plotly_dash.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,26 @@ def plotly_app(context, name=None, slug=None, da=None, ratio=0.1, use_frameborde
7777

7878
return locals()
7979

80+
@register.inclusion_tag("django_plotly_dash/plotly_app_bootstrap.html", takes_context=True)
81+
def plotly_app_bootstrap(context, name=None, slug=None, da=None, aspect="4by3", initial_arguments=None):
82+
'Insert a dash application using a html iframe'
83+
84+
valid_ratios = ['21by9',
85+
'16by9',
86+
'4by3',
87+
'1by1',
88+
]
89+
90+
if aspect not in valid_ratios:
91+
raise ValueError("plotly_app_bootstrap requires a valid aspect ratio from %s, but was supplied %s" % (str(valid_ratios),
92+
aspect))
93+
94+
cache_id = store_initial_arguments(context['request'], initial_arguments)
95+
96+
da, app = _locate_daapp(name, slug, da, cache_id=cache_id)
97+
98+
return locals()
99+
80100
@register.simple_tag(takes_context=True)
81101
def plotly_header(context):
82102
'Insert placeholder for django-plotly-dash header content'

docs/template_tags.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,39 @@ a JSON-encoded string representation. Each entry in the dictionary has the ``id`
4242
value is a dictionary mapping property
4343
name keys to initial values.
4444

45+
.. _plotly_app_bootstrap
46+
47+
The ``plotly_app_bootstrap`` template tag
48+
-----------------------------------------
49+
50+
This is a variant of the ``plotly_app`` template for use with responsive layouts using the Bootstrap library
51+
52+
.. code-block:: jinja
53+
54+
{%load plotly_dash%}
55+
56+
{%plotly_app_bootstrap name="SimpleExample" aspect="16by9"%}
57+
58+
The tag arguments are similar to the ``plotly_app`` ones:
59+
60+
:name = None: The name of the application, as passed to a ``DjangoDash`` constructor.
61+
:slug = None: The slug of an existing ``DashApp`` instance.
62+
:da = None: An existing ``django_plotly_dash.models.DashApp`` model instance.
63+
:aspect= "4by3": The aspect ratio of the app. Should be one of 21by9, 16by9, 4by3 or 1by1.
64+
:initial_arguments = None: Initial arguments overriding app defaults and saved state.
65+
66+
At least one of ``da``, ``slug`` or ``name`` must be provided. An object identified by ``slug`` will always be used, otherwise any
67+
identified by ``name`` will be. If either of these arguments are provided, they must resolve to valid objects even if
68+
not used. If neither are provided, then the model instance in ``da`` will be used.
69+
70+
The aspect ratio has to be one of the available ones from
71+
the `Bootstrap <https://getbootstrap.com/docs/4.3/utilities/borders/>`_ framework.
72+
73+
The ``initial_arguments`` are specified as a python dictionary. This can be the actual ``dict`` object, or
74+
a JSON-encoded string representation. Each entry in the dictionary has the ``id`` as key, and the corresponding
75+
value is a dictionary mapping property
76+
name keys to initial values.
77+
4578
.. _plotly_direct:
4679

4780
The ``plotly_direct`` template tag

0 commit comments

Comments
 (0)