I'm having a little trouble implementing a webpage that uses AJAX to update the bokeh plot embedded within an html page.
See below specific file where I'm trying to implement it:
https://github.com/hhprogram/PyramidSite/blob/master/webgraphing/views/ajaxView.py
You should be able to just clone the whole webgraphing repo to your machine to run the pyramid webpage locally. You can then run the pyramid serve using pserve deveopment.ini and then navigate to 'localhost:6543/bokehAJAX' in your browser. Looking at the javascript console it seems to be embedding the bokeh div in my html except the div has width of zero.
The ultimate goal is there should be a bokeh line graph figure on the page that periodically updates and adds data to the line graph. I'm not really too sure what I'm doing wrong here - any push in the right direction would be much appreciated. Note: I've tried looking at examples like: Flask + Bokeh AjaxDataSource but to no avail.
Problem was in my python code ajaxView.py file in the bokeh_ajax method, i was missing:
from bokeh.resources import INLINE
...
jsResources = INLINE.render_js()
...
return {..., 'jsResources': jsResources}
Then in my html / jinja2 template needed to add:
<head>
...
{{ jsResources | safe }}
...
</head>
Hope this helps someone else!
Related
I would like to achieve the following:
pass a variable from my python script to a HTML page
get the browser to display the updated information
DO NOT re-render, or reload the WHOLE HTML page as this would take too long (new data will be transmitted from the python script to the HTML page every 250ms or so.)
data is generated live by the python script and so the solution have to take this into account
After researching the whole day and watching numerous tutorials, I understood that Flask or Django could be used to achieve this via a concept called "templating". Unfortunately I am complete beginner and I got lost in the details without seeing the "big picture" of what is need to be done...
So I ended up here, hoping someone can clear up my understanding about the topic without assuming any previous knowledge...
So I have a super simple HTML file as below:
<!DOCTYPE html>
<html>
<head>
<title>Simple Test</title>
</head>
<body>
<h1>Changing Number:</h1>
<h1 id="number">0</h1>
and I also have a python script:
import random
import time
for i in range(10):
myvar = random.randint(1, 10)
time.sleep(1)
The goal is to pass myvar to the html element with the id, "number" and have the browser display the new value without reloading the page.
Just to be clear I do not expect a comprehensive in-depth tutorial as I know that it would take too long to create, (if possible at all...), but instead I would like to get the "birds eye view", or the "big picture" on what I need to do.
Here is my current understanding (which is most likely incorrect):
I have to have a python file containing the script that calculates the
value to be passed. (I use VSCode on a windows based system to edit
this file)
I have to import Flask into this python file (if nothing better is
recommended) as this is the framework with the capacity to create
the "link" in between the python script and the HTML page
so:
python script calculates desired value ---> hands the value to flask ---> flask hands the value to the HTML document ---> browser renders the document
...but how does the process repeated when a new value is calculated by the python script?
How do I instruct the browser to re-render only the desired part of the web-page?
Is there a simpler way, or better framework that could do that task?
Am I looking in the right direction to solve the problem or should approach the problem from a different angle?
Many thanks in advance!
I don't think that's possible without using js. On a request, django renders the html and sends it back to the browser, so you gotta reload the page.
My goal is to generate an interactive html file from plotly fig and embed this html in my website. I was previously using fig.write_html('name.html'), but in the generated HTML, there are some unwanted symbols like ampersands &&.
Now, I tried adding cdn like fig.write_html('name.html', include_plotlyjs="cdn"), which solves the && problem but I have some questions about this:
On using cdn, is my data still secured/private, and can there be some possible complications on embedding this html to my website?
Is there any better/alternate way of removing the && symbols/cleaning the initial html file generated by plotly?
TIA
The include_plotlyjs="cdn" parameter causes a script tag to be included in the HTML output that references the Plotly CDN ("content delivery network"). This offloads the work of providing the necessary javascript from your server to a more scalable one. A browser will typically cache this making subsequent page loads faster.
Your data security/privacy is not affected by this option.
If the unwanted text you refer to is part of the Plotly JavaScript, it must be loaded however this solution will keep it from appearing in your HTML.
See the documentation for to_html for more information.
I was going through the library NVD3 and have found this as an example on the website:
d3.json('cumulativeLineData.json', function(data) {
nv.addGraph(function() {
var chart = nv.models.cumulativeLineChart()
.x(function(d) { return d[0] })
.y(function(d) { return d[1]/100 }) //adjusting, 100% is 1.00, not 100 as it is in the data
.color(d3.scale.category10().range())
.useInteractiveGuideline(true)
;
chart.xAxis
.tickValues([1078030800000,1122782400000,1167541200000,1251691200000])
.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d))
});
chart.yAxis
.tickFormat(d3.format(',.1%'));
d3.select('#chart svg')
.datum(data)
.call(chart);
//TODO: Figure out a good way to do this automatically
nv.utils.windowResize(chart.update);
return chart;
});
});
The image is something like this:
Check the live demo here: http://nvd3.org/examples/cumulativeLine.html
The json file is here: Json file for example
Now I was willing to include such charts in the django example. So I went on checking the implementation of Django-NVD3. But I could not find anything related to it and the documentation written by author is not understood by me.
Please let me know how I can include d3 chart in the django frame in real time.
Django largely is backend framework for python. That means it creates responses to html requests. These responses are rendered using templates that contain the html code which is being created on the fly.
nvd3.js or d3.js for that matter live on the frontend, i.e. the user's browser. That means all nvd3.js html and javascript code (like the one you quote) go into the Django template.
To use nvd3.js you will have to load the d3.js and nvd3.js javascript libraries and corresponding style sheets. (On how to do this, see the respective documentations.) These elements need to go to a different place in the template (html where the chart is supposed to go, css into the header and javascript at the end of the body).
django-nvd3 is a django app that is used to simplify the use of nvd3 on the front end. It is one option to work with Django and nvd3.js. It defines template tags that will include the required javascript code and style sheets in your template. The first tag include_chart_jscss will do exactly this and is supposed to be used in the <head> section of the tempalte. The second tag load_chartwill generate the javascript you quoted actually creating the chart. The third tag (include_container) will insert the required html div elements (which you did not quote in the questions). By passing the latter tags the same name the browser knows on which div tag to apply the javascript code. It does not help to distribute the code bits over the template. Also, it does not generate the code. This is left to a different package python-nvd3 which itself relies on a template engine (Jinja2) which likely is different from the one you use with Django. In a nutshell: django-nvd3 solves the problem of generating javascript code for nvd3 charts but not the problem of how to distribute that code in django templates.
I suggest Sekizai to better distribute code bits. It allows to split html, css and js bits of a page in separate blocks. Then you can use simple includes to add a chart to your web page. In the included file you may surround the required css code by {% addtoblock css %} and the required
javascript by {% addtoblock js %}. When using sekizai the base templates need to have these block ("js" and "css") defined, see the Sekizai documentation.
Of course it is a matter of opinion, but I prefer using sekizai for distributing the nvd3.js code bits in the template and making charts available as includable templates to Django (thereby refraining from the costs of a second template engine). My include templates contain the raw nvd3 code taken, e.g. from one of the examples.
I have compiled three gists which assume you have sekizai installed and included in your INSTALLED_APPS settings:
Python code for the view function. Remember to include the view function in urls.py. The code assumes that the file with the json data is in a static folder.
A template called base.html which does include the html code of the page to be rendered. It has a title and then includes the chart.
A template for the chart which is a 1:1 copy of the code in the question except that some parameters are dynamically loaded (source file, ticks).
I plotted a bunch of things in a dash layout. I want to save them to an html file so I can look at them later. when I reopen the saved html file, I first see everything correctly. However, within <1s, the page goes blank and I get an error: “Error loading layout”. (see gif below)
How can this be fixed?
Thanks!
This solution is not fully working:
You have to save your Webpage complete.
To prevent the javascript creating any errors
i have removed the bundle(2).js file.
This file contains the function dash_renderer which tries to interact with the server and creates issues.
<footer>
<script id="_dash-config" type="application/json">{"url_base_pathname": "/", "requests_pathname_prefix": "/"}</script>
<script src="./Dash_files/react.min.js"></script>
<script src="./Dash_files/react-dom.min.js"></script>
<script src="./Dash_files/bundle.js"></script>
<script src="./Dash_files/plotly-1.38.0.min.js"></script>
<script src="./Dash_files/bundle(1).js"></script>
<!-- <script src="./Dash_files/bundle(2).js"> --></script>
</footer>
The result is the same page as you can see for ~1s.
Big disadvantage: The interactivity from plotly is lost.
A Dash app layout is serialized as JSON and served to the front-end by the Dash server (an extension of a Flask server).
All Dash components included in your layout are bundled as JS/CSS files. These bundles are also served by the Dash server to the front-end.
Without the server, there is no one to send JSON, JS, CSS bundles to the front-end, so nothing will be rendered.
I'm not sure why you can see your app for a brief moment. My guess is that Dash saves a PNG image of your app every time you run it. Think of it like a splash screen you see before the real, reactive app shows up.
Have a look at this high-level overview on how Dash works under the hood.
Here's the python code:
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values))
However, I'd like to load index.html starting at the anchor tag below:
(wherein this anchor tag is in the index.html file)
<section> id="home">
How would i change the python code to do this?
As you can tell, I'm new, and currently working through the Google App Engine tutorials.
Thanks for your help!
I think that you are a bit confused. With jinja2 and Python code all you can achieve is to produce the page server-side. If you want to jump into a specific section within that page you should do that client-side by using JavaScript (example).
Let's supose you want acces your page at /yourpage and on home section. You could do this with a redirect:
YourHandler(RequestHandler):
def get(self):
self.redirect("/yourpage#home")
So you need to put the section id just after the "#" sign.
It worked for me at least on Google Chrome.