I have little problem using chart.js . I can see graphs on screen but when i use aggregation method then i cannot see tooltip and please guide me how can i use looping function with graph here is my
views.py
def get(self, request, format=None):
qs = Add.objects.all().aggregate(Sum('expense'))
a = qs.values()
print(a)
labels = ["budget", "Pink", "Yellow", "Green", "Purple", "Orange"]
default_items = [a, 10, 10, 10, 10, 10] # PROBLEM IS HERE
data = {
"newlabels": labels,
"newdata": default_items,
}
return Response(data)
template t
var endpoint = '/api/chart/data/'
var labels = []
var defaultData = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(i){
labels = i.newlabels
defaultData = i.newdata
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels, // CHANGED
datasets: [{
label: 'sum',
data: defaultData, // CHANGED
}]
}
})
},
A Sum aggregation over a queryset that isn't assigned to a custom name will just return a dictionary with the key <fieldname>__sum. So you can get the result of the aggregation using qs['expense__sum'].
Related
I am trying to make a django website which will display a chart that is updated every 1sec. I dont know why but except for the lines everything else is getting update a snapshot of the graph with the console log. the code below is my jquery in the html page
{% block jquery %}
<script>
var updateInterval = 20 //in ms
var numberElements = 5
var values = []
//Globals
var updateCount = 0
var endpoint = '/api/chart/data'
var ctx = document.getElementById('myChart');
var gchart = new Chart(ctx, {
type: 'line',
data: {
label: [],
datasets: [{
label: 'Wholesale 24 K',
data: [],
fill: true,
borderColor: 'rgb(245, 0, 0)',
tension: 0.1,
parsing: {
yAxisKey: 'b1'
}
}, {
label: 'Retail 24 K',
data: [],
fill: true,
borderColor: 'rgb(245, 225, 0)',
tension: 0.1,
parsing: {
yAxisKey: 's24K'
}
}]
}, options: {
interaction: {
mode: 'index',
}
},
})
function addData(chart, label, data) {
console.log(data)
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
if (updateCount > numberElements) {
gchart.data.labels.shift();
gchart.data.datasets[0].data.shift();
gchart.data.datasets[1].data.shift();
}
else updateCount++;
chart.update();
}
setInterval(ajaxcal, 1000)
function ajaxcal() {
$.ajax({
method: "GET",
url: endpoint,
success: function (data) {
var lal = data.time
addData(gchart, lal, data)
},
error: function (error_data) {
console.log(error_data)
console.log("Failed to fetch chart data from " + endpoint + "!")
},
})
}
</script>
and this is my apiview
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
g_dic = GetGoldRates()
now = datetime.datetime.now()
current_time = now.strftime("%H:%M:%S")
tg = {
'time': current_time,
'b1': float(g_dic['karat24']),
's24K': float(g_dic['fixkarat24']),
}
return Response(tg)
g_dic will usually get a dic like this {'api_rate': '1796.03', 'karat24': '17.501', 'karat22': '16.031', 'karat21': '15.313', 'karat18': '13.126', 'fixkarat24': '17.950', 'fixkarat22': '17.050', 'fixkarat21': '16.300', 'fixkarat18': '14.000'}
Could someone please help and point out my mistake
You are telling chart.js which custom key it needs to look for for the y axis but not for the x axis. So chart.js is looking for the x key in the object.
Changing your parsing config to include the xAxisKey: 'time' will fix your issue.
<script>
var updateInterval = 20 //in ms
var numberElements = 5
var values = []
//Globals
var updateCount = 0
var endpoint = '/api/chart/data'
var ctx = document.getElementById('myChart');
var gchart = new Chart(ctx, {
type: 'line',
data: {
label: [],
datasets: [{
label: 'Wholesale 24 K',
data: [],
fill: true,
borderColor: 'rgb(245, 0, 0)',
tension: 0.1,
parsing: {
yAxisKey: 'b1',
xAxisKey: 'time'
}
}, {
label: 'Retail 24 K',
data: [],
fill: true,
borderColor: 'rgb(245, 225, 0)',
tension: 0.1,
parsing: {
yAxisKey: 's24K',
xAxisKey: 'time'
}
}]
}, options: {
interaction: {
mode: 'index',
}
},
})
function addData(chart, label, data) {
console.log(data)
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
if (updateCount > numberElements) {
gchart.data.labels.shift();
gchart.data.datasets[0].data.shift();
gchart.data.datasets[1].data.shift();
}
else updateCount++;
chart.update();
}
setInterval(ajaxcal, 1000)
function ajaxcal() {
$.ajax({
method: "GET",
url: endpoint,
success: function (data) {
var lal = data.time
addData(gchart, lal, data)
},
error: function (error_data) {
console.log(error_data)
console.log("Failed to fetch chart data from " + endpoint + "!")
},
})
}
</script>
I cant figure out how to render a simple trend line in chartjs using datatime.datetime data from a mysql database.
I have polled two rows of a table I want to use to create a line graph in chartjs. Data in the form of temperature and datetime when the temperature was recorded.
When I look at the script it shows the temperature data is fine and can be used but the format the datetime row is in wont allow x-axis labels
Below is an example of the array retrieved from the database using a function in views.
[
datetime.datetime(2021, 3, 7, 18, 32, 5, tzinfo=<UTC>),
datetime.datetime(2021, 3, 7, 18, 32, 16, tzinfo=<UTC>)
],**
The error in the code
Uncaught SyntaxError: Unexpected token '<'
models.py
class Mqtt(models.Model):
createdat = models.DateTimeField(db_column='createdAt')
topic = models.CharField(max_length=255)
message = models.CharField(max_length=255, blank=True, null=True)
qos = models.IntegerField()
class Meta:
managed = False
db_table = 'mqtt'
views.py
def chart_red(request):
labels = []
data = []
chart_red_obj = Mqtt.objects.order_by('createdat')[:2]
for mqtt in chart_red_obj:
labels.append(mqtt.createdat)
data.append(mqtt.message)
return render(request, "chart_red.html", {
'labels':labels,
'data':data,
})
})
html and js
<canvas id="myChart"></canvas>
<script>
var temp = {
type: 'line',
data: {
datasets: [{
data: {{ data|safe }},
label: 'Trend'
}],
labels:{{ labels|safe }},
},
options: {
responsive: true
}
};
window.onload = function() {
var ctx = document.getElementById('myChart').getContext('2d');
window.myLine = new Chart(ctx, temp);
};
When I view the code in the developer tools it looks like below. No Chart
</script>
var config = {
type: 'line',
data: {
datasets: [{
data: ['65.3', '65.3'],
label: 'Trend'
}],
**labels:[datetime.datetime(2021, 3, 7, 18, 32, 5, tzinfo=<UTC>), datetime.datetime(2021, 3, 7, 18, 32, 16, tzinfo=<UTC>)],**
},
options: {
responsive: true
}
};
window.onload = function() {
var ctx = document.getElementById('myChart').getContext('2d');
window.myLine = new Chart(ctx, config);
};
I have the MatPlot lib solution for this trend so if the question is not clear don't worry, will do it the easy way and leave Chartjs to the professionals
How to show specific data on html page using chart.js and django i am trying this method i can see data api view but cannot see on chart. i am able to see data except my query set. Is there any doc for this. Please help me i am beginner in django,
Here is my Views.py
class secondapi(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
qs = Add.objects.all().aggregate(Sum('budget')) # here is problem
labels = ["sum", "Blue", "Yellow", "Green", "Purple", "Orange"]
default_items = [qs, 23, 2, 3, 12, 2]
data = {
"newlabels": labels,
"newdata": default_items,
}
return Response(data)
html page
<script>
var endpoint = '/api/chart/data/'
var labels = [] //
var defaultData = []; //
$.ajax({
method: "GET",
url: endpoint,
success: function(i){
labels = i.newlabels
defaultData = i.newdata
console.log(labels)
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels, // CHANGED
datasets: [{
label: '# of Votes',
data: defaultData, // CHANGED
}]
}
})
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
</script>
<div class='col-sm-6'>
<canvas id="myChart"></canvas>
</div>
</body>
</html>
def get(self, request, format=None):
qs = Add.objects.all().aggregate(Sum('expense'))
# some = list(qs.keys())
a = qs.values()
labels = ["sum", "Blue", "Yellow", "Green", "Purple", "Orange"]
default_items = [a, 23, 2, 3, 12, 2]
data = {
"newlabels": labels,
"newdata": default_items,
}
return Response(data)
I'm trying to plot a graph from the database by using axios endpoint to get the data. I suspect it has something to do with the format. As I can see still see the correct data when navigating to api/chart/data/.
I have two variables, one is working fine but another is undefined:
total_km and sorted_vehicle_list
so when I console.log(labels), it said "Error Cannot read property 'hidden' of undefined"
P.S. sorted_vehicle_list has one only instance and returns as a list [] (which I'm sure if it's the problem)
I have tried to print the output of the query in views.py and the output is correct. It returns the data that I want but somehow Chart.js can't see it.
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
all_vehicles = LoggerRecord.objects.values('imei').distinct()
vehicle_list = []
for vehicle in all_vehicles:
vehicle_list.append(vehicle['imei'])
sorted_vehicle_list = sorted(vehicle_list)
#create sum km
total_km = LoggerRecord.objects.aggregate(Sum('distance'))
print(total_km)
print(all_vehicles)
data = {
'all_vehicles': all_vehicles,
'total_km': total_km
}
return Response(data)
axios.get(endpoint)
.then(function (response) {
labels = response.data.sorted_vehicle_list
total_km = response.data.total_km
console.log(labels)
console.log(total_km)
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx2, {
// The type of chart we want to create
type: 'bar',
// The data for our dataset
data: {
labels: labels,
datasets: [{
label: 'Total KM',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: total_km
}]
}
//console.log(response);
})
I have a doughnut graph created using Chart.js with two datasets. The graph displays the number of employees in offices around the world, with the second dataset breaking this down into permanent and contract employees.
There's a jsfiddle of this running here: https://jsfiddle.net/tetsujin1979/tt3ch8z7/
The "labels" attribute of the options for the graph contains the names of the offices, but since there is only one array of labels, they are repeated for the second dataset, and appear on the mouseover text for it.
var config = {
type: 'doughnut',
data: {
datasets: [
{
data: [124,231,152,613,523],
backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue],
label: 'Offices'
},
{
data: [60,64,100,131,71,81,337,276,405,118],
backgroundColor: [chartColors.purple, chartColors.grey],
label: 'Permanent/Contract'
}
],
labels: ['London', 'New York', 'Paris', 'Moscow', 'Mumbai']
}
};
var ctx = document.getElementById('employees-graph').getContext('2d');
var employeesGraph = new Chart(ctx, config);
Is it possible to specify a second array of labels for the permanent/contract dataset so the hover text displays the values from this second
Add a labels array to both of the datasets
var config = {
type: 'doughnut',
data: {
datasets: [
{
data: [124,231,152,613,523],
backgroundColor: [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue],
label: 'Offices',
labels: ['London', 'New York', 'Paris', 'Moscow', 'Mumbai']
},
{
data: [60,64,100,131,71,81,337,276,405,118],
backgroundColor: [chartColors.purple, chartColors.grey],
label: 'Permanent/Contract',
labels: ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
}
]
}
};
And add the following to the options:
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var index = tooltipItem.index;
return dataset.labels[index] + ": " + dataset.data[index];
}
}
}
}