gpt4 book ai didi

javascript - 如何使 D3 强制布局中的标签和节点可点击以导航到 URL?

转载 作者:搜寻专家 更新时间:2023-11-01 04:57:19 25 4
gpt4 key购买 nike

我正在使用 D3 使用基于力的布局,想知道是否有可能当我单击节点或标签时,我会自动转到存储在该节点/标签中的 url?如果是,我怎样才能做到这一点?

enter image description here

这是图表的实际外观(标签表示 URL 本身)

enter image description here

我正在分享我用来生成 D3 图表的 javascript 代码。在代码中,我目前使用的是虚拟数据,它们实际上将被 URL 替换。

document.addEventListener('DOMContentLoaded', function () {
drawVisual();
});

function drawVisual()
{
//document.getElementById('myMSG').innerHTML = "last name"+localStorage.lastname;
/*var getArr = [];
getArr = JSON.parse(localStorage.getItem('storeArray'));
document.getElementById('myMSG').innerHTML = getArr[1].parentURL;*/


//var w = 1024, h = 768;

var w=window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;

var h=window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
//var w = 1024, h = 768;

//var vis = d3.select("#tab_5_contents").append("svg:svg").attr("width", w).attr("height", h);
var vis = d3.select("#forcedLayoutGraph").append("svg:svg").attr("width", w).attr("height", h);

var QueuedORG = [];
//QueuedORG = JSON.parse(localStorage.getItem('storeArray'));
QueuedORG.push({url: "Root", parentURL: "Root", used:0});
QueuedORG.push({url: "a", parentURL: "Root", used:0});
QueuedORG.push({url: "b", parentURL: "Root", used:0});
QueuedORG.push({url: "c", parentURL: "Root", used:0});
QueuedORG.push({url: "d", parentURL: "Root", used:0});
QueuedORG.push({url: "e", parentURL: "a", used:0});
QueuedORG.push({url: "f", parentURL: "a", used:0});
QueuedORG.push({url: "g", parentURL: "a", used:0});
QueuedORG.push({url: "h", parentURL: "a", used:0});
QueuedORG.push({url: "p", parentURL: "b", used:0});
QueuedORG.push({url: "q", parentURL: "b", used:0});
QueuedORG.push({url: "r", parentURL: "b", used:0});
QueuedORG.push({url: "x", parentURL: "c", used:0});
QueuedORG.push({url: "y", parentURL: "x", used:0});
QueuedORG.push({url: "y", parentURL: "c", used:0});
QueuedORG.push({url: "x", parentURL: "a"});
QueuedORG.push({url: "y", parentURL: "b"});


var nodes = [];

var labelAnchors = [];
var labelAnchorLinks = [];
var links = [];

for(var i = 0; i < QueuedORG.length; i++)
{
var nodeExists = 0;

//check to see if a node for the current url has already been created. If yes, do not create a new node
for(var j = 0; j < nodes.length; j++)
{
if(QueuedORG[i].url == nodes[j].label)
nodeExists = 1;

}

if (nodeExists == 0)
{
var urlLabel = QueuedORG[i].url;
//remove 'http://' part
/*urlLabel = urlLabel.split("http://")[1];
if(urlLabel.match("www"))
urlLabel = urlLabel.split("www.")[1];
var rest = urlLabel.split("\.")[1];
urlLabel = urlLabel.split("\.")[0];*/

var node = {
label : QueuedORG[i].url,
category : QueuedORG[i].category
};
nodes.push(node);
labelAnchors.push({
node : node
});
labelAnchors.push({
node : node
});
}
};

for(var i=0;i<nodes.length; i++)
{
console.log("node i:"+i+nodes[i]+"\n");
console.log("labelAnchor i:"+i+labelAnchors[i]+"\n");
}

//To create links for connecting nodes
for(var i = 0; i < QueuedORG.length; i++)
{
var srcIndx = 0, tgtIndx = 0;
for(var j = 0; j < nodes.length; j++)
{
if( QueuedORG[i].url == nodes[j].label ) //to find the node number for the current url
{
srcIndx = j;
}

if( QueuedORG[i].parentURL == nodes[j].label ) //to find the node number for the parent url
{
tgtIndx = j;
}
}
//console.log("src:"+srcIndx+" tgt:"+tgtIndx);

//connecting the current url's node to the parent url's node
links.push({
source : srcIndx,
target : tgtIndx,
weight : 1,
});

labelAnchorLinks.push({
source : srcIndx * 2,
target : srcIndx * 2 + 1,
weight : 1
});
};

var force = d3.layout.force().size([w, h]).nodes(nodes).links(links).gravity(1).charge(-10000).linkStrength(function(x) {
return x.weight * 10 // charge is for inter-node repel, link distance is node-node distance
});
force.linkDistance(function(d) {
return d.weight * 100;
});

force.start();

var force2 = d3.layout.force().nodes(labelAnchors).links(labelAnchorLinks).gravity(0).linkStrength(10).charge(-500).size([w, h]); //charge is for inter-label repel, link distance is node-label distance
force2.linkDistance(function(d) {
return d.weight * 10;
});

force2.start();

var link = vis.selectAll("line.link").data(links).enter().append("svg:line").attr("class", "link").style("stroke", "#CCC");

var colors = {"1": "black", "2": "blue", "3": "red"}; // 1=root node 2=blog nodes 3=.org nodes
var shape = {"1": "diamond", "2": "cross", "3": "circle"};

var node = vis.selectAll("g.node").data(force.nodes()).enter().append("path").attr("class", "node").call(force.drag);
//node.append("circle").attr("r", 5).style("stroke", "#FFF").style("stroke-width", 3).attr("class", function(d) {return "node category"+d.category});

node.attr("d", d3.svg.symbol().type(function(d) {return shape[d.category];})).style("stroke", "#FFF").style("fill", function(d){ return colors[d.category];});

var anchorLink = vis.selectAll("line.anchorLink").data(labelAnchorLinks)//.enter().append("svg:line").attr("class", "anchorLink").style("stroke", "#999");

var anchorNode = vis.selectAll("g.anchorNode").data(force2.nodes()).enter().append("svg:g").attr("class", "anchorNode");
anchorNode.append("svg:circle").attr("r", 0).style("fill", "#FFF");
anchorNode.append("svg:text").text(function(d, i) {
return i % 2 == 0 ? "" : d.node.label
}).style("fill", "#555").style("font-family", "Arial").style("font-size", 12);

var updateLink = function() {
this.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 updateNode = function() {
this.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});

}

force.on("tick", function() {

force2.start();

node.call(updateNode);

anchorNode.each(function(d, i) {
if(i % 2 == 0) {
d.x = d.node.x;
d.y = d.node.y;
} else {
var b = this.childNodes[1].getBBox();

var diffX = d.x - d.node.x;
var diffY = d.y - d.node.y;

var dist = Math.sqrt(diffX * diffX + diffY * diffY);

var shiftX = b.width * (diffX - dist) / (dist * 2);
shiftX = Math.max(-b.width, Math.min(0, shiftX));
var shiftY = 5;
this.childNodes[1].setAttribute("transform", "translate(" + shiftX + "," + shiftY + ")");
}
});

anchorNode.call(updateNode);

link.call(updateLink);
anchorLink.call(updateLink);

});
}

最佳答案

一般来说,你可以在D3.js中给SVG元素添加点击事件,使用

.on('click', function(d, i) {
window.location.href = d.url;
})

d 是数据对象,i 在集合中 d 的索引中。

只需将该点击处理程序添加到您的文本节点以及您的节点(路径)节点,就像在这个 fiddle 中一样 http://jsfiddle.net/jNyrf/

关于javascript - 如何使 D3 强制布局中的标签和节点可点击以导航到 URL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20575026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com