gpt4 book ai didi

javascript - 更改 d3 力布局使用的数据

转载 作者:行者123 更新时间:2023-12-03 04:44:53 24 4
gpt4 key购买 nike

我正在尝试 Christopher Manning's 3D force layout 的实现

Here是我正在编辑的 JSFiddle 的链接。我的目标是创建一个三维布局,其中节点和链接是根据外部数据创建的。我的问题是,我从哪里开始将此布局转换为从外部文件获取数据的布局?目前节点已创建:

for(x=0;x<200;x++) {
source = nodes[~~(Math.random() * nodes.length)]
target = {id: 'label-'+x, x: source.x + Math.random(), y: source.y + Math.random(), group: Math.random()}
links.push({source: source, target: target})
nodes.push(target)

我已经创建了以这种方式设置的力导向布局,但是一旦引入第三个维度,我就会陷入困境。这尤其困难,因为我必须改变很多区域才能获得所需的结果。到目前为止我所尝试的一切都导致项目失败。我仍在学习 d3,所以任何输入都会有帮助。谢谢!

最佳答案

我很犹豫是否要回答这个问题,因为你没有问任何具体的问题。但这里是对链接代码的快速重构,该代码从 JSON API 从外部读取数据。我确实没有在代码中看到任何使数据与传统的力布局不同的内容。像这样的事情:

{
"nodes": [{
"x": 100,
"y": 100,
"group": 0.5
},{
"x": 200,
"y": 200,
"group": 0.2
},{
"x": 300,
"y": 300,
"group": 0.6
},{
"x": 400,
"y": 400,
"group": 0.1
},{
"x": 500,
"y": 500,
"group": 0.7
}],
"links": [{
"source": 0,
"target": 1
},{
"source": 1,
"target": 2
},{
"source": 2,
"target": 3
},{
"source": 3,
"target": 4
}]
}

其他更改只是为了修复变量范围,因为 nodelink 是在 d3.json 回调中创建的:

<!DOCTYPE html>
<html>

<head>
<title>Spherical Force-Directed Layout</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<!--<script src="/js/d3.v3.min.js"></script>-->
<!--<script src="/js/dat-gui/build/dat.gui.js"></script> -->
<style type="text/css">
body {
padding: 0;
margin: 0;
}

path.node {
stroke-width: 1.5px;
}

path.link {
stroke: #999;
fill-opacity: 0
}
</style>
</head>

<body>
<script type="text/javascript">
var projections = {
"Albers": d3.geo.albers(),
"Azimuthal Equal Area": d3.geo.azimuthalEqualArea(),
"Azimuthal Eqidistant": d3.geo.azimuthalEquidistant(),
"Conic Conformal": d3.geo.conicConformal(),
"Conic Equal Area": d3.geo.conicEqualArea(),
"Conic Equidistant": d3.geo.conicEquidistant(),
"Eqirectangular": d3.geo.equirectangular(),
"Gnomonic": d3.geo.gnomonic(),
"Mercator": d3.geo.mercator(),
"Orthographic": d3.geo.orthographic(),
"Stereographic": d3.geo.stereographic(),
"Transverse Mercator": d3.geo.transverseMercator(),
};
var config = {
"projection": "Orthographic",
"clip": true,
"friction": .9,
"linkStrength": 1,
"linkDistance": 20,
"charge": 30,
"gravity": .1,
"theta": .8
};
var gui = new dat.GUI();
//var projectionChanger = gui.add(config, "projection", ['equalarea', 'equidistant', 'gnomonic', 'orthographic', 'stereographic', 'rectangular']);
var projectionChanger = gui.add(config, "projection", Object.keys(projections));
//http://stackoverflow.com/a/3417242
function wrapIndex(i, i_max) {
return ((i % i_max) + i_max) % i_max;
}
projectionChanger.onChange(function(value) {
projection = projections[value]
.scale(height / 2)
.translate([(width / 2) - 125, height / 2])
.clipAngle(config["clip"] ? 90 : null)

path.projection(projections[value])
return
if (value == 'rectangular') {
path = d3.geo.path().projection(function(coordinates) {
console.log(coordinates[0], coordinates[1])
return [
wrapIndex(coordinates[0], width),
wrapIndex(coordinates[1], height),
];
});
config['clip'] = false
} else {
projection.mode(value)
path = d3.geo.path().projection(projection)
}

force.start()
});

var clipChanger = gui.add(config, "clip").listen();
clipChanger.onChange(function(value) {
projection.clipAngle(value ? 90 : null)
force.start()
});

var fl = gui.addFolder('Force Layout');
fl.open()

var frictionChanger = fl.add(config, "friction", 0, 1);
frictionChanger.onChange(function(value) {
force.friction(value)
force.start()
});

var linkDistanceChanger = fl.add(config, "linkDistance", 0, 400);
linkDistanceChanger.onChange(function(value) {
force.linkDistance(value)
force.start()
});

var linkStrengthChanger = fl.add(config, "linkStrength", 0, 1);
linkStrengthChanger.onChange(function(value) {
force.linkStrength(value)
force.start()
});

var chargeChanger = fl.add(config, "charge", 0, 500);
chargeChanger.onChange(function(value) {
force.charge(-value)
force.start()
});

var gravityChanger = fl.add(config, "gravity", 0, 1);
gravityChanger.onChange(function(value) {
force.gravity(value)
force.start()
});

var thetaChanger = fl.add(config, "theta", 0, 1);
thetaChanger.onChange(function(value) {
force.theta(value)
force.start()
});

var width = window.innerWidth,
height = window.innerHeight - 5,
fill = d3.scale.category20(),
nodes = [{
x: width / 2,
y: height / 2
}],
links = [];

var projection = projections[config["projection"]]
.scale(height / 2)
.translate([(width / 2) - 125, height / 2])
.clipAngle(config["clip"] ? 90 : null)

var path = d3.geo.path()
.projection(projection)

var force = d3.layout.force()
.linkDistance(config["linkDistance"])
.linkStrength(config["linkStrength"])
.gravity(config["gravity"])
.size([width, height])
.charge(-config["charge"]);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.drag()
.origin(function() {
var r = projection.rotate();
return {
x: 2 * r[0],
y: -2 * r[1]
};
})
.on("drag", function() {
force.start();
var r = [d3.event.x / 2, -d3.event.y / 2, projection.rotate()[2]];
t0 = Date.now();
origin = r;
projection.rotate(r);
}))


var node, link;
d3.json('https://jsonblob.com/api/547d877a-0e4e-11e7-a0ba-f11a5a82ba29', function(e, data) {
if (e) console.warn(e);

link = svg.selectAll("path.link")
.data(data.links)
.enter().append("path").attr("class", "link")

node = svg.selectAll("path.node")
.data(data.nodes)
.enter().append("path").attr("class", "node")
.style("fill", function(d) {
return fill(d.group);
})
.style("stroke", function(d) {
return d3.rgb(fill(d.group)).darker();
})
.call(force.drag);

force
.nodes(data.nodes)
.links(data.links)
.on("tick", tick)
.start();

});

function tick() {

node.attr("d", function(d) {
var p = path({
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [d.x, d.y]
}
});
return p ? p : 'M 0 0'
});
link.attr("d", function(d) {
var p = path({
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[d.source.x, d.source.y],
[d.target.x, d.target.y]
]
}
});
return p ? p : 'M 0 0'
});
}
</script>
</body>

</html>

关于javascript - 更改 d3 力布局使用的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42912631/

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