I'm trying to build a webpage with a chart in it. For the chart i'm using Chartjs.
Hardcoded data is no problem for the Chartjs chart. But if I'm trying to pass dynamic data the chart doesn't render.
The labels and results output is 46 (the dataframe is 46 rows with 1 column)
View.py
def results(request):
return render(request, 'results.html')
def result(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
data = request.FILES['file']
# handle_uploaded_file(data)
data = pd.read_csv(data,header=0, sep=',')
df = data.values
df2 = pd.DataFrame(df.reshape(-1,len(data.columns)))
x = getPredictions(df2)
x = np.array(x)
result = x.reshape(-1,1).round()
df = pd.DataFrame(data=result, columns=['output'])
labels = len(df)
# result = list(result)
return render(request, 'results.html', {'result': result, 'labels': labels})
else:
form = UploadFileForm()
return render(request, 'index.html', {'form': form})
html page
{% extends "base.html" %}
{% block content %}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="content">
<div class="row">
<div class="col-sm-8">
<div class="card card-tasks">
<h4>Chart.</h4>
<canvas id="line-chart" width="500" height="350"></canvas>
<script>
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: {labels|safe},
datasets: [{
data: {result|safe},
label: "output chart",
borderColor: "#3e95cd",
fill: false
}
]
},
options: {
title: {
display: true,
text: 'output chart'
}
}
});
</script>
</div>
</div>
</div>
</div>
{% endblock content %}
For the variables to show up, in your template, you have to wrap them inside two curly braces: {{ }}, you are using only one.
Modify your chart code as follows:
{% extends "base.html" %}
{% block content %}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="content">
<div class="row">
<div class="col-sm-8">
<div class="card card-tasks">
<h4>Chart.</h4>
<canvas id="line-chart" width="500" height="350"></canvas>
<script>
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: {{ labels |safe }},
datasets: [{
data: {{ result|safe }},
label: "output chart",
borderColor: "#3e95cd",
fill: false
}
]
},
options: {
title: {
display: true,
text: 'output chart'
}
}
});
</script>
</div>
</div>
</div>
</div>
{% endblock content %}
Thanks Amir for helping with the sugestion.
I had to update the scripts from chartjs. that made it work
had to put "{}" around the data and labels
Related
I have a django application that displays a few charts generated using plotly.
This is my views.py file
def home(request):
const_list = pd.read_csv('./const.csv').Const.unique()
party_list = pd.read_csv('./part_list.csv').abbr.unique()
all_list = pd.read_csv('./all_list.csv').All.unique()
chked=request.POST.get('chk', '')
print(chked)
if chked == 'true':
part_bargraph = main_graph(all_list, len(const_list))
else:
part_bargraph = main_graph(part_list, len(const_list))
context = {'main_graph': part_bargraph, 'const': const_list}
print(context)
return render(request, 'home.html', context)
The main_graph is a function that takes a list and an int value as parameters and generates a plotly graph. This graph is then returned as a json object using the plotly.io.to_json method.
I want to display this graph in an HTML template. This is what I am doing right now
<form method='post'>
{% csrf_token %}
<div class="switch">
<input id='chk' type="checkbox" class="switch-input" />
<label for="chk" class="switch-label">Switch</label>
</div>
</form>
<div class="main_graph" id='main_graph'></div>
<script>
Plotly.newPlot("main_graph", {{ main_graph | safe }})
$(document).on('click', '#chk', function (e) {
$.ajax({
type: 'POST',
url: '/home',
data: {
chk: $('#chk').prop('checked'),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
},
success: function (data) {
Plotly.newPlot("main_graph", {{ main_graph | safe }})
}
});
})
</script>
When I print the context after toggling the button, I can see that the graph has changed. But I am not able to display that in the template.
What am I doing wrong?
Thanks in advance
I have this search engine in django that when you look for let's say "release date" only displays one result with that date, but not all the available results with it. I was wondering how I can manage that, so that if I look for something that has more than one result, it will show all of them and not a random unique result.
This is the search function in my view:
def films(request):
movies = []
if request.method == 'POST':
film_url = 'https://ghibliapi.herokuapp.com/films/'
search_params = {
'films' : 'title',
'films' : 'description',
'films' : 'director',
'films' : 'release_date',
'q' : request.POST['search']
}
r = requests.get(film_url, params=search_params)
results = r.json()
if len(results):
for result in results:
movie_data = {
'Title' : result['title'],
'Release_date': result['release_date'],
'Director' : result['director'],
'Producer' : result['producer'],
'Description' : result['description']
}
movies.append(movie_data)
else:
message = print('No results found')
context = {
'movies' : movies
}
return render(request,'core/films.html', context)
This is my html:
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>Ghibli Studio | Movies</title>
<link rel="stylesheet" href="{% static 'core/films.css' %}">
</head>
<body>
<div class="layer">
<div class=" header">
</div>
<div class="wrap">
<form action='/films' method="POST">
{% csrf_token %}
<div class="search">
<input type="text" name="search" class="searchTerm" placeholder=" Type movie name">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<button type="submit" class="searchButton">
<i class="fa fa-search" style="font-size:24px"></i>
</button>
</div>
</form>
</div>
{% if movies %}
{% for movie in movies %}
<div>
<ul class="result">
<style>
#import url('https://fonts.googleapis.com/css2?family=Dosis:wght#300&display=swap');
</style>
<h4>{{movie.Title}}</h4>
<h5 style="color:lightslategray;">
Release date: {{movie.Release_date}} <br>
Director: {{movie.Director}}
<br>Producer: {{movie.Producer}}
<br>
<br>{{movie.Description}}
</h5>
</ul>
{% endfor %}
{% endif %}
</div>
</div>
</body>
</html>
I am using django to create a webpage and this is the first time I am doing so. I am trying to fetch the value of a variable from .py file at an interval of 5 seconds. Below is the HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Like Post App</title>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<div class = "display-3 color-red"><center>DataFlair AJAX Tutorial<br>Post APP</center></div>
{% for post in posts %}
<div class = 'container jumbotron'>
<h3 class="display-5">{{ forloop.counter }}. {{ post.post_heading }}</h3>
<p class="lead">{{ post.post_text }} </p>
<p>
<div type="text/css" class = "container">Author : {{ post.post_author }}</div>
<a class="likebutton btn btn-primary btn-lg" id="like{{ post.id }}" data-catid="{{ post.id }}">Like({{ post.like_ref.counter }})</a> </p> <p id="message{{post.id}}">
</p>
</div>
{% endfor %}
<script type="text/javascript">
setInterval(function() {
getvalue(); // Do something every 5 seconds
}, 5000);
getvalue();
function getvalue(){
var id;
id = $(this).attr("data-catid");
$.ajax(
{
type:"GET",
url: "like",
data:{
post_id: id
},
success: function( data )
{
$( '#like'+ id ).text("Like(" + data +")");
var i=parseInt(data);
console.log("Value= "+i);
}
}
)
}
</script>
</body>
</html>
Below is the views.py code:
import json
from django.shortcuts import render
from .models import Post, Like
from django.http import HttpResponse
# Create your views here.
#DataFlair #AJAX_tutorial
def index(request):
posts = Post.objects.all()
return render(request, 'post/index.html', { 'posts': posts })
def like(request):
if request.method == 'GET':
post_id = request.GET['post_id']
likedpost = Post.objects.get(id = post_id )
m = Like.objects.filter( post=likedpost ).first()
m.counter +=1
m.save()
value1= int(m.counter)
#data1= {'cmd': 'success', 'ctr': str(m.counter) }
return HttpResponse(value1)
#return HttpResponse(json.dumps(data1))
else:
return HttpResponse("unsuccesful")
I keep getting the following errors:
1) GET http://localhost:8000/ajax/like/ 500 (Internal Server Error)
2) GET http://localhost:8000/favicon.ico 404 (Not Found)
Please help.
I believe:
id = $(this).attr("data-catid");
is not pointing to the button... maybe you should try:
id = $(".likebutton").attr("data-catid");
My code:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['FileName', 'Frequency'],
{% for l in list1 %}
[{{l.file_name}},{{l.frequency_count}}],
{% endfor %}
]);
var options = {
title: 'Search Performance',
hAxis: {title: 'FileName', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
On running my app (created in Django) on the server this chart is not getting displayed, why? This page is "results.html" which is directed from my views.py file. Here "list1" contains the data stored in the table namely "file_name" and "frequency_count". Why is this happening?
I'm new to Django, google-charts and JavaScript.
You may have a problem in the loop that prints the javacript array of values for the chart. I guess the filenames are strings, and as such they need to be delimited with ' or ", like this:
{% for l in list1 %}
['{{ l.file_name }}', {{ l.frequency_count }}],
{% endfor %}
To test this, I just got rid of the loop and put a couple of rows of sample static data, like this:
var data = google.visualization.arrayToDataTable([
['FileName', 'Frequency'],
['this', 100],
['that', 200]
]);
And I got the chart working:
I am trying to implement "Upload Progress Bar" in Django.
Following is my code in the template file:
{% extends "index_base.html" %}
{% block content %}
<script src="/media/js/functions.js" type="text/javascript"></script>
<script src="/media/js/jquery.js" type="text/javascript"> </script>
<script type="text/javascript">
var xhrObject1;
var xhrObject2;
function createXMLHttpObject()
{
var xhrObject; // The variable that makes Ajax possible!
try
{
xhrObject = new XMLHttpRequest();
}
catch (e)
{
try{
xhrObject = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e){
try {
xhrObject = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
xhrObject = null;
}
}
}
return xhrObject;
}
function ajaxFunction()
{
xhrObject1 = createXMLHttpObject();
if (xhrObject1 == null)
{
alert("Your browser does not support ajax.");
return;
}
xhrObject1.onreadystatechange = function(){
if(xhrObject1.readyState == 4){
document.getElementById("targetDiv").innerHTML = xhrObject1.responseText;
}
else
{
xhrObject2 = createXMLHttpObject();
xhrObject2.onreadystatechange = function(){
if(xhrObject2.readyState == 4){
document.getElementById("targetDiv").innerHTML = xhrObject2.responseText;
}
else
{
document.getElementById("targetDiv").innerHTML = "getting progress...";
}
}
xhrObject2.open("GET", "/upload_progress.psp", true);
xhrObject2.send(null);
}
}
var arrFiles = document.getElementById('id_file');
var fileToUpload = arrFiles.files[0];
xhrObject1.open("POST", "/upload.psp/", true);
xhrObject1.send(fileToUpload);
}
function submitForm()
{
document.forms["myform"].submit();
ajaxFunction();
return false;
}
</script>
<div id="main_container">
{% include "includes/nav.html" %}
<!------- Main Contents ---------->
<div id="contents_holder">
<div id="contents">
<div id="c_banner">
<span class="main_title">Upload File</span>
</div>
<div id="targetDiv" > </div>
<div id="setting">
<form name="myform" id="myform" action="/upload.psp/" method="post" enctype="multipart/form-data">
<h2>Upload File</h2></br>
<p>{{ form.file.label_tag }} {{ form.file }}</p></br>
<input type="button" value="Upload" name="uploadButton" onclick="javascript:return submitForm();"/>
<input type="button" value="Cancel" name="cancelUploadButton" onclick ="cancelUploadClicked()"/>
<input type="hidden" value="title" name="title" id="title" />
</form>
</div>
</div>
</div>
</div>
{% endblock %}
Following are my two functions inside views.py:
#condition(etag_func=None)
def upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
#handle_uploaded_file(request.FILES['file'])
f = request.FILES['file']
filename = "/host_lighttpd/var/www/htdocs/satellite/static/Data/" + f.name
destination = open(filename, 'wb+')
for chunk in f.chunks():
destination.write(chunk)
#yield chunk
request.session['uploaded'] += chunk
destination.close()
return render_to_response('uploadsuccess.html')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
def upload_progress(request):
#uploaded = request.session['uploaded']
return HttpResponse("Upload progress function...")
#return HttpResponse(uploaded)
My problem is how can I return the upload status back to the
second ajax call (GET method), so that it can be eventually updated
inside the html.
I don't know how can I return the ongoing uploading status.
Any help would be appreciated. Thanks in advance.
I recently had to do a bit of digging to find a solution for this myself.
Check out :-
http://fairviewcomputing.com/blog/2008/10/21/ajax-upload-progress-bars-jquery-django-nginx/
I have not tried the solution referenced yet, but it looks reasonable enough.
It involves registering a custom file upload class to expose the upload progress information.