D3.js繪製實時映射的縮略圖

在作可視化的不少時候,咱們須要在主圖的一角設置一個縮略圖來掌握全局狀況。本次將使用力導向圖做爲例子,完成縮略圖的實現。node

繪製的原理就是依靠主圖的數據再畫一個圖出來,無需再次計算,只改變圖形形態。app

最終效果

主圖節點拖動,縮略圖跟着變化。
http://en.jsrun.net/UyiKp/showsvg

代碼解析

數據

依然使用以前例子的力導向圖繪製數據及方法動畫

var nodes = [
  {value:"66666666",type:"home",index:"0"},
  {value:"11111111111",type:"phone",index:"1"},
  {value:"22222222222",type:"phone",index:"2"},
  {value:"33333333333",type:"phone",index:"3"},
  {value:"44444444444",type:"phone",index:"4"},
  {value:"55555555555",type:"phone",index:"5"},
  {value:"aaa",type:"weixin",index:"6"},
  {value:"bbb",type:"weixin",index:"7"},
  {value:"ccc",type:"weixin",index:"8"},
  {value:"ddd",type:"weixin",index:"9"},
  {value:"eee",type:"weixin",index:"10"},
  {value:"fff",type:"weixin",index:"11"},
];
var links = [
  {source:0,target:1},
  {source:0,target:2},
  {source:0,target:3},
  {source:0,target:4},
  {source:0,target:5},
  {source:2,target:6},
  {source:2,target:7},
  {source:2,target:8},
  {source:3,target:9},
  {source:3,target:10},
  {source:3,target:11},
]

力導向圖繪製

var height = 500;
var width = 500;
var svg = d3.select("#forceMap").append("svg")
                        .attr("width",width)
            .attr("height",height)
            .attr("id","forceSvg");
var mapG = svg.append("g")
.attr("id","forceGroup");

var force = d3.layout.force()
                    .nodes(nodes)
                    .links(links)
                    .size([width,height])
                    .linkDistance(100)
                    .charge([-1250])
                    .gravity(0.5)
                    .friction(0.5);
force.start();
var linkG = mapG.selectAll(".link")
.data(links)
.enter()
.append("line")
.attr("class","link")
.attr("stroke","#ccc");
var nodeG = mapG.selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class","node")
.attr("r",8)
.attr("fill",function(d){
  switch(d.type){
    case "home": return "red";break;
    case"phone": return "blue";break;
    case "weixin": return "green";break;
  }
})
 .call(force.drag); //這個例子爲節點添加了可拖動的功能


force.on("tick", function () {
                      linkG.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;
                    });


                nodeG.attr("cx", function (d) {
                    return d.x
                })
                .attr("cy", function(d){
                  return d.y
                });
   drawThumb(); //在tick最後,執行繪製縮略圖
});

此次代碼中添加了drag方法,爲了使節點可拖動。.net

繪製縮略圖

function drawThumb(){

//每次繪製前刪除以前的圖形(這是一種簡單有效的動畫理論,可是比較消耗資源,以後會介紹如何節省資源完成需求)
  d3.select("#thumbSvg").remove();
  
  var thumbSvg = d3.select("#thumbMap").append("svg")
            .attr("width",100)
            .attr("height",100)
            .attr("id","thumbSvg");
    var thumbG = thumbSvg.append("g")
    .attr("id","thumbGroup");
    var thumbLink = thumbG.selectAll(".tlink")
    .data(links)
    .enter()
    .append("line")
    .attr("class","tlink")
    .attr("stroke","#ccc")
    //縮略圖繪製和主圖的差別在這,不須要tick,只須要把節點的座標直接賦予便可
    .attr("x1", function (d) {
                        return d.source.x/5;//這裏的除5是縮略圖和主圖的比例,thumbWidth/forceWidth
                    })
                    .attr("y1", function (d) {
                        return d.source.y/5;
                    })
                    .attr("x2", function (d) {
                        return d.target.x/5;
                    })
                    .attr("y2", function (d) {
                        return d.target.y/5;
                    });
var thumbNode = thumbG.selectAll(".tnode")
.data(nodes)
.enter()
.append("circle")
.attr("class","tnode")
.attr("r",1.2)//圖形尺寸都要縮小
.attr("fill",function(d){
  switch(d.type){
    case "home": return "red";break;
    case"phone": return "blue";break;
    case "weixin": return "green";break;
  }
})
.attr("cx", function (d) {
                    return d.x/5
                })
                .attr("cy", function(d){
                  return d.y/5
                });
}

在繪製縮略圖時,我在最前面有一個remove方法,就是用新的圖形代替舊的圖形,完成縮略圖的動畫效果,模擬了tick。
但在實際使用中,數據量很大時,如此刪了畫畫了刪,很是耗資源。
因此更好的方法是判斷是否有thumbSvg,有的話就只改變node和link的x,y,沒有的話就按上面代碼同樣繪製。code

ok,縮略圖的繪製完成,很簡單的例子,按照這個思路能夠完成大部分可視化的縮略圖繪製。除了拖動外,還能夠添加縮放和平移功能,但注意縮放時全部尺寸的比例都會跟着變化,會複雜不少。ci

相關文章
相關標籤/搜索