Highcharts 是一个用纯JavaScript编写的一个图表库。
Highcharts 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表
Highcharts 免费提供给个人学习、个人网站和非商业用途使用。
访问官网:
进入下载页面:
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,就可以得到上面的效果。
它的数据格式一个大的列表,里面每一个元素都是小列表。
列表第一个值,是一个时间戳,第二个是具体的值。打开站长工具的时间戳转换,链接如下:
输入数值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?===??developer/article/1176324/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
页面效果如下:
图标支持放大和缩小,可以看到秒级的数据,比如
增加黑色主题
打开解压路径,进入目录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>
再次访问网页,效果如下:
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:/developer/support-plan?invite_code=vcus7uflzabs