to employ charts(written in python using matplolib) in html file - python

I have created app using django which searches the keywords entered by the user in 10 xml documents and maintains the frequency count of those words for each file. The results are returned to the user in the form of expandable hyperlinked list of filenames and the charts. My html code:
<html>
<style type="text/css">
h1 {
position: absolute;
top: 5px;
left: 200px;
}
form #Edit1 {
position: absolute;
top: 37px;
left: 410px;
}
form #Edit2 {
position: absolute;
top: 37px;
left: 840px;
}
</style>
<font size="4" face="arial" color="#0000FF">
<h1>XML Search</h1>
</font>
<br/>
<br/>
<Form Action ="/search/" Method ="POST">
<div id="Edit1">
<INPUT TYPE = 'VARCHAR' name ='word' VALUE ="" size = "50">
</div>
<div id="Edit2">
<INPUT TYPE = "Submit" VALUE = "Search">
</div>
<br/>
<hr/>
{% csrf_token %}
</FORM>
{% if list1 %}
<input type="text" name="word" value="{{ word }}" />
<ul>
{% for l in list1 %}
<li>{{l.file_name}}, {{l.frequency_count}}</li>
{% endfor %}
</ul>
<br/>
# -- charts to be employed -- #
{% endif %}
</html>
this html page is redirected from views.py file. Now, I want to write the code for charts using matplotlib in this html code. As the code to create charts using the mentioned library is written in python, so how can I write this python code in the above html file or if there is any other way out, so please tell?
Note:
I have made use of google charts and that are working perfectly fine but I want to make this app internet independent, so please do not suggest me google charts.
Please Help , I'm new to charts and django.

The matplotlib cookbook has an entry on using matplotlib with django.
It boils down to the following:
In urls.py you add an entry for a png with a link to a new view.
In your new view you create a HttpResponse with content_type image/png
Using matplotlib you write a figure as png to the aforementioned HttpResponse
A straight copy/paste from the cookbook should get you going.
Perhaps you can break the problem into bite size pieces to avoid learning three things at once:
Add a static .png to your page
Add a dynamic .png to your page via urls.py and a new view
Create a figure in Matplotlib (offline)
Put the matplotlib figure from step 3 into the dynamic image from step 2

Related

HTML & Python - For loops and dynamic forms creation

I am new working with HTML and Python, and I am trying to develop some code for personal use.
The goal is to show the different leagues with a color code: red or green, and if I click on a league, it opens a different tab with more detailes information of that league, that is to say, it would be necessary to send the id of the league to the server to be able to use it for the next tab. I am trying to use a form, but it is not working.
The if-else condition is just to choose whether the color is red or green based on a league condition.
The problem I am having is that, creating the form with the for loop as I am doing, the league id that sends is always the same (1st league of the lopp), it is not dynamic, then I would like to know how to program it to be able to see the chosen league.
No matter on what league you click, you always access the same league information. I guess there is something wrong with the code because it is not dynamic, it does not display info based on my selection.
My idea was to have multiple forms created with the loop, one for each league, but it doesnt work.
I would really appreciate your help, thank you very much!
This is the HTML code:
competicionesAPIDict is a dict where the key is the country and the values the different leagues that exists in it.
competicionesAPI is the value obtained from the dict, that is iterated to get the info from each league.
<div style="width: 80%; height: 70%; background-color: azure; width: max-content">
{% for paisAPI, competicionesAPI in competicionesAPIDict.items() %}
<div class="div_pais">
<h4>{{paisAPI}} </h4>
<img src={{dict_banderas_pais[paisAPI]}} alt="No funciona" width="30px" height="30px"/>
{% for competicionAPI in competicionesAPI %}
{% if dict_hay_competicion[competicionAPI['id']] %}
<form name="siCompeticion"+{{competicionAPI['id']}} method="POST" action="/RAI/API/competicion">
<input type="hidden" name="id_competicion" value={{competicionAPI['id']}} />
<a href=/RAI/API/competicion style="font-size: 14px;margin-left: 17px;color: green;"
onclick="document.forms[0].submit();return false;">{{competicionAPI['name']}}</a>
</form>
{% else %}
<form name="noCompeticion"+{{competicionAPI['id']}} method="POST" action="/RAI/API/competicion">
<input type="hidden" name="id_competicion" value={{competicionAPI['id']}} />
<a href=/RAI/API/competicion style="font-size: 14px;margin-left: 17px;color: red;"
onclick="document.forms[0].submit();return false;">{{competicionAPI['name']}}</a>
</form>
{% endif %}
{% endfor %}
</div>
{% endfor %}
OK, I was wrong in a comment about hidden input field value being a problem.
I mean, it is still a problem, but it should work as is, except for JS code bug you made.
So first, what gave me wrong impression was that you would usually make one form per request, and then do as I said, set the forms values correctly to provide data of the request upon submit. You made a lot of forms, one per iteration, which is not wrong, but what you did is say in onclick event to activate always the first form on the site. I.e.
document.forms[0]
so, whatever you click, only first form will be submitted with the value of the first hidden input field in it.
As you have if-else clauses, I wouldn't rely on form indexes within the DOM, but use something to create unique IDs per each form, then use document.getElementById() to get that exact form and submit it. But you already gave your forms names, so you can use those with document.getElementsByName() or give the form an ID of same value.
Names does not need to be unique, IDs should.
Just a little sample:
<form id="siCompeticion"+{{competicionAPI['id']}} ...>
<input type="hidden" name="something" value={{competicionAPI['id']}}>
CLICK ME
</form>
In your place I would most probably write a little JS code to perform AJAX request, most likely using jquery. In any case, I would avoid making a lot of forms.

How do I make an html div element follow vertical scrolling (in html/django)?

I'm extremely inexperienced with html and although I know python, I had never used django before this. I'm trying to set up a simple website where the user can view some code on the left side of the screen and enter some text about it on the right side of the screen. The code can be pretty long sometimes so the webpage scrolls, but I want the textbox to always be present even if you scroll up or down. As my code is now, the textbox is on the right side of the screen, but it always stays at the bottom. Here's a screenshot of what it looks like:
(can't seem to get screenshot to show up in the post, here's the link http://imgur.com/3JfgHH3)
Here's the .html file I'm using in my templates directory in django:
<div style="display: inline-block">
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<pre>{{ source_code }}<pre>
</div>
<div style ="display: inline-block" >
<form method="post" action="/labeling/{{ document_id }}/send/">
{% csrf_token %}
<input type="text" name="textfield">
<input type="submit" value="Finish" name="finish_btn" />
</form>
</div>
Sorry for my complete lack of html knowledge. How would I fix this either in django or in the html file directly so that the textbox and button move up and down with the scrolling, instead of being permanently attached to the bottom right of the screen? If necessary I can post the django code too, I just wasn't sure if this was possible directly in html.
<div style ="display: inline-block;position: fixed;" >
Implement position: fixed; into your styling of the first div. That should already do the trick. Like #furas said is - when it comes to styling - CSS the language you have to learn.
In the CSS file please add the following Code:
div.[class_name_of_div_element] {
position: fixed;
}

Python flask generator function not working with JQuery-mobile

I've been stuck with the following problem for a while, and i can't seem to get it to work on this Python flask web application i've been developing:
1) my flask view -> obtains image data from a local database and passes the data via a generator to a template
My flask route/view code:
#app.route(#app.route('/viewer',methods=['GET'])
def viewer():
archive = request.args.get('filepath')
arc = rarTools()
pagetotal = arc.pageTotal(archive)
def g():
for n in range(pagetotal):
data = arc.getPageb64(archive,n+1)
print(n+1)
yield data
return Response(stream_template('viewer.html',data=g()))
2) My HTML template with JQuery Mobile UI obtains this data and simply displays all the image data on 1 page
My HTML viewer.html with JQuery mobile UI:
<body style="background-color: black">
<div data-role="page" class="page" id="mainpage" data-theme="b">
<div data-role="main" class="ui-content">
<div id="frame" align="middle" style="width: 100%">
{% for page in data %}
<img id="page_img" src="data:image/png;base64,{{ page }}" width="80px" height="auto"/>
{% endfor %}
</div>
</div>
</div>
</body>
My HTML viewer.html WITHOUT JQuery mobile UI:
<body style="background-color: black">
<div id="frame" align="middle" style="width: 100%">
{% for page in data %}
<img id="page_img" src="data:image/png;base64,{{ page }}" width="80px" height="auto"/>
{% endfor %}
</div>
</body>
My problem is how long it takes to load pages when there are many images in my database. The load time is vastly different when I use JQuery Mobile and when I don't:
Because i'm using a generator to pass the data to the template, the images are loaded dynamically with the page loading immediately and each page appearing as the image data is generated on the flask back-end when I don't use JQuery Mobile to style the page.
When I use JQuery Mobile on the other hand, the page only loads once all the image data is passed even though i'm using a generator.
How can I get my JQuery Mobile template page to refresh after every yield, so that
The page loads immediately irrespective of image count?
The pages refreshes after each new image data "yield" so the the images are loaded dynamically? - like it works when I don't use JQuery Mobile?
I am aware that it has something to do with the - either: 'pageinit' or 'pageload' events with Jquery Mobile, but for the life of me, i can't seem to get the above code to work!!
Any assistance would be much appreciated, thanks in advance!

Printing dynamic django view template

I'm working on a django app. I have a page that displays a log of items, and each item has a "Print label" link. At the moment, clicking the link displays the label for that particular item in a popup screen, but does not send the label to a printer. The view function behind the "Print label" link is shown below:
#login_required
def print_label(request, id):
s = Item.objects.get(pk = id)
return render_to_response('templates/label.html', {'s': s}, context_instance=RequestContext(request))
The HTML for the label is shown below:
{% load humanize %}
<head>
<style type="text/css">
div{
min-width: 350px;
max-width: 350px;
text-align: center;
}
body{
font-family: Arial;
width: 370px;
height: 560px;
text-align: center;
}
</style>
</head>
<body>
<div id="labelHeader">
<img src="{{ STATIC_URL }}img/label-header.png" width="350px">
</div>
<hr/>
<p></p>
<div id="destinationAddress">
<span style="font-size: xx-large; font-weight: bold;">{{ s.item_number }}</span>
</p>
DESTINATION:
<br/>
<strong>{{s.full_name}}</strong><br/>
<strong>{{ s.address }}</strong><br/>
<strong>{{s.city}}, {{s.state}}</strong><br/>
<strong>Tel: {{s.telephone}}</strong>
</div>
<p></p>
<hr/>
<div id="labelfooter">
<img src="{{ STATIC_URL }}img/label-footer.png" width="350px">
</div>
</body>
My question is, how can I also send the label displayed to a printer in the same function? I researched and found some libraries (like xhtml2pdf, webkit2png, pdfcrowd, etc), but they'll create a pdf or image file of the label and I'll have to send it to a printer. Is it possible to send straight to a printer without creating a pdf copy of the label? If so, please show me how to achieve this.
Your answers and suggestions are highly welcome. Thank you.
Presumably, as this is a Django app, it's the client's printer that you need to use. The only way to do this is to tell the user's browser to print. You will need to use Javascript for this: window.print().

Display a ‘loading’ message while a time consuming function is executed in Flask

I’m still relatively new to Flask, and a bit of a web noob in general, but I’ve had some good results so far. Right now I’ve got a form in which users enter a query, which is given to a function that can take anywhere between 5 and 30 seconds to return a result (looking up data with the Freebase API).
The problem is that I can’t let the user know that their query is loading during this time, as the results page only loads once the function finishes its work. Is there a way I can display a loading message while that's going on? I found some Javascript that could display a loading message while page elements are still loading, but my waiting period happens before ‘render_template’.
I knocked together some example code, just to demonstrate my situation:
Python:
from flask import Flask
from flask import request
from flask import render_template
import time
app = Flask(__name__)
def long_load(typeback):
time.sleep(5) #just simulating the waiting period
return "You typed: %s" % typeback
#app.route('/')
def home():
return render_template("index.html")
#app.route('/', methods=['POST'])
def form(display=None):
query = request.form['anything']
outcome = long_load(query)
return render_template("done.html", display=outcome)
if __name__ == '__main__':
#app.debug = True
app.run()
Excerpt from index.html:
<body>
<h3>Type anything:</h3>
<p>
<form action="." method="POST">
<input type="text" name="anything" placeholder="Type anything here">
<input type="submit" name="anything_submit" value="Submit">
</form>
</p>
</body>
Excerpt from done.html:
<body>
<h3>Results:</h3>
<p>
{{ display }}
</p>
</body>
Any help would be greatly appreciated, I hope this example helps.
Add this to your index.html or js file (I'm assuming you have jQuery here, you could use standard javascript of course.):
<script type="text/javascript">// <![CDATA[
function loading(){
$("#loading").show();
$("#content").hide();
}
// ]]></script>
Add this to you html or css file:
div#loading {
width: 35px;
height: 35px;
display: none;
background: url(/static/loadingimage.gif) no-repeat;
cursor: wait;
}
You can get an adequate GIF from http://www.ajaxload.info/. Download and put it into your static folder.
Then change your submission button to call above js function:
<input type="submit" name="anything_submit" value="Submit" onclick="loading();">
and add in a loading and a content div to you base html file:
<body>
<div id="loading"></div>
<div id="content">
<h3>Type anything:</h3>
<p>
<form action="." method="POST">
<input type="text" name="anything" placeholder="Type anything here">
<input type="submit" name="anything_submit" value="Submit" onclick="loading();">
</form>
</p>
</div>
</body>
Now when you click 'Submit', the js function should hide your content and display a loading GIF. This will display until your data is processed and flask loads the new page.
This can be done by using a div that contains a 'loading gif' image. When the submit button is clicked, the div is displayed using javascript.
To implement this, you can take a look at this website: http://web.archive.org/web/20181023063601/http://www.netavatar.co.in/2011/05/31/how-to-show-a-loading-gif-image-while-a-page-loads-using-javascript-and-css/
I found the purely CSS-dependent loader very useful. It does not depend on external resources:
https://www.w3schools.com/howto/howto_css_loader.asp
This is a bit of an old topic, but I needed to deal with this problem today and came with a solution on my own. I'm running a machine learning model that recieves an image input from the user and does some magic.
Basically this is what I did.
On my index.html file, I called a loading function on my "Submit" button passing the filename, because I was going to use it later:
<form method="post" action="/loading/{{filename}}"
enctype="multipart/form-data">
<input type="submit" value="Submit!">
</form>
On Flask, I created a route just to render the loading screen before doing the time consuming task, also passing the filename ahead:
#app.route('/loading/<filename>', methods=['POST'])
def loading_model(filename):
return render_template ("loading.html", filename=filename)
And then, on loading.html, I render my .gif animation and at the end I redirect the page to the time consuming task function:
<!doctype html>
<head>
<link rel= "stylesheet" type= "text/css" href= "{{url_for('static',filename='styles/main.css') }}">
</head>
<div id="preloader">
<div id="status">&nbsp</div>
<h1 class="ml13">ANALYZING...</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js> </script>
</div>
<title>Title</title>
<script src="{{url_for('static', filename='main.js')}}"></script>
<script> window.location.replace('/task/{{filename}}'); </script>
And then, final step, back to Flask, call the task function:
#app.route('/task/<filename>', methods=['POST', 'GET'])
def task(filename):
# Do your stuff
return render_template ("results.html")
By doing this, the gif animation will keep playing whilst the function does its job, and then render the results or the next page you want.
You obviously have to edit the css file so that "preloader" and "status" behave like you wish, this is how I used it:
#preloader {
background-color: white;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#status {
background-image: url("lalala.gif");
background-repeat: no-repeat;
width: 800px;
height: 600px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -400px;
margin-left: -400px;
}
It worked out for me.
Brilliant #jka.ne but confusing situation.
I only needed to introduce the loading gif while a button was clicked.
My solution was:
<script type="text/javascript">
function loading(){
$("#loading").show();
window.location.href="../target_html";
}
</script>
Then:
<button type="button" class="xxx" onclick="loading();">Run</button>
Finally:
<div id="loading"></div>

Categories

Resources