我请求您为我正在开发的工具提供帮助。 在全球范围内,我找到了我正在寻找的东西(https://jsfiddle.net/4xt5v51m/3/),但问题是它似乎与我的 D3.js 版本(7.8.5)不兼容。
我尝试将其转换为新版本,但我不能...我总是一个接一个地出现一个错误,我认为我的代码不再相关...
通常这样的问题应该被关闭(你需要展示你的工作/转换尝试),但因为我已经做了几次这个练习......这是你的开始:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.js"></script>
<style>
path.link {
fill: #ccc;
stroke: #333;
stroke-width: 1.5px;
}
circle {
fill: #ccc;
stroke: #333;
stroke-width: 1.5px;
}
text {
font: 10px sans-serif;
pointer-events: none;
}
text.shadow {
stroke: #fff;
stroke-width: 3px;
stroke-opacity: 0.8;
}
body {
background-color: white;
margin: 0px;
}
.graphContainer {
text-shadow: -1px -1px 0 white, 1px -1px 0 white, -1px 1px 0 white,
1px 1px 0 white;
}
</style>
</head>
<body>
<div class="graphContainer"></div>
<script>
var color = d3.scaleOrdinal(d3.schemeCategory10);
var data = {
nodes: [
{ id: 0, name: 'paper1', citation: 5, group: 1 },
{ id: 1, name: 'paper2', citation: 8, group: 2 },
{ id: 2, name: 'paper3', citation: 12, group: 3 },
{ id: 3, name: 'paper4', citation: 25, group: 4 },
{ id: 4, name: 'paper5', citation: 15, group: 5 },
{ id: 5, name: 'paper6', citation: 5, group: 1 },
{ id: 6, name: 'paper7', citation: 8, group: 2 },
{ id: 7, name: 'paper8', citation: 12, group: 3 },
{ id: 8, name: 'paper9', citation: 25, group: 4 },
{ id: 9, name: 'paper10', citation: 15, group: 5 },
],
links: [
{ source: 0, target: 1, name: 'A-B-1', value: 8, grouo: 1 },
{ source: 0, target: 1, name: 'A-B-2', value: 24, grouo: 2 },
{ source: 0, target: 2, name: 'A-C-1', value: 100, grouo: 1 },
{ source: 0, target: 2, name: 'A-C-3', value: 44, grouo: 2 },
{ source: 2, target: 3, name: 'A-D-1', value: 169, grouo: 1 },
{ source: 2, target: 3, name: 'A-D-2', value: 80, grouo: 2 },
{ source: 2, target: 4, name: 'A-E-1', value: 16, grouo: 1 },
{ source: 2, target: 4, name: 'A-E-5', value: 200, grouo: 2 },
{ source: 4, target: 5, name: 'A-B-1', value: 8, grouo: 1 },
{ source: 4, target: 5, name: 'A-B-2', value: 24, grouo: 2 },
{ source: 5, target: 6, name: 'A-C-1', value: 12, grouo: 1 },
{ source: 5, target: 6, name: 'A-C-3', value: 44, grouo: 2 },
{ source: 5, target: 7, name: 'A-D-1', value: 125, grouo: 1 },
{ source: 5, target: 7, name: 'A-D-2', value: 225, grouo: 2 },
{ source: 7, target: 8, name: 'A-E-1', value: 36, grouo: 1 },
{ source: 7, target: 8, name: 'A-E-5', value: 81, grouo: 2 },
{ source: 8, target: 3, name: 'A-C-1', value: 9, grouo: 1 },
{ source: 8, target: 3, name: 'A-C-3', value: 16, grouo: 2 },
{ source: 8, target: 9, name: 'A-D-1', value: 50, grouo: 1 },
{ source: 8, target: 9, name: 'A-D-2', value: 100, grouo: 2 },
],
};
// used to store the number of links between two nodes.
// mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex;
var mLinkNum = {};
// sort links first
sortLinks();
// set up linkIndex and linkNumer, because it may possible multiple links share the same source and target node
setLinkIndexAndNum();
var w = 960,
h = 500;
const force = d3
.forceSimulation(data.nodes)
.force(
'link',
d3
.forceLink(data.links)
.id((d) => d.id)
.distance(50)
)
.force('charge', d3.forceManyBody().strength(-1000))
.force('center', d3.forceCenter(w / 2, h / 2));
var svg = d3
.select('.graphContainer')
.append('svg:svg')
.attr('width', w)
.attr('height', h);
svg
.append('svg:defs')
.selectAll('marker')
.data(['end']) // Different link/path types can be defined here
.enter()
.append('svg:marker') // This section adds in the arrows
.attr('id', String)
.attr('viewBox', '0 -5 10 10')
.attr('refX', 15)
.attr('refY', 0.5)
.attr('markerWidth', 2)
.attr('markerHeight', 2)
.attr('orient', 'auto')
.append('svg:path')
.attr('d', 'M0,-5L10,0L0,5');
var path = svg
.append('svg:g')
.selectAll('line')
.data(data.links)
.enter()
.append('svg:path')
.attr('class', 'link')
.style('stroke-width', function (d) {
return Math.sqrt(d.value);
})
.style('stroke', function (d) {
return color(d.value);
})
.attr('marker-end', 'url(#end)');
var circle = svg
.append('svg:g')
.selectAll('circle')
.data(data.nodes)
.enter()
.append('svg:circle')
.attr('r', function (d) {
return d.citation;
})
.style('fill', function (d) {
return color(d.group);
});
var text = svg
.append('svg:g')
.selectAll('g')
.data(data.nodes)
.enter()
.append('svg:g');
// A copy of the text with a thick white stroke for legibility.
text
.append('svg:text')
.attr('x', 8)
.attr('y', '.31em')
.attr('class', 'shadow')
.text(function (d) {
return d.name;
});
text
.append('svg:text')
.attr('x', 8)
.attr('y', '.31em')
.text(function (d) {
return d.name;
});
force.on('tick', tick);
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr('d', function (d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
// get the total link numbers between source and target node
var lTotalLinkNum =
mLinkNum[d.source.id + ',' + d.target.id] ||
mLinkNum[d.target.id + ',' + d.source.id];
if (lTotalLinkNum > 1) {
// if there are multiple links between these two nodes, we need generate different dr for each path
dr = dr / (1 + (1 / lTotalLinkNum) * (d.linkindex - 1));
}
// generate svg path
return (
'M' +
d.source.x +
',' +
d.source.y +
'A' +
dr +
',' +
dr +
' 0 0 1,' +
d.target.x +
',' +
d.target.y +
'A' +
dr +
',' +
dr +
' 0 0 0,' +
d.source.x +
',' +
d.source.y
);
});
// Add tooltip to the connection path
path.append('svg:title').text(function (d, i) {
return d.name;
});
circle.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
text.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
}
circle.call(
d3
.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended)
);
// Reheat the simulation when drag starts, and fix the subject position.
function dragstarted(event) {
if (!event.active) force.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
// Update the subject (dragged node) position during drag.
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
// Restore the target alpha so the simulation cools after dragging ends.
// Unfix the subject position now that it’s no longer being dragged.
function dragended(event) {
if (!event.active) force.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}
// sort the links by source, then target
function sortLinks() {
data.links.sort(function (a, b) {
if (a.source > b.source) {
return 1;
} else if (a.source < b.source) {
return -1;
} else {
if (a.target > b.target) {
return 1;
}
if (a.target < b.target) {
return -1;
} else {
return 0;
}
}
});
}
//any links with duplicate source and target get an incremented 'linknum'
function setLinkIndexAndNum() {
for (var i = 0; i < data.links.length; i++) {
if (
i != 0 &&
data.links[i].source == data.links[i - 1].source &&
data.links[i].target == data.links[i - 1].target
) {
data.links[i].linkindex = data.links[i - 1].linkindex + 1;
} else {
data.links[i].linkindex = 1;
}
// save the total number of links between two nodes
if (
mLinkNum[data.links[i].target + ',' + data.links[i].source] !==
undefined
) {
mLinkNum[data.links[i].target + ',' + data.links[i].source] =
data.links[i].linkindex;
} else {
mLinkNum[data.links[i].source + ',' + data.links[i].target] =
data.links[i].linkindex;
}
}
}
</script>
</body>
</html>