赞
踩
注意:
以下示例是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
命令行中输入以下命令
django-admin startproject pyecharts_django_demo
创建一个应用程序
python manage.py startapp demo
效果如下:
创建完之后,在 Pycharm 中打开该项目,当然你也可以直接在 Pycharm 中创建
同时在pyecharts_django_demo/settings.py
中注册应用程序INSTALLED_APPS
中添加应用程序demo
- INSTALLED_APPS = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'demo',
- ]
在pyecharts_django_demo/urls.py
中新增demo.urls
- from django.contrib import admin
- from django.urls import path, include
-
-
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('demo/', include('demo.urls')),
- ]
新建demo/urls.py
文件
- from django.urls import path
- from . import views
-
- urlpatterns = [
- path('pie/', views.ChartView.as_view(), name='demoChart'),
- path('index/', views.IndexView.as_view(), name='demoIndex'),
- ]
由于 json 数据类型的问题,无法将 pyecharts 中的 JSCode 类型的数据转换成 json 数据格式返回到前端页面中使用。
因此在使用前后端分离的情况下尽量避免使用 JSCode 进行画图。
将下列代码保存到demo/views.py
中
- import json
- from random import randrange
-
- from django.http import HttpResponse
- from rest_framework.views import APIView
-
- from pyecharts.charts import Bar, Pie
- from pyecharts.faker import Faker
- from pyecharts import options as opts
-
-
- # Create your views here.
- def response_as_json(data):
- json_str = json.dumps(data)
- response = HttpResponse(
- json_str,
- content_type="application/json",
- )
- response["Access-Control-Allow-Origin"] = "*"
- return response
-
-
- def json_response(data, code=200):
- data = {
- "code": code,
- "msg": "success",
- "data": data,
- }
- return response_as_json(data)
-
-
- def json_error(error_string="error", code=500, **kwargs):
- data = {
- "code": code,
- "msg": error_string,
- "data": {}
- }
- data.update(kwargs)
- return response_as_json(data)
-
-
- JsonResponse = json_response
- JsonError = json_error
-
-
- def pie_base() -> Pie:
- c = (
- Pie()
- .add("", [list(z) for z in zip(Faker.choose(), Faker.values())])
- .set_colors(["blue", "green", "yellow", "red", "pink", "orange", "purple"])
- .set_global_opts(title_opts=opts.TitleOpts(title="Pie-示例"))
- .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
- .dump_options_with_quotes()
- )
- return c
-
-
- class ChartView(APIView):
- def get(self, request, *args, **kwargs):
- return JsonResponse(json.loads(pie_base()))
-
-
- class IndexView(APIView):
- def get(self, request, *args, **kwargs):
- return HttpResponse(content=open("./templates/index.html").read())
在根目录下新建一个templates
的文件夹,并在该文件夹下新建一个index.html
文件
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Awesome-pyecharts</title>
- <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
- <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
-
- </head>
- <body>
- <div id="pie" style="width:1000px; height:600px;"></div>
- <script>
- var chart = echarts.init(document.getElementById('pie'), 'white', {renderer: 'canvas'});
-
- $(
- function () {
- fetchData(chart);
- }
- );
-
- function fetchData() {
- $.ajax({
- type: "GET",
- url: "http://127.0.0.1:8000/demo/pie",
- dataType: 'json',
- success: function (result) {
- chart.setOption(result.data);
- }
- });
- }
- </script>
- </body>
- </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/,效果如下:
前面讲的是一个静态数据的展示的方法,用 Pyecharts 和 Django 结合最主要是实现一种动态更新数据,增量更新数据等功能。
定时全量更新主要是前端主动向后端进行数据刷新,定时刷新的核心在于 HTML 的 setInterval 方法。
新增index2.html
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Awesome-pyecharts</title>
- <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
- <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
-
- </head>
- <body>
- <div id="bar" style="width:1600px; height:800px;"></div>
- <script>
- var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
-
- $(
- function () {
- fetchData(chart);
- <!-- refresh time 1000ms-->
- setInterval(fetchData, 1000);
- }
- );
-
- function fetchData() {
- $.ajax({
- type: "GET",
- url: "http://127.0.0.1:8000/demo/bar",
- dataType: 'json',
- success: function (result) {
- chart.setOption(result.data);
- }
- });
- }
- </script>
- </body>
- </html>
同时在demo/views.py
中,增加如下代码:
- def bar_base() -> Bar:
- c = (
- Bar()
- .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
- .add_yaxis("商家A", [randrange(20, 100) for _ in range(6)])
- .add_yaxis("商家B", [randrange(20, 100) for _ in range(6)])
- .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="这是副标题"))
- .dump_options_with_quotes()
- )
- return c
-
-
- class ChartView2(APIView):
- def get(self, request, *args, **kwargs):
- return JsonResponse(json.loads(bar_base()))
-
-
- class IndexView2(APIView):
- def get(self, request, *args, **kwargs):
- return HttpResponse(content=open("./templates/index2.html").read())
demo/urls.py
中,修改成如下代码:
- from django.urls import path
- from django.template.defaulttags import url
-
- from . import views
-
- urlpatterns = [
- path('pie/', views.ChartView.as_view(), name='demoChart'),
- path('index/', views.IndexView.as_view(), name='demoIndex'),
- path('bar/', views.ChartView2.as_view(), name='demoChart'),
- path('index2/', views.IndexView2.as_view(), name='demoIndex'),
- ]
运行之后,http://127.0.0.1:8000/demo/index2/效果如下:
Awesome-pyecharts
原理一样,新增index3.html ,代码如下(网上别的教程里这块代码有问题达不到增量更新的效果,我已经做了修改):
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Awesome-pyecharts</title>
- <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
- <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
-
- </head>
- <body>
- <div id="bar" style="width:1600px; height:800px;"></div>
- <script>
- var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
- var old_data = [];
- $(
- function () {
- fetchData(chart);
- setInterval(getDynamicData, 100);
- }
- );
-
- function fetchData() {
- $.ajax({
- type: "GET",
- url: "http://127.0.0.1:8000/demo/line",
- dataType: "json",
- success: function (result) {
- var options = result.data;
- chart.setOption(options);
- old_data = chart.getOption().series[0].data;
- }
- });
- }
-
- function getDynamicData() {
- $.ajax({
- type: "GET",
- url: "http://127.0.0.1:8000/demo/lineUpdate",
- dataType: 'json',
- success: function (result) {
- var options = result.data;
- old_data.push([options.name, options.value]);
- chart.setOption({
- series: [{
- data: old_data
- }]
- });
- }
- });
- }
-
- </script>
- </body>
- </html>
index3.html中新增了两个请求地址demo/line
,demo/lineUpdate
所以在demo/urls.py
中增加以下路径的匹配(网上别的教程里这块代码有问题达不到增量更新的效果,我已经做了修改):
- from django.urls import path
- from django.template.defaulttags import url
-
- from . import views
-
- urlpatterns = [
- path('pie/', views.ChartView.as_view(), name='demoChart'),
- path('index/', views.IndexView.as_view(), name='demoIndex'),
- path('bar/', views.ChartView2.as_view(), name='demoChart2'),
- path('index2/', views.IndexView2.as_view(), name='demoIndex2'),
- path('line/', views.ChartLineView.as_view(), name='demoLine'),
- path('lineUpdate/', views.ChartLineUpdateView.as_view(), name='demoLineUpdate'),
- path('index3/', views.IndexView3.as_view(), name='demoIndex3'),
- ]
最后在views.py
中导入Line:
from pyecharts.charts import Bar, Pie, Line
并在views.py
中增加以下代码(网上别的教程里这块代码有问题达不到增量更新的效果,我已经做了修改):
- cnt = 0
-
-
- def line_base() -> Line:
- line = (
- Line()
- .add_xaxis(["{}".format(i) for i in range(10)])
- .add_yaxis(
- series_name="",
- # randrange(xx, xx) for x in range(x) 获取一个二维列表,列表长度为10,值的范围为在区间(50, 80)
- # [["0", 63], ["1", 79], ["2", 50], ["3", 65], ["4", 63], ["5", 72], ["6", 69], ["7", 65], ["8", 69], ["9", 64]]
- y_axis=[randrange(50, 80) for _ in range(10)],
- is_smooth=True,
- label_opts=opts.LabelOpts(is_show=False),
- )
- .set_global_opts(
- title_opts=opts.TitleOpts(title="动态数据"),
- xaxis_opts=opts.AxisOpts(type_="value"),
- yaxis_opts=opts.AxisOpts(type_="value"),
- )
- .dump_options_with_quotes()
- )
- return line
-
-
- class ChartLineView(APIView):
- def get(self, request, *args, **kwargs):
- return JsonResponse(json.loads(line_base()))
-
-
- class ChartLineUpdateView(APIView):
- def get(self, request, *args, **kwargs):
- global cnt
- cnt = cnt + 1 # line_base()已经绘制了第0~9个点,接下来从第10个点开始绘制
- return JsonResponse({"name": cnt, "value": randrange(50, 80)})
-
-
- class IndexView3(APIView):
- def get(self, request, *args, **kwargs):
- global cnt
- cnt = 9 # line_base()已经绘制了第0~9个点,接下来从第10个点开始绘制
- return HttpResponse(content=open("./templates/index3.html").read())
这样修改后,刷新index3.html会重新画折线图
运行之后,http://127.0.0.1:8000/demo/index3/效果如下:
Awesome-pyecharts
另外,如果调试的时候觉得加载 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:(输入到该文件的末尾即可,注意符号)
- STATIC_URL = '/static/'
- STATICFILES_DIRS = ( os.path.join('static'), )
- STATIC_ROOT = ''
修改index.html index2.html index3.html文件以下部分即可:
- <!-- <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>-->
- <!-- <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>-->
- <script src="/static/js/jquery.min.js"></script>
- <script type="text/javascript" src="/static/js/echarts.min.js"></script>
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'});
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。