Chart JS Manual Bar Chart YAxis - chart.js

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>

Related

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 %}
]
}

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

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 %}

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.

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.

Displaying a Google Chart Using Django

I have generated a variable data in Django with the following format:
data = [['100',10],['90',9],['80',8]]
and I've passed it off to my template using render_to_response:
return render_to_response('template.html', {
'data': data,
},
context_instance=RequestContext(request))
In the template header I have placed a call to Google Charts to generate a line chart:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Number');
data.addColumn('number', 'Number/10');
data.addRows( {{ data }} );
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240, title: "Numbers"});
}
</script>
When I do this, nothing is displayed. If I strip the strings out of data and try again, the chart appears, but obviously with no x-axis labels.
I have also tried adding the data using the arrayToDataTable function:
var data = google.visualization.arrayToDataTable([
['Number', 'Number/10'],
{% for datum in data %}
{{ datum }},
{% endfor %}],
false);
but this again fails to display any chart.
Any suggestions on how I can change one of the above, or try another approach to get the x-axis labels to appear?
You have to disable the autoescaping of your results. You can do so by adding the safe filter:
data.addRows( {{ data|safe }} );
or
{% autoescape off %}
[...]
{{ data }}
[...]
{% endautoescape %}
My advice is, if you can install additional packages, to use one of these wrappers:
http://code.google.com/p/google-chartwrapper/
https://github.com/jacobian/django-googlecharts/
I can't add more than two links yet but another one is located here: code.google.com/p/django-graphs/