标题说的可能不是很清楚。事情是这样的,最近在用python做一个数据的处理及可视化的项目,但是数据比较复杂,用python包绘图无法满足我们的全部功能,于是想要用D3.js来进行可视化及交互。而为了其他人使用方便,我打算运行完python程序就可以在本地生成一个html文件并自动打开。当然,要是想这个功能可以用python搭一个服务端。但在我这个功能下是完全没有必要的。
话不多说,由于项目的数据不可能拿来分享,我这里用的是d3官网上的一个数据。这里做了一个demo,供大家参考。结构如下:
demo/
demo.py
plot.js
demo.css
demo.json
然后只要运行一下demo.py就会打开一个html页面。具体代码看这里。https://github.com/peakhell/demo
其实关键的地方只有一个
def plot_net(graph, filename):
with open("plot.js", "r") as f:
data_func = f.read()
with open(filename, "w") as f:
f.write(''.join([
'<html>',
'<head><meta charset="utf-8" /></head>',
"<script src='https://d3js.org/d3.v4.min.js'></script>",
"<link href='demo.css' rel='stylesheet' type='text/css'/>",
'<body>',
"<div id='draw'>",
"<svg></svg>",
"</div>"
"<script>",
data_func,
"read_data({});".format(graph),
"</script>"
]))
webbrowser.open_new_tab(filename)
注意看上面的函数, graph是数据,在我这个demo中是通过python读取的json文件。filename就是你要保存的文件名。
向js传递参数很简单。只用在js文件中定义一个接受数据的函数。然后用python的字符串拼接将传输传进去就可以了。看这个地方。
data_func,
"read_data({});".format(graph),
注意read_data同时也是plot.js中的一个函数。通过这一个就可以将数据传进js中了。值得注意的是,一定要注意你传入的数据类型,你不能传递一个js中没有的数据类型,例如ndarray。根据我的测试,你可以再python中直接传入以下类型的数据:字符串,数字,json,字典,list。tuple也可以传入,但是效果不对。
demo的运行效果如下:
demo是一个力导向图。值得注意的是,demo.css中有一句很重要
* {
margin: 0;
padding: 0;
}
如果不加这一句的话,出来的html页面将会变宽和变高,导致出现滚轮。这是由于body元素自带的margin导致的。因此一定要添加。
我这个项目接下来的工作是给这个页面添加交互功能。如一键保存成图片,放大缩小,双击还原等等。有空了会把这些方法写到这些demo中,到时候再更新github, 如果有人看的话,我也会更新这篇文章,记录一下关键技术。