I am trying to show graphs made in plotly on a webpage served by flask.
The way it is set up now, they both display on the same page, one on top of the other. I want to show them individually on different pages.
The solution I found for plotly displays all of the graphs made, and I'm not sure how to get individual graphs
My flask/python
graphs = [
dict(
data=[thetaGraph, deltaGraph, alphaGraph, betaGraph,gammaGraph ],
layout=dict(
title='Brain Data'
)
),
dict(
data=[xGraph,yGraph,zGraph],
layout=dict(
title='Accelerometer Data'
)
),
]
ids = ['graph-{}'.format(i) for i, _ in enumerate(graphs)]
graphJSON = json.dumps(graphs, cls=plotly.utils.PlotlyJSONEncoder)
return render_template('index.html', title='Home',ids=ids, graphJSON=graphJSON)
And then the webpage
<div class="container">
<div class="row">
<!-- LEFT SIDE -->
<div class="col-6">
{% for id in ids %}
<div id="{{id}}"></div>
{% endfor %}
</div>
</div>
</div>
<footer>
<script type="text/javascript">
var graphs = {{graphJSON | safe}};
var ids = {{ids | safe}};
for(var i in graphs) {
Plotly.plot(ids[i], // the ID of the div, created above
graphs[i].data,
graphs[i].layout || {});
}
</script>
</footer>
Im unsure how to get just the first graph in that html, and then the second graph elsewhere on the page. Ive tried using {% for id in range(0,1) %} just to get the first element, or just putting <div id="{{ids[0]}}"></div>
but I get 'ids' in undefined
When printing out ids i get ['graph-0', 'graph-1'] which means that this is a list and I should be able to index it, but apparently that is not a thing with flask. I'm sure there is some strange way that flask needs it similarly to it's ways of reading from 2D arrays
I was able to figure out a way to complete my task, but it does not involve indexing arrays. Since the javascript creates usable id's I am able to show individual graphs by simple referencing them
Replacing
<div class="col-6">
{% for id in ids %}
<div id="{{id}}"></div>
{% endfor %}
</div>
With
<div class="col-6">
<div id="graph-0"></div>
</div>
Gave me the outcome I was looking for
Related
I am using wtforms as part of a Python + Flask project. There are some cases where I want multiple fields of a form to appear on the same line on the webpage. With SelectField, this works as expected. However, when I use IntegerField, it seems to automatically create a new line after the field is displayed, and I get have more than one on a line.
The Form:
class PremiumMandatory(FlaskForm):
match_dol = IntegerField('Dollar')
match_per = IntegerField('Percent')
The .html
{{form.match_dol.label}}
${{form.match_dol(size=3)}}
 
{{form.match_per(size=3)}}%
{% for error in form.match_per.errors %}
Using the above, the two fields also appear on different lines on the webpage. Ho do I keep then on the same line?
This is an entirely HTML/CSS problem. There are many ways to put multiple fields of a form on the same line, for example, you could use Bootstrap's grid system, which is very easy to use.
Another simple way is:
<form>
<div style="display: table;">
<div style="display: table-row;">
<div style="display: table-cell;">
{{ form.match_dol.label }}
{{ form.match_dol(size=3) }}
</div>
<div style="display: table-cell;">
{{ form.match_per.label }}
{{ form.match_per(size=3) }}
</div>
</div>
<div style="display: table-row;">
...
</div>
</div>
</form>
I'm working on a simple web application that lets users rate and comment on movies, storing them in a database to be viewed later. The user inputs a movie to rate, and if that movie title is shared by multiple films, they are prompted to specify which of those films they meant. I've chosen to do this with radio buttons in my html file, but I can't figure out how to get the text of the button chosen and use it in Flask. The application takes the name of the film chosen and prints that name at the top of a different html file, but no matter what I do it always prints "None" instead of the chosen title.
I was able to find this answer: Get the text of the selected radio button in JQuery , which led me to try
var confirmed = $("input[name='confirmation']:checked").parent('label').text();
in my html script in order to obtain the text of the checked button. But when I try to request this in Flask it does not work.
confirm.html :
<div id="id02" class="modal" data-backdrop="false">
<form class="modal-content animate" action="/confirm" method="post">
<span onclick="document.getElementById('id02').style.display='none'" class="close" title="Close Modal">×</span>
<div class="container">
<h1>Please Specify Which Title to Rate:</h1>
{% for movie in multi %}
<label class="container">{{movie["title"]}} ({{movie["year"]}})
<input type="radio" id={{movie["year"]}} name="confirmation">
<span class="checkmark"></span>
</label>
{% endfor %}
<button type="submit">Rate</button>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" onclick="document.getElementById('id02').style.display='none'" class="cancelbtn">Cancel</button>
</div>
</form>
</div>
<script>
// Get the modal when page is loaded
$(window).on('load',function(){
$('#id02').modal('show');
});
var modal = document.getElementById('id02');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
// variable storing the name of the film selected
var confirmed = $("input[name='confirmation']:checked").parent('label').text();
</script>
application.py :
#app.route("/confirm", methods=["GET", "POST"])
def confirm():
if request.method == "POST":
full = request.form.get("confirmed")
session["title"] = full # add movie title to session in order to use in rate function
return render_template("rate.html", full=full)
else:
return render_template("confirm.html")
I also have tried assigning an id to the button if it is checked in hopes of getting the text from the id, but when I tried this I just got "None" as well.
{% for movie in multi %}
<label class="container">{{movie["title"]}} ({{movie["year"]}})
<input type="radio" name="confirmation">
{% if checked=="checked" %}
<input type="hidden" id="confirmed" value="({{movie["year"]}})">
{% endif %}
<span class="checkmark"></span>
</label>
{% endfor %}
I'm very new to programming and this is my first time trying to make a web application, so any help on this is greatly appreciated!
When flask gives you a radio button value. It gives you the value attribute not the radio button text, so you only need to put value attributes to your radio buttons
I created some plots with bokeh and exported them as html files. I now try to add these plots in a django template. The first plot works just fine, but if I want to add a second one it is not displayed.
Here i have the python file that creates the bokeh html:
from bokeh.plotting import figure, output_file, show
output_file("test2.html",title="test2")
p = figure(plot_width=400, plot_height=400)
p.circle([1, 5, 7, 2, 5], [6, 7, 2, 5, 5], size=20, color="navy", alpha=0.5)
show(p)
This is the second plot, the first one is saved as test.html, the title is test and some of the point coordinates are different.
And here is my django template:
{% extends "MainPage/PageBase.html" %}
{% block content %}
<div class="container">
<div class="card">
<div class="card-header">
<font size="3">plot1</font>
</div>
<div class="card-body">
<blockquote class="blockquote mb-0">
<p><div class="basic">
{% include "GPanalysis\WorkingData\test.html" %}
</div></p>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-header">
<font size="3">plot2</font>
</div>
<div class="card-body">
<blockquote class="blockquote mb-0">
<p><div class="basic">
{% include "GPanalysis\WorkingData\test2.html" %}
</div></p>
</blockquote>
</div>
</div>
</div>
{% endblock %}
In the first box appears a graph but the second one is empty.
I switched the position of two plots, but only the one that comes first in the html script will be displayed. If I try to call the same graph twice, it will be plotted twice but the second one is directly below the first one and not at the location it should be according to the html script.
I am not sure if this is an error i have somewhere or if what I am trying is simply not possible. I am aware, that there are other possibilities to get multiple bokeh plots in one template, but this one would be the easyest for my situation as i have to generate the html files anyway.
Thanks for any helpful answer.
Don't do this. Bokeh file output is not designed or intended to be embedded this way, and there is no expectation that it should work well or at all:
File output generates full HTML files with their own <head>, by doing this you are 100% guaranteed to generate malformed HTML
Bokeh objects from different files will probably end up stomping on each other, because file output is not intended to be used this way.
There are APIs sepcifically purposed for Embedding Plots and Apps and those should be used.
I want to find the difference between two different values. But, I am getting a Jinja2 error. I am not sure about how to find the difference in this template.
I tried using - operator but this did not work. So, I used sub to find the difference between actual and predicted score.
{% for e in question.essays %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{loop.index}}</h3>
</div>
<div class="panel-body">
<div class="actual-score">Actual score: {% if e.actual_score %} {{e.actual_score|round(1)}}/5{% endif %}</div>
<div class="predicted-score">Predicted score: {% if e.predicted_score %}{{e.predicted_score|round(1)}}/5{% endif %}</div>
<p class="essay-text">Text: {{e.text}}</p>
<div class="diff">Difference: {{ e.actual_score|sub(e.predicted_score)}} </div>
</div>
I am getting this error:
TemplateAssertionError: no filter named 'sub'
According to the Jinja2 documentation, using - should work pretty fine. Also from my end, it is working just fine. Mind posting the error message you get when using the operator. I also cannot find the sub tag in the documentation for Jinja2.
Therefore, as Amazing Things Around You has said, I think this should work:
{{ e.actual_score - e.predicted_score }}
Just a side note, the only other template tag I have found that does arithmetic operations close to that is Django's add tag, which also does not do subtraction.
I wanted to print barcodes using for loop in python. This is my code:
`{%- from "templates/print_formats/standard_macros.html" import add_header -%}
<hr>
{% set a = doc.end %}
{% set count = 0 %}
<div class="row">
{%- for i in range(doc.start,doc.end) -%}
<div class="col-md-4 text-center">
<p style="font-family: Code39AzaleaFont;font-weight: normal;font-style: normal;font-size:30px;">
00000000000000{{ i }}</p>
{% set count = count + 1 %}
{{count}}
<br/>
</div>
{%- endfor -%}
</div>
<hr>
<br>
<p class="strong">
<br>
<br>
<br>
{{ _("Authorized Signatory") }}
</p>
</div>`
The problem is,I wanted to restrict the number of barcodes printed on one sheet of paper to 24.Is there any way to do that?
You can add a page break after every 24th barcode using:
{% if count % 24 %}<div style="page-break-before: always;"></div>{% endif %}
HTML doesn't have a really good concept of "paper sheet size". A HTML page has an infinite height and browser's are notoriously bad a printing HTML in a readable way (with the notable exception of Opera).
With CSS 3, three page break properties were defined.
They might be supported by your browser. If they are, then wrap 24 bar codes in a <div> and give that <div> a class which tells the browser to break the page afterwards.
If the browser emits an empty page at the end, then you need two classes: One for the first <div> without a page break and one for every successive <div> and a page-break-before: always;
If that doesn't work well, you should look at PDF. PDF allows you place elements exactly on pages with a known, fixed size.