前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Web | Django 与 Chart.js 联用做出精美的图表

Web | Django 与 Chart.js 联用做出精美的图表

作者头像
咸鱼学Python
发布2020-11-05 12:35:17
5.4K0
发布2020-11-05 12:35:17
举报
文章被收录于专栏:咸鱼学Python咸鱼学Python

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

安装

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

代码语言:javascript
复制
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
代码语言:javascript
复制
您可以从Chart.js官方网站下载并在本地使用它,也可以通过CDN使用它。

示例场景

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

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

代码语言:javascript
复制
代码语言:javascript
复制
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()
代码语言:javascript
复制


并将原始数据存储在数据库中:
城市ID名称country_id人口1东京2836,923,0002上海1334,000,0003雅加达1930,000,0004汉城2125,514,0005广州1325,000,0006北京1324,900,0007卡拉奇2224,300,0008深圳1323,300,0009新德里2521,753,48610墨西哥城2421,339,78111拉各斯921,000,00012圣保罗120,935,20413孟买2520,748,39514纽约市2020,092,88315大阪2819,342,00016武汉市1319,000,00017成都市1318,100,00018达卡417,151,92519重庆市1317,000,00020天津1315,400,00021加尔各答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 render
from mysite.core.models import City

def 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。在这种情况下,这里data是City模型中保存的人口计数。

对于urls.py一个简单的路由:
urls.py
from django.urls import path
from mysite.core import views
urlpatterns = [
    path('pie-chart/', views.pie_chart, name='pie-chart'),
]
现在是模板。我从Chart.js饼图文档中获得了一个基本片段。
pie_chart.html
{% extends 'base.html' %}
{% block content %}
  <div id="container" style="width: 75%;">
    <canvas id="pie-chart"></canvas>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script>
  <script>
    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);
    };
</script>
{% endblock %}


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

示例2:使用Ajax的条形图 如标题所示,我们现在将使用异步调用来绘制条形图。 views.py from django.shortcuts import render from django.db.models import Sum from django.http import JsonResponse from mysite.core.models import City def 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 path from mysite.core import views urlpatterns = [ path('', views.home, name='home'), path('population-chart/', views.population_chart, name='population-chart'), ] home.html {% extends 'base.html' %} {% block content %} <div id="container" style="width: 75%;"> <canvas id="population-chart" data-url="{% url 'population-chart' %}"></canvas> </div> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js"></script> <script> $(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' } } }); } }); }); </script> {% endblock %} 现在我们前端和后端有了更好的分离,可以先查看下图表容器: <canvas id="population-chart" data-url="{% url 'population-chart' %}"></canvas> 我们添加了获取数据的data-url。稍后,我们将使用它来执行Ajax调用。 var $populationChart = $("#population-chart"); $.ajax({ url: $populationChart.data("url"), success: function (data) { // 生成bar图标实例,展示data。 } }); success以后,在回调内部,我们最终使用JsonResponse数据执行与Chart.js相关的代码, 展示效果如下图所示:

小结 我希望本教程可以帮助您开始使用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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 咸鱼学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装
  • 示例场景
相关产品与服务
内容分发网络 CDN
内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档