当前位置:   article > 正文

Django动态展示Pyecharts图表数据_django 图表

django 图表

注意:

以下示例是pyecharts官网django示例中的例子,目前发现一处bug,示例3中的定时增量无法实现,我在下面代码中已经改好。

该动态展示的index.html模板中用的还是echarts渲染的,view.py视图下使用pyecharts生成json。index.html中的JavaScript去请求json数据,请求响应结果为success后通过setOption进行解析data字段下的数据绘制图表。

前置条件:

(1)python安装完成

(2)Django安装完成

(3)pyecharts安装完成

pip install pyecharts

 (4)APIView安装完成

pip install APIView

1. 新建一个 Django 项目

命令行中输入以下命令

django-admin startproject pyecharts_django_demo

创建一个应用程序

python manage.py startapp demo

效果如下:

创建完之后,在 Pycharm 中打开该项目,当然你也可以直接在 Pycharm 中创建

同时在pyecharts_django_demo/settings.py中注册应用程序INSTALLED_APPS中添加应用程序demo

  1. INSTALLED_APPS = [
  2. 'django.contrib.admin',
  3. 'django.contrib.auth',
  4. 'django.contrib.contenttypes',
  5. 'django.contrib.sessions',
  6. 'django.contrib.messages',
  7. 'django.contrib.staticfiles',
  8. 'demo',
  9. ]

pyecharts_django_demo/urls.py中新增demo.urls

  1. from django.contrib import admin
  2. from django.urls import path, include
  3. urlpatterns = [
  4. path('admin/', admin.site.urls),
  5. path('demo/', include('demo.urls')),
  6. ]

2. 新建项目 urls 文件

新建demo/urls.py文件

  1. from django.urls import path
  2. from . import views
  3. urlpatterns = [
  4. path('pie/', views.ChartView.as_view(), name='demoChart'),
  5. path('index/', views.IndexView.as_view(), name='demoIndex'),
  6. ]

3. 编写 Django 和 pyecharts 代码渲染图表

由于 json 数据类型的问题,无法将 pyecharts 中的 JSCode 类型的数据转换成 json 数据格式返回到前端页面中使用。

因此在使用前后端分离的情况下尽量避免使用 JSCode 进行画图。

将下列代码保存到demo/views.py

  1. import json
  2. from random import randrange
  3. from django.http import HttpResponse
  4. from rest_framework.views import APIView
  5. from pyecharts.charts import Bar, Pie
  6. from pyecharts.faker import Faker
  7. from pyecharts import options as opts
  8. # Create your views here.
  9. def response_as_json(data):
  10. json_str = json.dumps(data)
  11. response = HttpResponse(
  12. json_str,
  13. content_type="application/json",
  14. )
  15. response["Access-Control-Allow-Origin"] = "*"
  16. return response
  17. def json_response(data, code=200):
  18. data = {
  19. "code": code,
  20. "msg": "success",
  21. "data": data,
  22. }
  23. return response_as_json(data)
  24. def json_error(error_string="error", code=500, **kwargs):
  25. data = {
  26. "code": code,
  27. "msg": error_string,
  28. "data": {}
  29. }
  30. data.update(kwargs)
  31. return response_as_json(data)
  32. JsonResponse = json_response
  33. JsonError = json_error
  34. def pie_base() -> Pie:
  35. c = (
  36. Pie()
  37. .add("", [list(z) for z in zip(Faker.choose(), Faker.values())])
  38. .set_colors(["blue", "green", "yellow", "red", "pink", "orange", "purple"])
  39. .set_global_opts(title_opts=opts.TitleOpts(title="Pie-示例"))
  40. .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
  41. .dump_options_with_quotes()
  42. )
  43. return c
  44. class ChartView(APIView):
  45. def get(self, request, *args, **kwargs):
  46. return JsonResponse(json.loads(pie_base()))
  47. class IndexView(APIView):
  48. def get(self, request, *args, **kwargs):
  49. return HttpResponse(content=open("./templates/index.html").read())

 在根目录下新建一个templates的文件夹,并在该文件夹下新建一个index.html文件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Awesome-pyecharts</title>
  6. <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
  7. <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
  8. </head>
  9. <body>
  10. <div id="pie" style="width:1000px; height:600px;"></div>
  11. <script>
  12. var chart = echarts.init(document.getElementById('pie'), 'white', {renderer: 'canvas'});
  13. $(
  14. function () {
  15. fetchData(chart);
  16. }
  17. );
  18. function fetchData() {
  19. $.ajax({
  20. type: "GET",
  21. url: "http://127.0.0.1:8000/demo/pie",
  22. dataType: 'json',
  23. success: function (result) {
  24. chart.setOption(result.data);
  25. }
  26. });
  27. }
  28. </script>
  29. </body>
  30. </html>

 python manage.py runserver 127.0.0.1:8000 命令运行

发现报错 sqlite3.OperationalError: no such table: django_session

由于是第一次使用Django的session,所以必须要做以下的操作:

(1)进入cmd,通过cd命令进入到项目根目录下,即manage.py文件所在的文件夹。

(2)执行下面的命令:python manage.py migrate

把相关需要的给配置应用进去了,最后一个就是初始化Django的session,后面跑项目就没问题了。

再次运行,在浏览器中打开http://127.0.0.1:8000/demo/index/,效果如下:

 4. 定时全量更新图表

前面讲的是一个静态数据的展示的方法,用 Pyecharts 和 Django 结合最主要是实现一种动态更新数据,增量更新数据等功能。

定时全量更新主要是前端主动向后端进行数据刷新,定时刷新的核心在于 HTML 的 setInterval 方法。

新增index2.html代码如下:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Awesome-pyecharts</title>
  6. <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
  7. <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
  8. </head>
  9. <body>
  10. <div id="bar" style="width:1600px; height:800px;"></div>
  11. <script>
  12. var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
  13. $(
  14. function () {
  15. fetchData(chart);
  16. <!-- refresh time 1000ms-->
  17. setInterval(fetchData, 1000);
  18. }
  19. );
  20. function fetchData() {
  21. $.ajax({
  22. type: "GET",
  23. url: "http://127.0.0.1:8000/demo/bar",
  24. dataType: 'json',
  25. success: function (result) {
  26. chart.setOption(result.data);
  27. }
  28. });
  29. }
  30. </script>
  31. </body>
  32. </html>

同时在demo/views.py中,增加如下代码:

  1. def bar_base() -> Bar:
  2. c = (
  3. Bar()
  4. .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
  5. .add_yaxis("商家A", [randrange(20, 100) for _ in range(6)])
  6. .add_yaxis("商家B", [randrange(20, 100) for _ in range(6)])
  7. .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="这是副标题"))
  8. .dump_options_with_quotes()
  9. )
  10. return c
  11. class ChartView2(APIView):
  12. def get(self, request, *args, **kwargs):
  13. return JsonResponse(json.loads(bar_base()))
  14. class IndexView2(APIView):
  15. def get(self, request, *args, **kwargs):
  16. return HttpResponse(content=open("./templates/index2.html").read())

 demo/urls.py中,修改成如下代码:

  1. from django.urls import path
  2. from django.template.defaulttags import url
  3. from . import views
  4. urlpatterns = [
  5. path('pie/', views.ChartView.as_view(), name='demoChart'),
  6. path('index/', views.IndexView.as_view(), name='demoIndex'),
  7. path('bar/', views.ChartView2.as_view(), name='demoChart'),
  8. path('index2/', views.IndexView2.as_view(), name='demoIndex'),
  9. ]

运行之后,http://127.0.0.1:8000/demo/index2/效果如下:

Awesome-pyecharts

5. 定时增量更新图表

原理一样,新增index3.html ,代码如下(网上别的教程里这块代码有问题达不到增量更新的效果,我已经做了修改)

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Awesome-pyecharts</title>
  6. <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
  7. <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
  8. </head>
  9. <body>
  10. <div id="bar" style="width:1600px; height:800px;"></div>
  11. <script>
  12. var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
  13. var old_data = [];
  14. $(
  15. function () {
  16. fetchData(chart);
  17. setInterval(getDynamicData, 100);
  18. }
  19. );
  20. function fetchData() {
  21. $.ajax({
  22. type: "GET",
  23. url: "http://127.0.0.1:8000/demo/line",
  24. dataType: "json",
  25. success: function (result) {
  26. var options = result.data;
  27. chart.setOption(options);
  28. old_data = chart.getOption().series[0].data;
  29. }
  30. });
  31. }
  32. function getDynamicData() {
  33. $.ajax({
  34. type: "GET",
  35. url: "http://127.0.0.1:8000/demo/lineUpdate",
  36. dataType: 'json',
  37. success: function (result) {
  38. var options = result.data;
  39. old_data.push([options.name, options.value]);
  40. chart.setOption({
  41. series: [{
  42. data: old_data
  43. }]
  44. });
  45. }
  46. });
  47. }
  48. </script>
  49. </body>
  50. </html>

index3.html中新增了两个请求地址demo/line,demo/lineUpdate

所以在demo/urls.py中增加以下路径的匹配(网上别的教程里这块代码有问题达不到增量更新的效果,我已经做了修改)

  1. from django.urls import path
  2. from django.template.defaulttags import url
  3. from . import views
  4. urlpatterns = [
  5. path('pie/', views.ChartView.as_view(), name='demoChart'),
  6. path('index/', views.IndexView.as_view(), name='demoIndex'),
  7. path('bar/', views.ChartView2.as_view(), name='demoChart2'),
  8. path('index2/', views.IndexView2.as_view(), name='demoIndex2'),
  9. path('line/', views.ChartLineView.as_view(), name='demoLine'),
  10. path('lineUpdate/', views.ChartLineUpdateView.as_view(), name='demoLineUpdate'),
  11. path('index3/', views.IndexView3.as_view(), name='demoIndex3'),
  12. ]

 最后在views.py中导入Line:

from pyecharts.charts import Bar, Pie, Line

并在views.py中增加以下代码(网上别的教程里这块代码有问题达不到增量更新的效果,我已经做了修改)

  1. cnt = 0
  2. def line_base() -> Line:
  3. line = (
  4. Line()
  5. .add_xaxis(["{}".format(i) for i in range(10)])
  6. .add_yaxis(
  7. series_name="",
  8. # randrange(xx, xx) for x in range(x) 获取一个二维列表,列表长度为10,值的范围为在区间(50, 80)
  9. # [["0", 63], ["1", 79], ["2", 50], ["3", 65], ["4", 63], ["5", 72], ["6", 69], ["7", 65], ["8", 69], ["9", 64]]
  10. y_axis=[randrange(50, 80) for _ in range(10)],
  11. is_smooth=True,
  12. label_opts=opts.LabelOpts(is_show=False),
  13. )
  14. .set_global_opts(
  15. title_opts=opts.TitleOpts(title="动态数据"),
  16. xaxis_opts=opts.AxisOpts(type_="value"),
  17. yaxis_opts=opts.AxisOpts(type_="value"),
  18. )
  19. .dump_options_with_quotes()
  20. )
  21. return line
  22. class ChartLineView(APIView):
  23. def get(self, request, *args, **kwargs):
  24. return JsonResponse(json.loads(line_base()))
  25. class ChartLineUpdateView(APIView):
  26. def get(self, request, *args, **kwargs):
  27. global cnt
  28. cnt = cnt + 1 # line_base()已经绘制了第0~9个点,接下来从第10个点开始绘制
  29. return JsonResponse({"name": cnt, "value": randrange(50, 80)})
  30. class IndexView3(APIView):
  31. def get(self, request, *args, **kwargs):
  32. global cnt
  33. cnt = 9 # line_base()已经绘制了第0~9个点,接下来从第10个点开始绘制
  34. return HttpResponse(content=open("./templates/index3.html").read())

 这样修改后,刷新index3.html会重新画折线图

运行之后,http://127.0.0.1:8000/demo/index3/效果如下:

Awesome-pyecharts

6. 本地加载js文件

另外,如果调试的时候觉得加载 https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js 和 https://assets.pyecharts.org/assets/echarts.min.js 速度太慢可以将这两个js文件保存在本地。

保存在pyecharts_django_demo项目根目录下的/static/js/目录下。

 找到setting.py修改STATIC_URL:(输入到该文件的末尾即可,注意符号)

  1. STATIC_URL = '/static/'
  2. STATICFILES_DIRS = ( os.path.join('static'), )
  3. STATIC_ROOT = ''

修改index.html   index2.html   index3.html文件以下部分即可:

  1. <!-- <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>-->
  2. <!-- <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>-->
  3. <script src="/static/js/jquery.min.js"></script>
  4. <script type="text/javascript" src="/static/js/echarts.min.js"></script>

7. 修改pyecharts自带的主题

pyechart给使用用户提供了一套主题样式,使用户对其的使用更加方便。

试了下在views.py中以

Pie(init_opts=opts.InitOpts(theme=ThemeType.DARK))

方式更换主题未生效, 然后发现在index.html下已经设置了“white”主题。

var chart = echarts.init(document.getElementById('pie'), 'white', {renderer: 'canvas'});

将“white”字段修改为“dark”后能生效:

var chart = echarts.init(document.getElementById('pie'), 'dark', {renderer: 'canvas'});

但是这种方式我尝试了一下只有

BUILTIN_THEMES = ["light", "dark", "white"]

中的三种主题会生效。其余的十几种主题无法生效。

--------------------------------------------更新--------------------------------------------

通过html执行的是echarts,所以只能使用默认的三种内置主题。如果需要使用另外的十几种主题可以直接下载主题js文件,在HTML中引入js文件。

主题编辑器网址 >> 主题编辑器 - Apache ECharts

 该编辑器中默认的十几种就是pyecharts的globals.py中预设的,并且还能在编辑器中进行修改后再下载js文件。

 例如下载了一款名为 wonderland 的主题,将wonderland.js文件放在pyecharts_django_demo项目根目录下的/static/js/theme目录下:

 修改index.html   index2.html   index3.html文件,在<head /><head>中增加以下代码引用js文件:

<script src="/static/js/theme/wonderland.js"></script>

设置“wonderland”主题,保存后刷新页面可以看到主题生效:

var chart = echarts.init(document.getElementById('bar'), 'wonderland', {renderer: 'canvas'});

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号