D3.js D3强制布局缩放和平移不工作
我刚开始学习D3的强制布局,并通过参考以下内容实现了一个径向图实现: 我面临的问题是缩放不起作用。下面是我提到的代码:用于缩放功能 这是我的代码:D3.js D3强制布局缩放和平移不工作,d3.js,zooming,force-layout,D3.js,Zooming,Force Layout,我刚开始学习D3的强制布局,并通过参考以下内容实现了一个径向图实现: 我面临的问题是缩放不起作用。下面是我提到的代码:用于缩放功能 这是我的代码: var w = $("#network-plot").width(), h = 800, r = 6, fill = d3.scale.category20(); var payload={js:'mis1'} $.ajax({ url: "/getSource",
var w = $("#network-plot").width(),
h = 800,
r = 6,
fill = d3.scale.category20();
var payload={js:'mis1'}
$.ajax({
url: "/getSource",
type: "post",
async: false,
data: payload,
success: function (data) {
mis1=JSON.parse(data);
},
});
var force = d3.layout.force()
.charge(-30)
.linkDistance(310)
.size([w, h]);
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
var svgnt = d3.select("#network-plot-svg")
.attr("width", w)
.attr("height", h)
.style('margin-top', h/15)
.call(zoom);
var vis = svgnt.append("svg:g");
var rect = vis.append("svg:rect")
.attr("width", w)
.attr("height", h)
.attr("fill", '#fff')
.style("pointer-events", "all");
function zoomed() {
vis.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
var radius = d3.scale.log();
var mis1;
//**********RADIAL CODE****************
var unsortednodes = {};
var sortednodes = [];
var sortagainst = [];
var heaviest_node_length = 0;
for(var i = 0; i < mis1.nodes.length; i++) {
var count_conn = 0;
var heaviest_node;
for(var j = 0; j < mis1.links.length; j++) {
if(mis1.links[j].source == mis1.nodes[i].group || mis1.links[j].target == mis1.nodes[i].group) {
count_conn++;
}
}
if(count_conn > heaviest_node_length) {
heaviest_node_length = count_conn;
heaviest_node = i;
}
unsortednodes[i] = 10 + count_conn;
sortagainst[i] = 10 + count_conn;
}
sortagainst.sort();
sortagainst.reverse();
for(i in unsortednodes) {
var index = sortagainst.indexOf(unsortednodes[i]);
sortednodes[index] = i;
sortagainst[index] = '';
}
var c = {"x":w/2, "y":h/2};
var negativeY = 0;
var positiveY = 0;
var negativeX = 0;
var positiveX = 0;
var groupcenters = radialPlacement(c, 300, 18, sortednodes);
//following lines for readjustment code in case svg container is outgrown by graph
h = Math.abs(negativeY) + Math.abs(positiveY) + 100; //TBD: extra padding needs to be dynamic
w = Math.abs(negativeX) + Math.abs(positiveX) + 200;
c = {"x":w/2, "y":h/2};
groupcenters = radialPlacement(c, 300, 18, sortednodes);
svgnt.attr("height", h);
vis.attr("height", h);
svgnt.attr("width", w);
vis.attr("width", w);
function radialLocation(center, angle, radius) {
x = (center.x + radius * Math.cos(angle * Math.PI / 180));
y = (center.y + radius * Math.sin(angle * Math.PI / 180));
if(y < negativeY) {
negativeY = y;
}
if(y > positiveY) {
positiveY = y;
}
if(x < negativeX) {
negativeX = x;
}
if(x > positiveX) {
positiveX = x;
}
return {"x":x,"y":y};
}
function radialPlacement(center, radius, increment, keys) {
var values_circle = {};
var increment;
var start = -90;
var current = start;
var total_nodes = keys.length;
var circles = Math.floor(Math.sqrt((total_nodes - 1)/5));
if(circles == 0) {
circles = 1;
}
var ratio;
var r = [];
var circleKeys = [];
var radius = 140;
r[0] = radius;
var sum_r = r[0];
for(var j = 1; j < circles; j++){
r[j] = r[j-1] + 100 //TBD: should radius be linearly incremented like this?
sum_r += r[j];
}
ratio = 1/sum_r;
var temp = 0;
for(j = 0; j < circles; j++) {
if(j == circles - 1)
circleKeys[j] = total_nodes - temp;
else {
circleKeys[j] = Math.floor(total_nodes * r[j] * ratio);
temp += circleKeys[j];
}
}
var k = 0;
for(var i = 0; i < circleKeys.length; i++) {
increment = 360/circleKeys[i];
for(j = 0; j < circleKeys[i]; j++, k++) {
if(k == 0) {
values_circle[keys[k]] = radialLocation(center, -90, 0);
}
else {
values_circle[keys[k]] = radialLocation(center, current, r[i]);;
current += increment;
}
}
}
return values_circle;
}
//************RADIAL CODE ENDS***************
d3.json(mis1, function() {
var link = svgnt.selectAll("line")
.data(mis1.links)
.enter()
.append("svg:line")
.style("stroke","#ddd");
var node = svgnt.selectAll("circle")
.data(mis1.nodes)
.enter()
.append("svg:circle")
.attr("r", function(d, j){
var count = 0;
for(var i=0; i<mis1.links.length; i++) {
if(mis1.links[i].source == d.group || mis1.links[i].target == d.group){
count ++;
}
}
return (10+count);
})
.style("fill", function(d) {
return fill(d.group);
})
.on("mouseover", fade(.1))
.on("mouseout", fade(1));
texts = svgnt.selectAll("text.label")
.data(mis1.nodes)
.enter().append("text")
.attr("class", "label")
.attr("fill", "black")
.text(function(d) { return d.name; });
force.nodes(mis1.nodes).links(mis1.links).on("tick", tick).start();
var linkedByIndex = {};
mis1.links.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
function isConnected(a, b) {
return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index;
}
function tick() {
node.attr("cx", function(d, i) {
return d.x = groupcenters[i].x;
}).attr("cy", function(d, i) {
return d.y = groupcenters[i].y;
});
link.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;
});
texts.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
var w=$(“#网络图”).width(),
h=800,
r=6,
fill=d3.scale.category20();
var有效负载={js:'mis1'}
$.ajax({
url:“/getSource”,
类型:“post”,
async:false,
数据:有效载荷,
成功:功能(数据){
mis1=JSON.parse(数据);
},
});
var-force=d3.layout.force()
。收费(-30)
.linkDistance(310)
.尺寸([w,h]);
var zoom=d3.behavior.zoom()
.scaleExtent([1,10])
。打开(“缩放”,缩放);
var svgnt=d3。选择(“网络图svg”)
.attr(“宽度”,w)
.attr(“高度”,h)
.样式(页边距顶部,h/15)
.呼叫(缩放);
var vis=svgnt.append(“svg:g”);
var rect=vis.append(“svg:rect”)
.attr(“宽度”,w)
.attr(“高度”,h)
.attr(“填充”,“fff”)
.style(“指针事件”、“全部”);
函数缩放(){
vis.attr(“transform”、“translate”(+d3.event.translate+))比例(+d3.event.scale+);
}
var radius=d3.scale.log();
var-mis1;
//**********径向码****************
var unsortednodes={};
var sortednodes=[];
var sortagainst=[];
var最重节点长度=0;
对于(var i=0;i最重节点长度){
最重节点长度=计数连接;
最重节点=i;
}
未排序节点[i]=10+计数连接;
sortagainst[i]=10+计数连接;
}
sortagainst.sort();
sortagainst.reverse();
对于(未排序节点中的i){
var指数=sortagainst.indexOf(未排序节点[i]);
分类节点[索引]=i;
sortagainst[索引]='';
}
var c={“x”:w/2,“y”:h/2};
var negativeY=0;
var正值=0;
var negativeX=0;
var正值=0;
变量组中心=辐射位置(c、300、18、分类节点);
//在svg容器因图形而无法使用的情况下,以下行用于重新调整代码
h=数学abs(否定)+数学abs(肯定)+100//待定:额外的填充需要是动态的
w=Math.abs(negativeex)+Math.abs(positiveex)+200;
c={“x”:w/2,“y”:h/2};
分组中心=径向位置(c、300、18、分类节点);
svgnt.attr(“高度”,h);
相对属性(“高度”,h);
svgnt.attr(“宽度”,w);
视觉属性(“宽度”,w);
功能半径分配(中心、角度、半径){
x=(中心x+半径*Math.cos(角度*Math.PI/180));
y=(中心y+半径*数学正弦(角度*数学PI/180));
if(y正y){
正y=y;
}
if(xpositiveX){
阳性x=x;
}
返回{“x”:x,“y”:y};
}
功能半径位置(中心、半径、增量、关键点){
var值_圆={};
var增量;
var start=-90;
无功电流=启动;
var total_nodes=keys.length;
变量圆=数学地板(数学sqrt((总节点数-1)/5));
如果(圆==0){
圆圈=1;
}
var比率;
var r=[];
var circleKeys=[];
var半径=140;
r[0]=半径;
var sum_r=r[0];
对于(var j=1;j<圆;j++){
r[j]=r[j-1]+100//TBD:半径应该像这样线性增加吗?
和r+=r[j];
}
比率=1/总和;
var-temp=0;
对于(j=0;j<圆;j++){
如果(j==圆-1)
circleKeys[j]=总节点数-温度;
否则{
circleKeys[j]=数学楼层(总节点数*r[j]*比率);
温度+=循环键[j];
}
}
var k=0;
对于(var i=0;i 对于(var i=0;i而言,问题是,您正在添加
var link = svgnt.selectAll("line")
.data(mis1.links)
.enter()
.append("svg:line")
.style("stroke","#ddd");
var node = svgnt.selectAll("circle")
.data(mis1.nodes)
.enter()
.append("svg:circle")
----------------------
----------------------
----------------------
var link = vis.selectAll("line")
.data(mis1.links)
.enter()
.append("svg:line")
.style("stroke","#ddd");
var node = vis.selectAll("circle")
.data(mis1.nodes)
.enter()
.append("svg:circle")
----------------------
----------------------
----------------------