標(biāo)題說的可能不是很清楚兔朦。事情是這樣的,最近在用python做一個(gè)數(shù)據(jù)的處理及可視化的項(xiàng)目磨确,但是數(shù)據(jù)比較復(fù)雜沽甥,用python包繪圖無法滿足我們的全部功能,于是想要用D3.js來進(jìn)行可視化及交互乏奥。而為了其他人使用方便摆舟,我打算運(yùn)行完python程序就可以在本地生成一個(gè)html文件并自動(dòng)打開。當(dāng)然邓了,要是想這個(gè)功能可以用python搭一個(gè)服務(wù)端恨诱。但在我這個(gè)功能下是完全沒有必要的。
話不多說驶悟,由于項(xiàng)目的數(shù)據(jù)不可能拿來分享胡野,我這里用的是d3官網(wǎng)上的一個(gè)數(shù)據(jù)材失。這里做了一個(gè)demo痕鳍,供大家參考。結(jié)構(gòu)如下:
demo/
demo.py
plot.js
demo.css
demo.json
然后只要運(yùn)行一下demo.py就會(huì)打開一個(gè)html頁面龙巨。具體代碼看這里笼呆。https://github.com/peakhell/demo
其實(shí)關(guān)鍵的地方只有一個(gè)
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)
注意看上面的函數(shù), graph是數(shù)據(jù)旨别,在我這個(gè)demo中是通過python讀取的json文件诗赌。filename就是你要保存的文件名。
向js傳遞參數(shù)很簡單秸弛。只用在js文件中定義一個(gè)接受數(shù)據(jù)的函數(shù)铭若。然后用python的字符串拼接將傳輸傳進(jìn)去就可以了〉堇溃看這個(gè)地方叼屠。
data_func,
"read_data({});".format(graph),
注意read_data同時(shí)也是plot.js中的一個(gè)函數(shù)。通過這一個(gè)就可以將數(shù)據(jù)傳進(jìn)js中了绞铃。值得注意的是,一定要注意你傳入的數(shù)據(jù)類型镜雨,你不能傳遞一個(gè)js中沒有的數(shù)據(jù)類型,例如ndarray儿捧。根據(jù)我的測試荚坞,你可以再python中直接傳入以下類型的數(shù)據(jù):字符串,數(shù)字菲盾,json颓影,字典,list懒鉴。tuple也可以傳入瞭空,但是效果不對。
demo的運(yùn)行效果如下:
demo是一個(gè)力導(dǎo)向圖。值得注意的是咆畏,demo.css中有一句很重要
* {
margin: 0;
padding: 0;
}
如果不加這一句的話南捂,出來的html頁面將會(huì)變寬和變高,導(dǎo)致出現(xiàn)滾輪旧找。這是由于body元素自帶的margin導(dǎo)致的溺健。因此一定要添加。
我這個(gè)項(xiàng)目接下來的工作是給這個(gè)頁面添加交互功能钮蛛。如一鍵保存成圖片鞭缭,放大縮小,雙擊還原等等魏颓。有空了會(huì)把這些方法寫到這些demo中岭辣,到時(shí)候再更新github, 如果有人看的話甸饱,我也會(huì)更新這篇文章沦童,記錄一下關(guān)鍵技術(shù)。