D3.js 以圓做點繪製力圖(一)

來源:互聯網
上載者:User

標籤:d3   d3.js   資料視覺效果   大資料   

SVG是什嗎?

如何在SVG上繪製一個圓?

如何在SVG上繪製一條線?

力圖的基本屬性有哪些?

這些問題將由本文來一一解答。

在代碼方面,我們沿用上文的網頁架構,把body裡面的js替換成現在的js即可。


SVG

  SVG,可縮放的向量圖,我們以後所繪製 的資料展示圖大都是在SVG這個大容器內完成的,它相當於畫布。建立SVG,就是有利於匯出、儲存繪製好的圖形。

  簡單的SVG標籤格式 <svg width="500" height="50"></svg>,在SVG標籤中可以嵌入很多可見元素,包括 rect、circle、ellipse、line、text和path。

  下面,我們在body中建立一個js標籤,在裡面建立一個svg對象,代碼如下:

<span style="font-size:14px;">var w = 500;var h = 500;var svg = d3.select("body")  .append("svg")  .attr("width", w)          //設定寬度  .attr("height", h);        //設定高度</span>
 
繪製圓

在svg內添加circle元素,先介紹下circle的基本屬性:cx 圓心x座標  cy圓心y座標   r半徑

接下來,繪製五個半徑依次增大的圓,並將它們的圓心放到同一條y軸上,代碼如下

<span style="font-size:14px;"> var dataset = [ 5, 10, 15, 20, 25 ]; var circles = svg.selectAll("circle")    .data(dataset)            .enter()    .append("circle");    circles.attr("cx", function(d, i) {//圓心座標從左向右依次遞增,注意:i表示引入資料在數組的下標,如:d=5,i=0        return (i * 50) + 25;    })    .attr("cy", h/2) //將圓心放到svg高度中間    .attr("r", function(d) {//半徑        return d;    })</span>

緊接著設定各圓的屬性

<span style="font-size:14px;">    .attr("fill", "yellow")         //給各圓填充黃色    .attr("stroke", "orange")       //給各圓邊塗成橘黃    .attr("stroke-width", function(d) { //按比例設定邊的厚度    return d/2;}); </span>

至此,SVG上的圓就繪製完成了見


繪製線

在svg繪製一條線,首先要定義它的兩個端點,起點和終點 (x1,y1)和(x2,y2)

線的基本屬性包括:

  • x1 屬性在 x 軸定義線條的開始
  • y1 屬性在 y 軸定義線條的開始
  • x2 屬性在 x 軸定義線條的結束
  • y2 屬性在 y 軸定義線條的結束

<span style="font-size:14px;">var line = svg.append('line')            .attr('x1',100)               .attr('y1',100)            .attr('x2',200)            .attr('y2',200)            .attr('style','stroke:rgb(99,99,99);stroke-width:2'); //描邊寬度</span>
顯示如下:



用力圖簡介

  有點有線,那麼有關聯的點用線相連,再設定下點之間的電荷排斥力,讓沒關聯的點保持距離, 那麼力圖的雛形就形成了。

  力學圖( Force ),也有被翻譯做力導向圖等。這種圖很有意思,先從初始資料開始,看下面代碼:

{  "nodes":[    {"name":"Myriel","group":3,"QQ":"635511111"},    {"name":"Napoleon","group":1,"QQ":"635511112"},    {"name":"Mlle.Baptistine","group":1,"QQ":"635511113"},    {"name":"Mme.Magloire","group":1,"QQ":"635511114"},    {"name":"CountessdeLo","group":1,"QQ":"635511115"},    {"name":"Geborand","group":1,"QQ":"635511116"},    {"name":"Champtercier","group":1,"QQ":"635511117"},    {"name":"Cravatte","group":1,"QQ":"635512111"},    {"name":"Count","group":1,"QQ":"635513111"},    {"name":"OldMan","group":1,"QQ":"635514111"},    {"name":"Labarre","group":2,"QQ":"635515111"},    {"name":"Valjean","group":2,"QQ":"635516111"},    {"name":"Marguerite","group":3,"QQ":"635531111"},    {"name":"Mme.deR","group":2,"QQ":"635511311"},    {"name":"Isabeau","group":2,"QQ":"635511211"},    {"name":"Gervais","group":2,"QQ":"635514111"},    {"name":"Tholomyes","group":3,"QQ":"635571111"},    {"name":"Listolier","group":3,"QQ":"635581111"},    {"name":"Fameuil","group":3,"QQ":"635511011"},    {"name":"Blacheville","group":3,"QQ":"635211111"},    {"name":"Favourite","group":3,"QQ":"635510111"},    {"name":"Dahlia","group":3,"QQ":"635511121"}  ],  "links":[    {"source":1,"target":0,"value":1},    {"source":2,"target":0,"value":8},    {"source":3,"target":0,"value":10},    {"source":3,"target":2,"value":6},    {"source":4,"target":0,"value":1},    {"source":5,"target":0,"value":1},    {"source":6,"target":0,"value":1},    {"source":7,"target":0,"value":1},    {"source":8,"target":0,"value":2},    {"source":9,"target":0,"value":1},    {"source":11,"target":1,"value":1},    {"source":11,"target":3,"value":3},    {"source":11,"target":2,"value":3},    {"source":11,"target":0,"value":5},    {"source":12,"target":2,"value":1},    {"source":13,"target":2,"value":1},    {"source":14,"target":2,"value":1},    {"source":15,"target":2,"value":1},    {"source":17,"target":3,"value":4},    {"source":18,"target":3,"value":4},    {"source":18,"target":3,"value":4},    {"source":19,"target":3,"value":4},    {"source":19,"target":2,"value":4},    {"source":19,"target":3,"value":4},    {"source":20,"target":4,"value":3},    {"source":20,"target":1,"value":3},    {"source":20,"target":2,"value":3},    {"source":20,"target":3,"value":4},    {"source":21,"target":16,"value":3},    {"source":21,"target":17,"value":3},    {"source":21,"target":18,"value":3},    {"source":21,"target":19,"value":3},    {"source":21,"target":20,"value":5}  ]}

這些資料包含兩部分,點(nodes)和邊(links),source 和target的數值代表nodes數組該數值下標對應的元素。

注意的一點,不管nodes元素有多少屬性,source和target都暫時指向人名,如source 1 target0 表示napoleon和myriel串連

細細一看就會發現,這些點只是些人員的屬性而已,光靠這些是無法知道每個點該畫到哪兒。

  所以就需要先瞭解一下D3 畫力圖的一些專有方法了 。下面為大家羅列一些必要的方法和解釋:

  為了使用方便先將上面的json資料,賦值給 dataset,放到js裡

(以後這些資料都會儲存在相應格式的檔案中,由d3載入,載入方法在 D3總體展示篇已略有介紹) 

var force = d3.layout.force()  //轉換資料的方法,將點轉換為座標格式.nodes(<span style="font-size:14px;">dataset.</span>nodes)          //傳入點.links(dataset.links)          //傳入邊.size([w, h])                  //設定圖形寬高.start();                      //開始轉換

以上代碼是 用力圖最基礎的布局方法。

這些基本布局並不能滿足所有資料集,我們還要在這基礎上添加一些layout的自訂方法,

 比如設定節點間連線的長度、節點間互斥力大小。完善之後的代碼顯示如下:

var force = d3.layout.force().nodes(dataset.nodes).links(dataset.edges).size([w, h]).linkDistance([50]) // 節點連線長度.charge([-100]) //    排斥力.start();
至此,力圖基本初始化布局完成

 接下來建立連線

var edges = svg.selectAll("line").data(dataset.edges).enter().append("line").style("stroke", "#ccc").style("stroke-width", 1);

這裡的連線顏色和寬度都可以編寫函數隨意設定,例如同類人員設為同色,重要人員連線加粗等

然後為每個節點建立圓,方便瀏覽

var nodes = svg.selectAll("circle").data(dataset.nodes).enter().append("circle").attr("r", 10).style("fill", function(d, i) {return colors(i);}).call(force.drag);    //增加拖動效果,拉動節點
 最後,我們就要打點,將點線繪製到畫布上

force.on("tick", function() {edges.attr("x1", function(d) { return d.source.x; })     .attr("y1", function(d) { return d.source.y; })     .attr("x2", function(d) { return d.target.x; })     .attr("y2", function(d) { return d.target.y; });nodes.attr("cx", function(d) { return d.x; })     .attr("cy", function(d) { return d.y; });});
這樣,每次打點,取得線和點的座標,在更新到畫布上。那麼這些座標哪兒來的?就是layout初始化轉換傳入的點線資料後,

 為他們類比一些座標資訊。你可以在瀏覽器控制台輸入dataset查看各點線座標資訊

  好了,最簡單的用力圖就這樣完成了,後文會繼續在此基礎上講解如何為個點設定表徵圖、如何?不同分組的群成員聚類縮放、如何顯示成員資訊、如何將圓替換為矩形塊放置屬性連絡方式等,敬請期待!





D3.js 以圓做點繪製力圖(一)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.