How to query data in order to show in chart - django

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)

Related

Unable to see the lines in chart.js

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>

Chartjs wont render a graph from datetime.datetime code requested from mysql database in Django using views.py

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 select time on my chart js graph on Django?

I'm trying to do a selection on what only will be displayed on my chart, but I don't know what it's called hehe. please help
my views.py look like this.
class ResView(LoginRequiredMixin, ListView):
model = Rainfall
template_name = 'home.html'
context_object_name = 'res'
paginate_by = 8
queryset = Rainfall.objects.all().order_by('-id')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["qs"] = Rainfall.objects.all()
return context
my chart look like this.
<script>
(function () {
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [{% for i in qs %}'{{i.timestamp}}',{% endfor %}],
datasets: [{
label: 'Rainfall Graph',
data: [{% for i in qs %}'{{i.amount}}',{% endfor %}],
lineTension: 0,
backgroundColor: 'transparent',
borderColor: '#c9c5c5',
borderWidth: 2,
pointRadius: 1,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
display: false
}
}
})
}());
Now I want to select what to display on my chart. something like a dropdown like this. That I have an option.
<select>
<option value="hour">Hour</option>
<option value="day">Day</option>
<option value="month">Month</option>
</select>

Cannot view tooltip data using chart.js

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'].

How to fix "Error Cannot read property 'hidden' of undefined" when trying to plot Chart.js from views.py

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);
})