Chart.js是一个很酷的开源JavaScript库,可帮助您呈现精美的HTML5图表。它可以自动适应屏幕大小,并且可以统计8种不同的图表类型。在本教程中,我们将探讨如何使Django与Chart.js对话以及如何基于从我们的模型中提取的数据来呈现一些简单的图表。

9a21b1624a05e8f2a571ff3a306925d1.png

安装

对于本教程,您要做的就是将Chart.js库添加到HTML页面:

您可以从Chart.js官方网站下载并在本地使用它,也可以通过CDN使用它。

示例场景

我将使用与本教程如何使用Django ORM创建按查询分组的示例相同的示例,它是对本教程的很好补充,因为实际上处理图表的棘手部分是如何转换数据以便使其适合条形图/折线图等。

我们将使用以下两种模型,Country以及City:

class Country(models.Model):    name = models.CharField(max_length=30)class City(models.Model):    name = models.CharField(max_length=30)    country = models.ForeignKey(Country, on_delete=models.CASCADE)    population = models.PositiveIntegerField()

并将原始数据存储在数据库中:

城市
ID名称country_id人口
1东京2836,923,000
2上海1334,000,000
3雅加达1930,000,000
4汉城2125,514,000
5广州1325,000,000
6北京1324,900,000
7卡拉奇2224,300,000
8深圳1323,300,000
9新德里2521,753,486
10墨西哥城2421,339,781
11拉各斯921,000,000
12圣保罗120,935,204
13孟买2520,748,395
14纽约市2020,092,883
15大阪2819,342,000
16武汉市1319,000,000
17成都市1318,100,000
18达卡417,151,925
19重庆市1317,000,000
20天津1315,400,000
21加尔各答2514,617,882
国家
ID名称
1巴西
2土耳其
3意大利
4孟加拉国
5加拿大
6法国
7秘鲁
8阿根廷
9奈及利亚
10澳大利亚
11伊朗
12新加坡
13中国
14智利
15泰国
16德国
17西班牙
18菲律宾
19印度尼西亚
20美国
21南韩
22巴基斯坦
23安哥拉
24墨西哥
25印度
26英国
27哥伦比亚
28日本
29台湾

示例1:饼图

对于第一个示例,我们仅要检索人口最多的前5个城市,并将其以饼图形式呈现。在这种策略中,

我们将返回图表数据作为视图上下文的一部分,并使用Django模板语言将结果注入JavaScript

代码中。

views.py

from django.shortcuts import renderfrom mysite.core.models import Citydef pie_chart(request):    labels = []    data = []    queryset = City.objects.order_by('-population')[:5]    for city in queryset:        labels.append(city.name)        data.append(city.population)    return render(request, 'pie_chart.html', {        'labels': labels,        'data': data,    })

基本上在上面的视图中,我们遍历Cityqueryset并构建的列表labels和 data。在这种情况下,这里dataCity模型中保存的人口计数。

对于urls.py一个简单的路由:

urls.py

from django.urls import pathfrom mysite.core import viewsurlpatterns = [    path('pie-chart/', views.pie_chart, name='pie-chart'),]

现在是模板。我从Chart.js饼图文档中获得了一个基本片段。

pie_chart.html

{% extends 'base.html' %}{% block content %}          var config = {      type: 'pie',      data: {        datasets: [{          data: {{ data|safe }},          backgroundColor: [            '#696969', '#808080', '#A9A9A9', '#C0C0C0', '#D3D3D3'          ],          label: 'Population'        }],        labels: {{ labels|safe }}      },      options: {        responsive: true      }    };    window.onload = function() {      var ctx = document.getElementById('pie-chart').getContext('2d');      window.myPie = new Chart(ctx, config);    };{% endblock %}

在上面的示例中,base.html模板并不重要,但是您可以在本文结尾处共享的代码示例中看到它。这种策略不是理想的,但是效果很好。不好的是,我们正在使用Django模板语言来干扰JavaScript逻辑。当我们放置时,我们直接在JavaScript代码中注入来自服务器的变量,如{{ data|safe}}

上面的代码展示效果如下所示:

cc762d0502304097feebf194f1a8d591.png

示例2:使用Ajax的条形图

如标题所示,我们现在将使用异步调用来绘制条形图。

views.py

from django.shortcuts import renderfrom django.db.models import Sumfrom django.http import JsonResponsefrom mysite.core.models import Citydef home(request):    return render(request, 'home.html')def population_chart(request):    labels = []    data = []    queryset = City.objects.values('country__name').annotate(country_population=Sum('population')).order_by('-country_population')    for entry in queryset:        labels.append(entry['country__name'])        data.append(entry['country_population'])    return JsonResponse(data={        'labels': labels,        'data': data,    })

因此,这里我们使用两个视图函数。该home视图将是加载图表的主页。另一个视图population_chart将是唯一负责提供数据的视图,返回带有标签和数据的JSON格式响应数据。如果您想知道此查询集在做什么,它将按国家对城市进行分组,并汇总每个国家的总人口。结果将是国家/地区总人口列表。要了解有关这种查询的更多信息,请查看:Django基础(24): aggregate和annotate方法使用详解与示例

urls.py

from django.urls import pathfrom mysite.core import viewsurlpatterns = [    path('', views.home, name='home'),    path('population-chart/', views.population_chart, name='population-chart'),]

home.html

{% extends 'base.html' %}{% block content %}            $(function () {      var $populationChart = $("#population-chart");      $.ajax({        url: $populationChart.data("url"),        success: function (data) {          var ctx = $populationChart[0].getContext("2d");          new Chart(ctx, {            type: 'bar',            data: {              labels: data.labels,              datasets: [{                label: 'Population',                backgroundColor: 'blue',                data: data.data              }]                      },            options: {              responsive: true,              legend: {                position: 'top',              },              title: {                display: true,                text: 'Population Bar Chart'              }            }          });        }      });    });{% endblock %}

现在我们前端和后端有了更好的分离,可以先查看下图表容器:

我们添加了获取数据的data-url。稍后,我们将使用它来执行Ajax调用。

var $populationChart = $("#population-chart");$.ajax({  url: $populationChart.data("url"),  success: function (data) {    // 生成bar图标实例,展示data。  }});

success以后,在回调内部,我们最终使用JsonResponse数据执行与Chart.js相关的代码, 展示效果如下图所示:

1035beb16b48670a6d42951c1b074e44.png

小结

我希望本教程可以帮助您开始使用Chart.js处理图表。不久前,我使用Highcharts库发布了

关于同一主题的另一篇教程。方法大致相同:如何将Highcharts.js与Django集成。

如果您想获取本教程中使用的代码,可以在这里找到:

github.com/sibtc/django-chartjs-example。

大江狗翻译整理,原作Vitor Freitas

原文地址:

https://simpleisbetterthancomplex.com/tutorial/2020/01/19/how-to-use-chart-js-with-django.html

相关阅读

Django 3.0实战: 仿链家二手房信息查询网(附GitHub源码)

Django实战:Django 3.0 +Redis 3.4 +Celery 4.4异步生成静态HTML文件

Django实战: 利用自定义模板标签实现仿CSDN博客月度归档

dfc430bb123f7fe72e492d7475a0fa78.png

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐