Multiple chart on one page using chart.js and Flask app - flask

I am trying to get multiple charts on one web page with different value. I can get two charts, but displays same data. Can someone please help me what i am missing?
Below is App.py where I am reading data from csv file.
temp.csv
Month,Temperature,Temp
January,7,10
February,7,30
March,10,5
April,15,25
May,20,20
June,23,15
July,26,20
App.py
from flask import Flask, render_template, url_for, redirect, request
import pandas as pd
app = Flask(__name__)
#app.route('/')
def index():
df = pd.read_csv('temp.csv')
legend = 'Monthly Data'
legend1 = "Test"
labels = list(df.Month)
values = list(df.Temperature)
values1 = list(df.Temp)
return render_template('index.html', values=values, labels=labels,
legend=legend,values1=values1, legend1=legend1)
if __name__ == "__main__":
app.run(debug=True)
Below is my index. html. I am trying to call values from App.py file.
index.html
{% extends 'base.html' %}
{%block head %}
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<title>My Chart.js Chart</title>
{% endblock %}
{% block body %}
<h1>Burn Page</h1>
<div class="container">
<canvas id="myChart" width="400" height="200"></canvas>
</div>
<div class="container">
<canvas id="myChart2" width="400" height="200"></canvas>
</div>
<script>
Chart.defaults.global.responsive = false;
var chartData = {
labels : [{% for item in labels %}
"{{item}}",
{% endfor %}],
datasets : [{
label: '{{ legend }}',
fill: true,
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data : [{% for item in values %}
{{item}},
{% endfor %}],
spanGaps: false
}]
}
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: chartData,
});
Chart.defaults.global.responsive = false;
var chartData2 = {
labels : [{% for item in labels %}
"{{item}}",
{% endfor %}],
datasets : [{
label: '{{ legend1 }}',
ill: true,
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data : [{% for item in values1 %}
{{item}},
{% endfor %}],
spanGaps: false
}]
}
var ctx2 = document.getElementById("myChart2").getContext("2d");
var myChart2 = new Chart(ctx2, {
type: 'line',
data: chartData,
});
</script>
{% endblock %}

I finally figured it out. For second chart i was calling first chart function. Changed that and it is all working now.
It should be "chartData2 and not chartData toward the end of my html (java script) code
data: chartData2,
});
</script>
{% endblock %}

Related

Error when creating a radar chart with chart.js version 4.2.1

Problem with Chart.js version > 4
With the following scriptversion radar charts are working https://cdn.jsdelivr.net/npm/chart.js
the version 4.2.1 gives an error with radar charts.
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.1/chart.js"> error in chart.js line 7 (unexpected token "{". ... -->
I don't find a working example for Chartjs > 4.0
``
`<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chart.js Radar Chart</title>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> --> <!-- works -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.1/chart.js"></script> <!-- doesn't work -->
<!-- error in chart.js line 7 (unespected token "{". ... -->
<script>
const ctx = document.getElementById('myChart');
new Chart(ctx, {
type: 'radar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: 'Whatever 1',
data: [12, 19, 23, 5, 32, 3],
borderWidth: 1
}, {
label: 'Whatever 2',
data: [12, 1, 22, 15, 2, 23],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>
</body>
</html>``
You are using the esm version, you need to use the footing link: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.1/chart.umd.js

Django chart.js multi axis line chart

Hi Guys I have inspired from this Fiddle example to try to create a similar multi axis line chart in my django project.
I have in my views :
class dashboard(TemplateView):
template_name = 'users/dashboard.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['qs'] = DummyData.objects.all()
data = DummyData.objects.all()
years=[]
for i in range(data.count()) :
if data[i].year not in years :
years.append(data[i].year)
context['years'] = years
return context
in in my dashboard.html :
{% extends 'users/base.html' %} {% load static %} {% block content %}
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- semantic UI -->
<link rel="stylesheet" type='text/css' href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.14/semantic.min.css">
<!--Chart js-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" integrity="sha256-Uv9BNBucvCPipKQ2NS9wYpJmi8DTOEfTA/nH2aoJALw=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" integrity="sha256-aa0xaJgmK/X74WM224KMQeNQC2xYKwlAt08oZqjeF0E=" crossorigin="anonymous" />
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function (){
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [{% for year in years %} '{{year}}', {% endfor %}],
datasets: [{% for item in qs %}
{
label: '{{item.site}}',
yAxisID: '{{item.site}}',
data: [100, 96, 84, 76, 69] , {% endfor %}
]
},
options: {
scales: {
yAxes: [{
id: 'A',
type: 'linear',
position: 'left',
}, {
id: 'B',
type: 'linear',
position: 'right',
ticks: {
max: 1,
min: 0
}
}]
}
}
});
});
</script>
<canvas id="myChart" width="400" height="100"></canvas>
{% endblock content %}
When I copied the fiddle example it showed correctly in my dahsboard.html as follows :
But When I tried to change the datasets in the code as presented in my dashboard.html nothing shows up, labels are updated okay but this is what makes my chart not work :
datasets: [{% for item in qs %}
{
label: '{{item.site}}',
yAxisID: '{{item.site}}',
data: {{item.turn_over}}' , {% endfor %}
]
I am sure this is not how it is supposed to be done, I'm a beginner at chart.js , what I want to do is load how many sites I have in my Dummydata table and show their turn over
Thank you
Done It was a comma positioning mistake, I checked the console and the problem was that when my if condition was not being checked instead of skipping, it was adding an empty value, meaning that I was getting for example 1, , , , 2 , , , 3 instead of 1,2,3 and the chart was rendering the empty cells, anyway here is the how I was able to fix it for data :
data: {
labels: [{% for year in years %} '{{year}}', {% endfor %}],
datasets: [
{% for site in sites %}
{
label: '{{site.site}}',
yAxisID: 'y',
borderColor: '{{site.color}}',
backgroundColor: 'transparent',
data: [ {% for item in qs %}
{% if item.site == site.site %}
{{item.turn_over}} ,{% endif %} {% endfor %}
]
}, {% endfor %}
]
}

Data not displaying in django admin - using chart.js (no errors)

I have created a changelist_view for displaying a chart.js visual in the Django admin.
I am not getting any errors, the chart outline is visible, but the data is not. Not sure what I'm missing. Info below:
admin.py model:
class MachineFaultAdmin(admin.ModelAdmin):
readonly_fields = [
'event_id',
'fault_type_id',
'position',
]
list_display = [
'event_id',
'fault_type_id',
'position',
]
def changelist_view(self, request, extra_context=None):
# Aggregate Faults
chart_data = (
MachineFault.objects.all()
.values('position')
.annotate(total=Count('fault_type_id'))
.order_by('total')
.filter(position__gte=10)
)
#Serialize and attach the chart data to the template context
as_json = json.dumps(list(chart_data), cls=DjangoJSONEncoder)
extra_context = extra_context or {"chart_data": as_json}
#Call the superclass changelist_view to render the page
return super().changelist_view(request, extra_context=extra_context)
def has_add_permission(self, request):
# Nobody is allowed to add
return False
def has_delete_permission(self, request, obj=None):
# nobody is allowed to delete
return False
# suit_classes = 'suit-tab suit-tab-faults'
empty_value_display = ''
list_filter = ('fault_type',)
search_fields = ('position',)
changelist_view html (admin override file)
<!--# machines/templates/admin/machines/machinefault/change_list.html-->
{% extends "admin/change_list.html" %}
{% load static %}
<!-- Override extrahead to add Chart.js -->
{% block extrahead %}
{{ block.super }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const ctx = document.getElementById('myChart').getContext('2d');
// Sample data
const chartData = {{ chart_data | safe }};
// Parse the dates to JS
chartData.forEach((d) => {
d.x = new Date(d.date);
});
// Render the chart
const chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [
{
label: 'Breaks ',
data: chartData,
backgroundColor: 'rgba(220,20,20,0.5)',
},
],
},
options: {
responsive: true,
scales: {
xAxes: [
{
type: 'time',
time: {
unit: 'day',
round: 'day',
displayFormats: {
day: 'MMM D',
},
},
},
],
yAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
});
</script>
{% endblock %}
{% block content %}
<!-- Render our chart -->
<div style="width: 80%;">
<canvas style="margin-bottom: 5px; width: 50%; height: 15%;" id="myChart"></canvas>
</div>
<button id="reload" style="margin: 1rem 0">Reload chart data</button>
<!-- Render the rest of the ChangeList view -->
{{ block.super }}
{% endblock %}
But my chart is still blank - I have no errors.
Using latest Django, Python3.7
UPDATE: 2/14/2020
Can't be sure that this is the cause of your issue without seeing the HTML, but the way you are passing data to your chart JS is unsafe - don't do this:
const chartData = {{ chart_data | safe }};
It's very likely you are ending up with invalid JS as a result of this, because the output is not properly escaped. Instead, use the json_script filter to safely render your object, and then read this in JS. Something like this:
{{ chart_data|json_script:"chart-data" }}
<script>
const chartData = JSON.parse(document.getElementById("chart-data").textContent);
// initialise the chart as you currently do
</script>
Note - you need to stop encoding the data as JSON in your view - just pass it the original list which this filter will encode safely for you.
If this doesn't fix it then it's likely that the data structure itself is not what the chart library is expecting - perhaps if you post a sample of what chartData looks like we can see whether that looks right.

Chart JS Manual Bar Chart YAxis

I am working on a project that will use ratings from 1-10. The automatic scaling in ChartJs is causing issues where data is not displayed due to it not being in range.
How can I remove the automatic scaling of a bar chart yxais and manually set the scales to 1-10 ?
<canvas id="bar-chart-grouped" width="800" height="350"></canvas>
<script>
new Chart(document.getElementById("bar-chart-grouped"), {
type: 'bar',
data: {
labels: [{% for result in results %}
"{{result.title}}",
{% endfor %}],
datasets: [
{
label: "Rating",
backgroundColor: "#3e95cd",
data: [{% for result in results %}
"{{result.w_average}}",
{% endfor %}]
}, {
label: "My Rating",
backgroundColor: "#3cba9f",
data: [{% for result in results %}
"{{result.rating}}",
{% endfor %}]
}
]
},
options: {
title: {
display: true,
text: 'Movie Ratings'
}
}
});
</script>

something wrong in presenting highcharts using django

I was stuck in passing dict's data to highchart using django
here's my views.py code. My thought is trying to pass the database's data to dictionary data , then pass its to user_chart.html's highchairs
def user_chart(request):
user_data = User_Data.objects.filter(user=request.user.username)
data = {'words':[], 'click_times':[]}
for i in user_data:
data['words'].append(i.word)
data['click_times'].append(i.click_times)
xAxis = {"title": {"text": 'ss'}, 'categories': data['words']}
yAxis = {"title": {'text': 'fdfd'}}
series = [
{"name": 'dfdf', "data": data['click_times']}
]
content = {'xAxis': xAxis, 'yAxis': yAxis, 'series': series}
return render(request, 'yigu/user_chart.html', content)
user_chart.html's code. I want to achieve a goal that highchart receives the data then present its as chart.
{% extends 'yigu/base_charts.html' %}
{% block body_block %}
<div class="container">
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-1"></div>
<div class="col-md-1"></div>
<div class="col-md-1">
<div id="chart1" style="width:450px">
</div>
</div>
<div class="col-md-4"></div>
</div>
</div>
<script>
var xAxis = {{ xAxis|safe }}
var yAxis = {{ yAxis|safe }}
var series = {{ series|safe }}
</script>
<script>
$(document).ready(function(){
$("#chart1").highcharts({
chart: {
type: 'column'
},
title: {
text: '搜索频率'
},
xAxis: xAxis,
yAxis: yAxis,
series: series
});
});
</script>
{% endblock %}
But i just got the blank response, the chart didn't show up. Anyone could give me a hand?
After reading http://blogs.law.harvard.edu/rprasad/2011/08/30/highcharts-django-admin/ I noticed categories: [ '{{ categories|join:"','" }}'] And i thought that maybe i should try this type. Then i change my template into something like below
<script>
$(document).ready(function(){
$("#chart1").highcharts({
chart: {
type: 'column'
},
title: {
text: '搜索频率'
},
xAxis: {
title:{
text: '词条',
},
categories: [ '{{ data.words|join:"','"}}']
},
yAxis: {
title:{
text: '次数'
}
},
series:[{
name:'搜索次数',
data:[{{ data.click_times|join:"," }}]
}]
});
});
</script>
Then everything went right. I was so surprised. I hope the solution would help someone.