d3.js是一個近年來推出的基於javascript的數據展現庫,全稱爲Data Driven Document, 在瀏覽器數據展現領域的地位相似於通用js框架裏的jQuery。d3.js的官網是d3js.org,你們能夠在上面看到不少例子和應用。d3.js也是圖形數據庫neo4j所內置的數據展現工具。javascript
說到圖形數據庫,其實正確的翻譯應該是圖數據庫,圖即所謂的Graph,來自於數學裏的圖論,好比四色定理和推銷員過橋的問題(著名的NP問題之一)。圖數據庫着重於數據之間的關聯和屬性,對於關係錯綜複雜的關係分析效率很高。例如,我想知道誰是我朋友的朋友,而且他們有哪些朋友也認識我。對於這種問題,普通關係型數據庫的計算複雜度是O(N^c)左右或者更高,N爲選擇範圍的數據集合大小,你好友數量加上好友的好友的數量等,c爲關係層數。圖數據庫的計算複雜度在O(N^2)左右或者更低,可是基本不會超過O(N^2)。html
圖數據庫對於複雜關係數據查詢起來效率高的主要緣由是在數據輸入的時候就已經對關係進行了處理和索引,這樣作在查詢的時候具備很高的效率,可是在數據導入的時候會很慢。QQ羣的15億個關係在向圖數據庫neo4j裏導入的時候花了3天都沒弄完,也沒有進度提示,因此後來我直接放棄了。java
數據處理node
在QQ羣和羣成員關係裏面,對於層數我是這麼定義的:mysql
你們能夠看出這樣的查詢是能夠遞歸的,假設每一個QQ號所加入的羣數量和每一個羣的成員數量爲N,那麼查詢3層數據時總計算量爲N*N*N=n^3,因此當查詢層數爲c層的時候,計算複雜度是N^c。web
前面說過,圖數據庫的計算複雜度通常在N^2如下,因此當使用普通的關係型數據庫的時候,若是查詢的層數很少,效率和圖數據庫比起來差很少,加上關係數據庫自帶的便於管理和導入導出的屬性,因此我仍是選擇了mysql數據庫。sql
對於QQ和QQ羣之間的關係,每一個QQ號都能加入羣,一個羣裏也有不少QQ,基本都在幾十到幾百人,因此兩個QQ號在同一個羣裏不必定表明他們的關係很緊密,換句話說QQ和QQ羣之間的關係相對於QQ好友而言相對較弱。可是這並不表明咱們從中不能分析出有用的資料,俗話說的好,大數據就像一座金礦,只有用力挖才能挖到金子。數據庫
d3.js支持多種數據格式,好比JSON,XML,CSV,HTML等,由於PHP的數組能夠很簡單的轉換爲JSON格式,因此我選擇用PHP寫API來獲取JSON數據。QQ和QQ羣是一種典型的圖數據的應用,QQ和QQ羣做爲節點(node),QQ加入了哪些羣做爲關係(link),d3.js內置了一個功能很強大的內建佈局,叫作Force-Directed Graph(受力導向圖),後面簡稱爲force。force佈局模擬了一些基本的物理粒子原理,好比引力和斥力(確切的說是模擬了電磁力和引力,在離的遠的時候會互相吸引,在離的近的時候斥力急劇增長),而且能夠調節力的大小和受力距離等等,能夠說是自由度至關高。關於d3.js的force佈局,在官網有詳細的API和很多例子,這裏我就不貼代碼了。數組
在force佈局裏面,數據源的JSON能夠有不少種不一樣的格式和屬性,可是基本格式以下:瀏覽器
其中nodes數組對應的是節點列表,links對應的是關係列表。
每一個節點能夠有不少自定義屬性,在d3.js能夠針對每一個節點存取節點的屬性,好比我定義num是QQ號或者羣號,type表明節點是QQ仍是羣,另外我在js裏設定在type==‘qun’的時候顯示羣的圖標,是qq的時候顯示qq的圖標。關係裏面默認的屬性有source和target,分別對應一個關係的兩頭,默認狀況下關係裏面的source和target對應的數字是節點在節點數組裏面的位置index。可是我自定義成了qq號和羣號。另外你也能夠定義其餘屬性,好比auth表明這個QQ號在羣裏的權限,nick是羣暱稱。
對於QQ羣這樣的關係來講,基本上在第4層和以上的QQ和羣的關係就比較弱了,因此爲了提升查詢速度和減小節點數量,我只查詢2層關係(少麼?很多,要想一想有些羣有超過500人……)。
首先,d3.js須要在瀏覽器裏面運行,個人首選是Google Chrome,V8引擎的效率果真不錯,在節點和關係很少的時候基本感受不到延遲,後來在FF和IE11裏面測試了一次,FF比Chrome卡一半左右,IE的話我只能呵呵了……
先拿小馬哥作個測試,QQ號是霸氣的10001。當d3.js導入完數據JSON的時候,各類節點會在屏幕上亂飛幾秒鐘,直到他們的力達到一個穩定的平衡點。結果以下:
你們也能夠看到,羣主和管理員的關係線也比普通的羣成員長一些,這是爲了突出羣內的重要成員的關係。
圖標旁邊自動標註了QQ號和羣號,若是有的話還有羣名。沒有在QQ號旁邊標註暱稱是由於不少人加入不一樣的羣使用的是不一樣暱稱,因此把暱稱放到了其餘的地方顯示。
在下圖中你們能夠隱約的看到,全部的關係都是以QQ 10001爲起點的。
在圖上節點是能夠拖拽的,拖拽後會固定在你釋放的地方。咱們把幾個羣稍微拖的分開一點,關係就一目瞭然了。
這個時候咱們能夠看到在目標的QQ羣裏也有不少共同QQ號,好比有些QQ號同時加入了2,3個羣。羣名顯示的都是各類產品開發討論羣,這些同時加入2,3個產品羣的人估計不是產品經理就是主管吧……、
鼠標懸停到羣圖標上能夠看到羣的詳細信息(若是有的話)
由於不少人在不一樣羣裏的暱稱不同,因此羣內暱稱等信息就只能放到link上面了,由於線比較細,因此鼠標比較難對準,這個功能還待修改。
這個傢伙和小馬哥一塊兒同時在3個羣裏,好基友?
下面咱們來看看更加實際的應用,好比把某圈子裏的人找出來。咱們先從某土豪大黑闊大牛的QQ號入手:
初始數據好多……此大黑闊加入的羣夠雜的,不過就是由於雜因此才能更深刻的瞭解一我的的全部喜愛。看看羣名神馬的,我好像看到了dota,XX國際俱樂部,web技術交流,XXsec等羣……充分說明了此人……是個屌絲技術宅大黑闊,XX國際俱樂部又彷佛帶着那麼種高大上的感受……
圖中錯綜複雜的各類關係組成了一朵朵怒放的菊花,向咱們訴說着他的歷史……
爲了理清他那不堪回首的過去和關係網,我特意把瀏覽器窗口拖到第二個屏幕上,而後把羣挨個分開。爲了保護當事人的隱私,這張圖我打碼了。
這張圖比較寬,建議你們下載下來放大看
總結
假如把層數擴展到4層,不知可否篩選出中國全部黑闊的QQ號呢?至少我已經在這張圖裏看到了不少熟悉的名字和號碼。 騰訊老是說漏洞早已修復,不存在問題了,廣大網民放心,但實際上信息泄露這種事情,豈是你漏洞修復好了就結束了的事情?
做者: Anthr@X anthrax@insight-labs.org