How could I pass data to chart.js with flask? - javascript

I recently trying to make dashboard which datas from mongodb with flask. But I cannot send datas to chart.js. I got the data from mongodb and send to javascript and try to loop data with jinja2.
#app.route("/dashboard")
def dashboard():
limit = request.args.get("limit",12,type=int)
dashboardDatas = mongo.db.dashBoard
dashDatas = dashboardDatas.find().limit(limit)
return render_template("dashboard.html", dashDatas = dashDatas)
<canvas id="myChart" height="50"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [ {% for item in dashDatas %}
'{{item._id}}',
{% endfor %} ],
datasets: [{
label: '# of Votes',
data: [ {% for item in dashDatas %}
{{item.logistic}},
{% endfor %}],
borderColor: [
'rgba(255, 99, 132, 1)',
],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
],
borderWidth: 0.5
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
And I got empty chart. What did I do wrong?

My approach is to store the labels and data in lists in the Flask view, pass them to the template and transform them to JSON with the tojson filter.
Suppose you have labels = ['a', 'b', 'c'] and data = [1, 2, 3] in your view. You can pass them to Chart.js in your template as
let chart = new Chart(ctx, {
type: 'line',
data: {
labels: {{ labels|tojson }},
datasets: [{
label: 'My 1st dataset',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: {{ data|tojson }}
}]
});

Version (library) 1 of chartjs has important differences to version 2 in terms of usability. Fine references are:
. version 1: https://blog.ruanbekker.com/blog/2017/12/14/graphing-pretty-charts-with-python-flask-and-chartjs/
. version 2: https://towardsdatascience.com/flask-and-chart-js-tutorial-i-d33e05fba845

Related

Chart.js display no data message using django

I have a pie chart that I want to display no data message when there is no data to be shown I have tried the methods here but it seems to stop displaying the chart all together even when there is data. currently if there is no data it shows NAN% the data it based off the user data from a model. I have also tried to just use the if statement for the part displaying the Nan% but the if statement also just seems to cause it to stop rendering the chart.
JS:
<script>
{% block jquery %}
var endpoint = '/api/chart1'
var defaultData = []
var labels = []
$.ajax({
methode: "GET",
url: endpoint,
success: function(data){
labels = data.labels
defaultData = data.default
setChart1()
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
function setChart1(){
var ctx = document.getElementById('myChart').getContext('2d');
Chart.register(ChartDataLabels);
var myChart = new Chart(ctx, {
type: 'pie',
plugins: [ChartDataLabels],
data: {
labels: labels,
datasets: [{
label: '',
data: defaultData,
backgroundColor: [
'rgba(255, 51, 51, 0.2)',
'rgba(255, 255, 0, 0.2)',
'rgba(0, 204, 204, 0.2)',
],
borderColor: [
'rgba(255, 51, 51, 1)',
'rgba(204, 204, 0, 1)',
'rgba(0, 204, 204, 1)',
],
borderWidth: 1
}]
},
options: {
plugins: {
tooltip: {
enabled: false
},
datalabels: {
anchor: 'center',
align: 'center',
formatter: (value, ctx) => {
let sum = 0;
let dataArr = ctx.chart.data.datasets[0].data;
dataArr.map(data => {
sum += data;
});
let percentage = (value*100 / sum).toFixed(2)+"%";
return percentage;
},
color: '#000',
}
}
}
});
}
{% endblock %}
</script>
HTML:
<div class="card bg-light mb-4">
<div class="card-header">
Assigned Tickets-By Priority
</div>
<div class="card-body">
<canvas id="myChart" width="400" height="400" ></canvas>
</div>
</div>
View:
def get_chart1(request):
highTickets = Issue.objects.filter(Q(priority='High') & Q(assigned_users=request.user)).count()
lowTickets = Issue.objects.filter(Q(priority='Low') & Q(assigned_users=request.user)).count()
medTickets = Issue.objects.filter(Q(priority='Medium') & Q(assigned_users=request.user)).count()
labels = ['High', 'Med', 'Low']
default = [highTickets, medTickets, lowTickets]
data = {
'labels': labels,
'default': default,
}
return JsonResponse(data)

Input data in german data format combined with ChartsJs

I'm relative new to Charts.js, but I'll need it to create some nice graphs for my webpage. In the background I have a Django project running which computes me a certain amount of numbers. Since I've put the language code in Django to "de-at" (requirement, since there are some input variables to fill in by austrian users), the number formats are done like: "1.000.000,54€" and not the US-way like "1,000,000.54€".
If I now want to add some of my data into charts.js, it won't read the data, which has more than 6 digits. Furthermore, if there is a number like "653.598,36" it takes actually two parameters, namely (653,598 ; 36).
Formatting the numbers in python does not help, since charts.js won't use strings for the graphs. Using the setting "locale = 'de-DE'" in the charts.js options only helps for labelling propertes, not for the data itself.
If I change the Django setting back to "en-us", charts.js works with the numbers, but than my numbers on the webpage are not formatted correctly for the end-user.
Has someone experienced this problem and has a solution to it?
Thank you and best regards!
Here is the code of charts.js with example values. I used chart.js directly in a HTML-file.
Note: The numbers in the data-section are just examples. Usually, there is a variable in it, which has the value.
<canvas id="testChart" width="200" height="100"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
<script>
var ctx = document.getElementById('testChart').getContext('2d');
var testChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['+', '-'],
datasets: [{
label: 'Years 1 - 20',
data: [ 568.987,68, 0],
backgroundColor: [
'rgba(54, 162, 235, 0.2)'
],
borderColor: [
'rgba(54, 162, 235, 0.2)'
],
borderWidth: 1
}, {
label: 'Einnahmen nach 20',
data: [ 1.265.986,32 , 0],
backgroundColor: [
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 0.2)'
],
borderWidth: 1
},{
label: 'EK',
data: [0, 120.000,00],
backgroundColor: [
'rgba(200, 50, 132, 0.2)'
],
borderColor: [
'rgba(200, 50, 132, 0.2)'
],
borderWidth: 1
}, {
label: 'FK',
data: [0, 480.000,00],
backgroundColor: [
'rgba(150, 20, 132, 0.2)'
],
borderColor: [
'rgba(150, 20, 132, 0.2)'
],
borderWidth: 1
}
]
},
options: {
plugins: {
title: {
display: true,
text: 'Testgrafik'
},
},
locale: 'de-DE',
responsive: true,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
});
</script>
Before inserting the numbers in that library, do this:
EDIT2: I misread your question, I thought you were asking how to change the floating point integers formats.
let n = "653.598,36";
let result = "";
let decimalPart = n.split(",")[1];
let decimalPartLen = decimalPart.length;
n = n.replace(".",""); //parseFloat doesn't like commas
let commaIndex = n.length - decimalPartLen;
result = parseFloat(n.substr(0,commaIndex - 1)+"."+n.substr(commaIndex, n.length));
console.log(result);
EDIT: this is client side js, but you could do this in python with minimal changes
Here it is in python:
n = "653.598,36"
result = ""
decimalPart = n.split(",")[1]
decimalPartLen = len(decimalPart)
n = n.replace(".","")
commaIndex = len(n) - decimalPartLen
result = float(n[:commaIndex-1]+"."+n[commaIndex:])
print(result)

chart.js mix chart (bar + line): get lines to start at x = 0

I am trying to plot a chart with two bars and two lines. the issue is that the lines wont go start at 0.
I have tried to artificially create points on the x axis to make them go all the way but it won't do the trick. Here is what my code look like for the graph:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: document.getElementById('tag1').textContent == 'ITEM TIME SUPPLY ANALYSIS'? ["Desired time supply","Actual time Supply"] :[ 'jours de stock désirés','jours de stock actuel'] ,
datasets: [{
label: document.getElementById('tag1').textContent == 'ITEM TIME SUPPLY ANALYSIS'? "limit max time supply (days)": "limite max jours de stock désirés",
data: [
{
x: 0,
y: [{% for dr in reference %} {{ dr.cap_ts }}, {% endfor %}]
},
{
x: 30,
y: [{% for dr in reference %} {{ dr.cap_ts }}, {% endfor %}]
},
{
x: 60,
y: [{% for dr in reference %} {{ dr.cap_ts }}, {% endfor %}]
},
{
x: 90,
y: [{% for dr in reference %} {{ dr.cap_ts }}, {% endfor %}]
},
],
type: 'line',
backgroundColor: [
'rgba(0, 0, 0, 0)',
],
borderColor: [
'rgba(54, 162, 235, 1)',
],
borderWidth: 5
}, {
label: document.getElementById('tag1').textContent == 'ITEM TIME SUPPLY ANALYSIS'? "limit min time supply (days)": "limite min jours de stock désirés",
data: [
{
x: 0,
y: [{% for dr in reference %}{{ dr.min_ts}}, {% endfor %}]
},
{
x: 30,
y: [{% for dr in reference %}{{ dr.min_ts}}, {% endfor %}]
},
{
x: 60,
y: [{% for dr in reference %}{{ dr.min_ts}}, {% endfor %}]
},
{
x: 90,
y: [{% for dr in reference %}{{ dr.min_ts}}, {% endfor %}]
},
],
type: 'line',
backgroundColor: [
'rgba(0, 0, 0, 0)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
],
borderWidth: 3
}, {
data: [
{x:30,
y: {% for dr in reference %}{{ dr.dts}}, {% endfor %}
},
{ x: 60,
y: {% for dr in reference %}{{ dr.actual_ts}}, {% endfor %}
},
],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
scaleShowLabels: false,
type: 'linear',
position: 'bottom',
xAxes: [{
maxBarThickness: 90,
ticks: {
beginAtZero: true,
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
}
}
})
At this point I don't know what to try, I can't find much on chart.js documentation and I am new to javascript, any help would be very appreciated on this
This is happening because chart.js sets the offset property in the x scale to true for bar charts so the bar is in the middle of the grid instead of on the gridLine as is with line charts.
You can set the offset to false but then the first and last bar will look weird because they are half of the width.
Live example:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'red',
borderColor: 'red'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
type: 'bar',
backgroundColor: 'blue'
}
]
},
options: {
scales: {
x: {
offset: false
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.js"></script>
</body>

How to create float charts with chartjs?

I tried creating float charts with chartjs but it does not seem to work. I tried copying the same example as they have http://pravopys.net/chartjs/samples/charts/bar/vertical.html but mine does not render at all or throw any errors.
var myBarChart = new Chart(document.getElementById("bar-chart"), {
type: 'bar',
data: {
labels: ['January', 'February', 'March'],
datasets: [
{
label: "Population (millions)",
data: [
[-2, 5],
[-20, 70],
[30, 80]
],
backgroundColor: "rgba(75, 192, 192, 0.2)",
borderColor: "rgba(75, 192, 192, 1)",
borderWidth: 1,
fill: false,
lineTension: 0,
type: "bar"
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
}
}
});
Not sure what I'm doing wrong here. The example shows the data structure for the dataset being used exactly how I'm using it.
Any help is greatly appreciated.
Plunker link: http://www.plnkr.co/edit/bD1MgVvjuq7B4RM5Qcmh?p=preview
You need a 2d context to draw the chart on. Here's a working example:
Do these 2 changes in your code:
HTML
<canvas id="bar-chart" width="400" height="400"></canvas>
Javascript
var ctx = document.getElementById("bar-chart").getContext("2d");
var myBarChart = new Chart(ctx, ...)
Source: https://www.chartjs.org/docs/latest/#creating-a-chart

Chart.js showing nothing on canvas

I'm trying to create a graphic in my .html file in the altervista ftp.
Here's my code:
<canvas id="myChart" width="400" height="200"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js" />
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
...
],
borderColor: [
'rgba(255,99,132,1)',
...
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
Why I'm getting nothing in canvas?
Also the console does not show errors.
You should remove the ... under backgroundColor and borderColor or add colors according to the number of labels.
You need to call myChart.update() after initializing the chart.
I solved my error editing the first script from this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js" />
to this:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.js" ></script>
as suggested by #j.ian.le
And adding
responsive: false,
under options: {

Categories

Resources