Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 标签为d3.js的有界力图_Javascript_D3.js_Force Layout - Fatal编程技术网

Javascript 标签为d3.js的有界力图

Javascript 标签为d3.js的有界力图,javascript,d3.js,force-layout,Javascript,D3.js,Force Layout,我试图创建一个带标签的有界力图。是没有标签的有界力图的正式示例。一次,我添加了我需要使用不同的勾号函数的标签。当我使用适当的勾号函数时,圆节点确实停留在边界内,但是,如果拖动到边界之外,直线将继续移动,这与我链接的示例不同。下面是我的带标签的有界图的示例,但是如果拖动到边界之外,线仍然在移动(可以将整个图拖走,节点除外)。下面是代码。如果你能帮我找出如何保持线在边界内,并模仿我链接的示例的行为,那就太好了。谢谢 js var width = 280 height = 370 radius = 6

我试图创建一个带标签的有界力图。是没有标签的有界力图的正式示例。一次,我添加了我需要使用不同的勾号函数的标签。当我使用适当的勾号函数时,圆节点确实停留在边界内,但是,如果拖动到边界之外,直线将继续移动,这与我链接的示例不同。下面是我的带标签的有界图的示例,但是如果拖动到边界之外,线仍然在移动(可以将整个图拖走,节点除外)。下面是代码。如果你能帮我找出如何保持线在边界内,并模仿我链接的示例的行为,那就太好了。谢谢

js

var width = 280
height = 370
radius = 6;

var force = d3.layout.force()
    .nodes(d3.values(nodes))
    .links(links)
    .size([width, height])
    .linkDistance(50)
    .charge(-200)
    .on("tick", tick)
    .start();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var link = svg.selectAll(".link")
    .data(force.links())
    .enter().append("line")
    .attr("class", "link");

var node = svg.selectAll(".node")
    .data(force.nodes())
    .enter().append("g")
    .attr("class", "node")
    .on("mouseover", mouseover)
    .on("mouseout", mouseout)
    .on("click", click)
    .on("dblclick", dblclick)
    .call(force.drag);

node.append("circle")
    .attr("r", radius)
    .style("fill", "#C71585");

node.append("text")
    .attr("x", 14)
    .attr("dy", ".35em")
    .style("fill", "#333")
    .text(function (d) {
    return d.name;
});

function tick() {
    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;
    });

    var dx = function(d) {return Math.max(radius, Math.min(width - radius, d.x))}
    var dy = function(d) {return Math.max(radius, Math.min(width - radius, d.y))}

    node.attr("transform", function (d) {
        return "translate(" + dx(d) + "," + dy(d) + ")";
    });
}

function mouseover() {
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 16);
}

function mouseout() {
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 12);
}
// action to take on mouse click
function click() {
    d3.select(this).select("text").transition()
        .duration(750)
        .attr("x", 22)
        .style("stroke-width", ".5px")
        .style("opacity", 1)
        .style("fill", "#E34A33")
        .style("font", "17.5px serif");
    d3.select(this).select("circle").transition()
        .duration(750)
        .style("fill", "#E34A33")
        .attr("r", 16)
}

// action to take on mouse double click
function dblclick() {
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 12)
        .style("fill", "#E34A33");
    d3.select(this).select("text").transition()
        .duration(750)
        .attr("x", 14)
        .style("stroke", "none")
        .style("fill", "#E34A33")
        .style("stroke", "none")
        .style("opacity", 0.6)
        .style("font", "14px serif");
}
var链接=[{
“来源”:“分析”,
“目标”:“科学”
}, {
“来源”:“分析”,
“目标”:“软件”
}, {
“来源”:“分析”,
“目标”:“故事”
}, {
“资料来源”:“科学”,
“目标”:“数学”
}, {
“资料来源”:“科学”,
“目标”:“统计”
}, {
“来源”:“软件”,
“目标”:“R”
}, {
“来源”:“软件”,
“目标”:“SAS”
}, {
“来源”:“软件”,
“目标”:“其他”
}, {
“来源”:“故事”,
“目标”:“业务沟通”
}, {
“来源”:“故事”,
“目标”:“可视化”
}];
变量节点={}
//从链接计算不同的节点。
links.forEach(函数(link){
link.source=节点[link.source]| |(节点[link.source]={
名称:link.source
});
link.target=节点[link.target]| |(节点[link.target]={
名称:link.target
});
link.value=+link.value;
});
可变宽度=280
高度=370
半径=6;
var-force=d3.layout.force()
.节点(d3.值(节点))
.链接(links)
.尺寸([宽度、高度])
.linkDistance(50)
。收费(-200)
.on(“滴答”,滴答)
.start();
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
var link=svg.selectAll(“.link”)
.data(force.links())
.enter().append(“行”)
.attr(“类”、“链接”);
var node=svg.selectAll(“.node”)
.data(force.nodes())
.enter().append(“g”)
.attr(“类”、“节点”)
.on(“鼠标悬停”,鼠标悬停)
.on(“mouseout”,mouseout)
.on(“单击”,单击)
.on(“dblclick”,dblclick)
.呼叫(强制拖动);
node.append(“圆”)
.attr(“r”,半径)
.样式(“填充”、“C71585”);
node.append(“文本”)
.attr(“x”,14)
.attr(“dy”,“.35em”)
.样式(“填充”、“#333”)
.文本(功能(d){
返回d.name;
});
函数tick(){
link.attr(“x1”,函数(d){
返回d.source.x;
})
.attr(“y1”,函数(d){
返回d.source.y;
})
.attr(“x2”,函数(d){
返回d.target.x;
})
.attr(“y2”,功能(d){
返回d.target.y;
});
var dx=函数(d){
返回Math.max(半径,Math.min(宽度-半径,d.x))
}
var dy=函数(d){
返回Math.max(半径,Math.min(宽度-半径,d.y))
}
node.attr(“转换”,函数(d){
返回“translate”(“+dx(d)+”,“+dy(d)+”);
});
}
函数mouseover(){
d3.选择(这个)。选择(“圆”)。过渡()
.持续时间(750)
.attr(“r”,16);
}
函数mouseout(){
d3.选择(这个)。选择(“圆”)。过渡()
.持续时间(750)
.attr(“r”,12);
}
//鼠标单击时要执行的操作
函数单击(){
d3.选择(这个).select(“文本”).transition()
.持续时间(750)
.attr(“x”,22)
.style(“笔划宽度”,“0.5px”)
.style(“不透明度”,1)
.样式(“填充”、“E34A33”)
.style(“字体”、“17.5px衬线”);
d3.选择(这个)。选择(“圆”)。过渡()
.持续时间(750)
.样式(“填充”、“E34A33”)
.attr(“r”,16)
}
//鼠标双击时要执行的操作
函数dblclick(){
d3.选择(这个)。选择(“圆”)。过渡()
.持续时间(750)
.attr(“r”,12)
.样式(“填充”、“E34A33”);
d3.选择(这个).select(“文本”).transition()
.持续时间(750)
.attr(“x”,14)
.style(“笔划”、“无”)
.样式(“填充”、“E34A33”)
.style(“笔划”、“无”)
.样式(“不透明度”,0.6)
.style(“字体”、“14px衬线”);
}
.link{
行程:#666;
不透明度:0.6;
笔划宽度:1.5px;
}
.节点圆{
冲程:#fff;
不透明度:0.6;
笔划宽度:1.5px;
}
正文{
字体:15px衬线;
不透明度:0.6;
指针事件:无;
}

如果要为拖动创建边界,则可以重新定义拖动方法而不是勾号

创建新的拖动:

var drag = force.drag()
  .on("drag", dragmove);
使用此拖动节点

并在新的dragmove方法中对节点的x、y坐标进行约束:

function dragmove(d) {
    var dx = function(d) {return Math.max(radius, Math.min(width - radius, d.x))}
    var dy = function(d) {return Math.max(radius, Math.min(width - radius, d.y))}
    d.px = Math.min(d3.event.x,200);
    d.py = Math.min(d3.event.y, 200);
    d.x = Math.min(d3.event.x, 200);
    d.y = Math.min(d3.event.y, 200);
}
您可以在这里查看:

勾号功能需要稍作更改。使用节点变换函数内计算的有界值更新d.x和d.y位置,然后更新链接位置属性

我已经更改了svg的背景色,以便清楚地看到边界效果

var链接=[{
“来源”:“分析”,
“目标”:“科学”
}, {
“来源”:“分析”,
“目标”:“软件”
}, {
“来源”:“分析”,
“目标”:“故事”
}, {
“资料来源”:“科学”,
“目标”:“数学”
}, {
“资料来源”:“科学”,
“目标”:“统计”
}, {
“来源”:“软件”,
“目标”:“R”
}, {
“来源”:“软件”,
“目标”:“SAS”
}, {
“来源”:“软件”,
“目标”:“其他”
}, {
“来源”:“故事”,
“目标”:“业务沟通”
}, {
“来源”:“故事”,
“目标”:“可视化”
}];
变量节点={}
//从链接计算不同的节点。
links.forEach(函数(link){
link.source=节点[link.source]| |(节点[link.source]={
名称:link.source
});
link.target=节点[link.target]| |(节点[link.target]={
名称:link.target
});
link.value=+link.value;
});
可变宽度=280
高度=370
半径=6;
var-force=d3.layout.force()
.节点(d3.值(节点))
.链接(links)
.尺寸([宽度、高度])
.linkDistance(50)
。收费(-200)
.on(“滴答”,滴答)
.start();
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,