Highcharts 是一个用纯 JavaScript 编写的一个图表库.
Highcharts 能够很简单便捷的在 web 网站或是 Web 应用程序添加有交互性的图表
Highcharts 免费提供给个人学习, 个人网站和非商业用途使用.
访问官网:
https://www.hcharts.cn/
进入下载页面:
https://www.hcharts.cn/download
下载 6.10 版本
解压 Highcharts-6.1.0.zip 文件, 访问里面的 index.htm 文件.
点击 Time series, zoomable
页面效果如下:
这个, 就是接下来 django 需要用的模板.
它在目录 Highcharts-6.1.0\examples\line-time-series 里面, 编辑 line-time-series 目录下的 index.htm 文件
注意这一行:
'https://cdn.rawgit.com/highcharts/highcharts/057b672172ccc6c08fe7dbb27fc17ebca3f5b770/samples/data/usdeur.json',
它是图表需要的 JSON 数据, 打开这个 JSON 链接, 将网页内容复制, 使用 JSON 格式化工具处理, 效果如下:
如果谷歌浏览器, 安装插件 JSON Formatter, 就可以得到上面的效果.
它的数据格式一个大的列表, 里面每一个元素都是小列表.
列表第一个值, 是一个时间戳, 第二个是具体的值. 打开站长工具的时间戳转换, 链接如下:
https://tool.lu/timestamp/
输入数值 1167609600000, 点击转换
很明显, 时间不对. 为什么呢? 因为它是毫秒
选择毫秒, 再次点击转换, 时间就对了.
那么 django 需要输出, 指定格式的 JSON 数据, 才能展示正确的图表.
数据从何而来呢? 自己造呗!
下面将演示, 如何展示一个 CPU 使用率的图表.
在项目根目录创建文件 monit_system.py, 它能统计系统的 CPU 使用率, 内存使用情况.
统计完成之后, 将对应的数值插入到 MySQL 中. 它会插入 30 条记录, 每隔 10 秒采集一次.
代码如下:
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import pymysql
- import gevent
- import time
- import psutil
- # 解决 wind10 错误 OSError: raw write() returned invalid length
- import win_unicode_console
- win_unicode_console.enable()
- class MyPyMysql:
- def __init__(self, host, port, username, password, db, charset='utf8'):
- self.host = host # MySQL 主机地址
- self.port = port # MySQL 端口
- self.username = username # MySQL 远程连接用户名
- self.password = password # MySQL 远程连接密码
- self.db = db # MySQL 使用的数据库名
- self.charset = charset # MySQL 使用的字符编码, 默认为 utf8
- self.pymysql_connect() # __init__初始化之后, 执行的函数
- def pymysql_connect(self):
- # pymysql 连接 MySQL 数据库
- # 需要的参数 host,port,user,password,db,charset
- self.conn = pymysql.connect(host=self.host,
- port=self.port,
- user=self.username,
- password=self.password,
- db=self.db,
- charset=self.charset
- )
- # 连接 MySQL 后执行的函数
- self.asynchronous()
- def getCPUstate(self,interval=1):
- CPU = psutil.cpu_percent(interval)
- return CPU
- def getMemorystate(self):
- phymem = psutil.virtual_memory()
- cur_mem = phymem.percent
- mem_rate = int(phymem.used / 1024 / 1024)
- mem_all = int(phymem.total / 1024 / 1024)
- line = {
- 'cur_mem': cur_mem,
- 'mem_rate': mem_rate,
- 'mem_all': mem_all,
- }
- return line
- def run(self):
- # 创建游标
- self.cur = self.conn.cursor()
- # 定义 sql 语句
- sql = "insert into blog_system_monit(cpu,cur_mem,mem_rate,mem_all,create_time,time_stamp) values (%s,%s,%s,%s,%s,%s)"
- print(sql)
- # 定义数据
- CPU = self.getCPUstate() # CPU 使用率
- mem = self.getMemorystate() # 内存 info 信息
- mem_rate = mem['mem_rate'] # 内存使用率
- cur_mem = mem['cur_mem'] # 当前使用内存
- mem_all = mem['mem_all'] # 总内存
- struct_time = time.localtime()
- create_time = time.strftime("%Y-%m-%d %H:%M:%S", struct_time) # 转换为标准时间
- t = time.time() # 当前时间戳
- time_stamp = int(round(t * 1000)) # 转换为毫秒的时间戳
- print((CPU, cur_mem,mem_rate, mem_all,create_time,time_stamp))
- # 执行插入一行数据, 如果插入多行, 使用 executemany(sql 语句, 数据 (需一个元组类型))
- content = self.cur.execute(sql,(CPU,cur_mem,mem_rate,mem_all,create_time,time_stamp))
- if content:
- print('插入 ok')
- # 提交数据, 必须提交, 不然数据不会保存
- self.conn.commit()
- def asynchronous(self):
- #执行 30 次协程任务
- for i in range(0,30):
- time.sleep(10) # 等待 10 秒
- gevent.spawn(self.run()) # 执行方法
- self.cur.close() # 关闭游标
- self.conn.close() # 关闭 pymysql 连接
- if __name__ == '__main__':
- start_time = time.time() # 计算程序开始时间
- st = MyPyMysql('127.0.0.1', 3306, 'root', '','db2') # 实例化类, 传入必要参数
- print('程序耗时 {:.2f}'.format(time.time() - start_time)) # 计算程序总耗时
创建表 blog_system_monit
进入 django 项目, 修改 blog 目录下的 models.py, 内容如下:
- from django.db import models
- # Create your models here.
- # 必须要继承 models.Model 类, 这个固定写法.
- # 这里表示创建表 blog_system_monit,blog 是应用名, 它会自动加上的.
- class system_monit(models.Model):
- #id 自增, 类型为 bigint. 设置为主键
- id = models.BigAutoField(primary_key=True)
- #类型为 decimal(10,2), 长度为 10, 小数点保留 2 位
- CPU = models.DecimalField(max_digits=10, decimal_places=2)
- #类型为 int(11),11 是默认长度
- cur_mem = models.IntegerField()
- mem_rate = models.DecimalField(max_digits=10, decimal_places=2)
- mem_all = models.IntegerField()
- #类型为 datetime
- create_time = models.DateTimeField()
- #由于毫秒的时间戳超过了 timestamp 的长度, 所以只能设置 bigint 了.
- time_stamp = models.BigIntegerField()
在 Pycharm 的 Terminal 窗口中, 输入以下命令
- python manage.py makemigrations
- python manage.py migrate
执行完成之后, 它会自动创建表 blog_system_monit
使用 pycharm 执行脚本 monit_system.py, 等待 5 分钟, 就会插入 30 条数据.
如果脚本没有报错, 查看表记录, 会有 30 条记录
编辑文件 views.py, 增加 2 个视图函数
- def chart(request):
- #显示 html 文件
- return render(request, "chart.html")
- def chart_json(request):
- #读取表所有记录
- system_monit = models.system_monit.objects.all()
- data = [] # 创建一个空列表
- for i in system_monit: # 遍历, 拼横纵坐标
- #横坐标为时间戳, 纵坐标为 CPU 使用率. 注意, 必须转换类型, 否则数据不对.
- data.append([int(i.time_stamp),float('%.2f' % i.CPU)])
- print(data)
- isdict = JSON.dumps(data) # JSON 序列化列表
- return HttpResponse(isdict, content_type="application/json") # 执行类型为 JSON
修改 mysite 下的 urls.py, 新增 2 个路径
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('chart/', views.chart),
- path('chart_json/', views.chart_json),
- ]
访问 JSON 的 url
http://127.0.0.1:8000/chart_json/
必须保证格式, 和上面 cdn.rawgit.com 链接的 JSON 格式一样.
上的图片是用了 JSON Formatter 插件展示 JSON 数据的效果.
否则下面的步骤不用做了!!!
将 line-time-series 目录下的 index.htm 文件复制到 django 项目的 templates 目录下, 重命名为 chart.HTML
在 django 项目的 static 文件夹下, 创建目录 Highcharts-6.1.0
将 Highcharts-6.1.0 解压目录中的 3 个文件, 复制到此目录
修改部分代码, 大家可以和 index.htm 对比一下, 就知道修改的部分了. 完整代码如下:
- <!DOCTYPE HTML>
- <HTML>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>
- Highcharts Example
- </title>
- <style type="text/CSS">
- </style>
- {# 配置 favicon.ico, 解决警告 Not Found: /favicon.ico#} {% load staticfiles
- %}
- <link REL="SHORTCUT ICON" HREF="{% static" images/favicon.ico "%}"/>
- </head>
- <body>
- <script src="../static/js/jquery-3.3.1.min.js">
- </script>
- <script src="../static/Highcharts-6.1.0/highcharts.js">
- </script>
- <script src="../static/Highcharts-6.1.0/modules/exporting.js">
- </script>
- <script src="../static/Highcharts-6.1.0/modules/export-data.js">
- </script>
- <div id="container" style="min-width: 310px; height: 400px; margin: 0 auto">
- </div>
- <script type="text/javascript">
- {#解决显示时间少8小时问题#
- }
- Highcharts.setOptions({
- global: {
- useUTC: false
- }
- });
- $.getJSON({#'https://cdn.rawgit.com/highcharts/highcharts/057b672172ccc6c08fe7dbb27fc17ebca3f5b770/samples/data/usdeur.json',
- #
- }
- '/chart_json/',
- function(data) {
- Highcharts.chart('container', {
- chart: {
- zoomType: 'x'
- },
- title: {
- text: 'cpu 使用率'
- },
- subtitle: {
- text: document.ontouchstart === undefined ? '单击并拖动绘图区域以放大': '捏合图表放大'
- },
- xAxis: {
- type: 'datetime',
- },
- {#自定义x坐标信息显示,
- return部分是用JS拼接的,
- 内容可以自己定义.#
- }
- tooltip: {
- formatter: function() {
- return '<strong>' + this.series.name + ':' + this.y + '%<br/></strong>' + Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x);
- }
- },
- yAxis: {
- title: {
- text: '使用率'
- }
- },
- legend: {
- enabled: false
- },
- plotOptions: {
- area: {
- fillColor: {
- linearGradient: {
- x1: 0,
- y1: 0,
- x2: 0,
- y2: 1
- },
- stops: [[0, Highcharts.getOptions().colors[0]], [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]]
- },
- marker: {
- radius: 2
- },
- lineWidth: 1,
- states: {
- hover: {
- lineWidth: 1
- }
- },
- threshold: null
- }
- },
- series: [{
- type: 'area',
- name: '百分比',
- data: data
- }]
- });
- });
- </script>
- </body>
- </HTML>
项目文件结构如下:
mysite/
├── blog
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── models.py
│ └── views.py
├── manage.py
├── monit_system.py
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── static
│ ├── CSS
│ ├── Highcharts-6.1.0
│ │ ├── highcharts.JS
│ │ └── modules
│ │ ├── export-data.JS
│ │ └── exporting.JS
│ ├── images
│ │ └── favicon.ico
│ └── JS
│ └── jQuery-3.3.1.min.JS
└── templates
├── chart.HTML
├── cur_time.HTML
├── detail.HTML
└── index.HTML
使用 pycharm 启动 django 项目, 访问 url
http://127.0.0.1:8000/chart/
页面效果如下:
图标支持放大和缩小, 可以看到秒级的数据, 比如
增加黑色主题
打开解压路径, 进入目录 Highcharts-6.1.0\code\themes, 里面有一个 dark-unica.JS 文件
在 static\Highcharts-6.1.0 目录下创建目录 themes, 将 dark-unica.JS 文件复制到此目录
修改 char.HTML 文件, 在
<script src="../static/Highcharts-6.1.0/modules/export-data.js"></script>
下面一行添加如下代码, 导入主题 JS
- {
- # 黑色主题 #
- }
- <script src="../static/Highcharts-6.1.0/themes/dark-unica.js"></script>
再次访问网页, 效果如下:
来源: http://www.bubuko.com/infodetail-2861059.html