我需要设置一些圆的半径,我有以下数据,由链接和节点组成。我需要将圆(节点)的半径设置为连接到节点的链接的总和
var data = {
"nodes": [
{
"id": "s1",
"val": 12
},
{
"id": "s2",
"val": 12
},
{
"id": "s3",
"val": 12
},
{
"id": "s4",
"val": 12
},
{
"id": "s5",
"val": 12
},
{
"id": "s6",
"val": 12
}
],
"Links": [
{
"n1": "s1",
"n2": "s2",
"amount": 10
},
{
"n1": "s2",
"n2": "s3",
"amount": 10
},
{
"n1": "s2",
"n2": "s4",
"amount": 10
},
{
"n1": "s2",
"n2": "s6",
"amount": 10
},
{
"n1": "s3",
"n2": "s1",
"amount": 10
},
{
"n1": "s4",
"n2": "s5",
"amount": 10
},
{
"n1": "s5",
"n2": "s6",
"amount": 10
}
]
};
即(我希望节点此时处于上下文中),我在下面编写了一些伪代码
val1 = 0
val2 = 0
for i to len.links
if (links.node1 = nodes.id)
val1 = val1 + links.amount
else if (links.node02 = nodes.id)
val2 = val2 + links.amount
next
sum = val1 + val2
下面的代码将圆圈显示在屏幕上,我尝试了各种方法,但是可以缓解我所说的死亡白屏
var w = 1200;
var h = 800;
var svg = d3.select("body").append("svg").attr("width",w).attr("height", h);
var lines = svg.attr("class", "line")
d3.json("data.json", function(error, data) {
console.log(data);
var circles = svg.selectAll("foo")
.data(data.nodes)
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", 20); // <- i want to put this calculation here
我是JS新手,不知道如何将其转换为Javascript
答案 0 :(得分:1)
由于d3可能会造成混淆,而js本身...还是很不错,我觉得这样花很长时间才能解释而不输入它。我在jsbin中一起破解了这个,并添加了一些注释。您应该能够逐行跟踪并找出发生了什么情况。如果您不了解或未发表评论,请使用Google语法,我会尽力帮助您进行推理。
jsbin并附有示例
const data = {
"nodes": [
{
"id": "s1",
"val": 12
},
{
"id": "s2",
"val": 12
},
{
"id": "s3",
"val": 12
},
{
"id": "s4",
"val": 12
},
{
"id": "s5",
"val": 12
},
{
"id": "s6",
"val": 12
}
],
"links": [
{
"n1": "s1",
"n2": "s2",
"amount": 10
},
{
"n1": "s2",
"n2": "s3",
"amount": 10
},
{
"n1": "s2",
"n2": "s4",
"amount": 10
},
{
"n1": "s2",
"n2": "s6",
"amount": 10
},
{
"n1": "s3",
"n2": "s1",
"amount": 10
},
{
"n1": "s4",
"n2": "s5",
"amount": 10
},
{
"n1": "s5",
"n2": "s6",
"amount": 10
}
]
};
const width = window.innerWidth;
const height = window.innerHeight;
//set up the svg container
const svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background-color', 'lightgray'); // just to see the outline
//update our data to have referable x, y positions for each node
data.nodes.forEach(n => {
n.x = Math.random()*width; //since I don't know how you want them arranged...
n.y = Math.random()*height;//...i'm setting them randomly
})
//draw the lines
//each line has an x1,y1 and an x2,y2
//again not sure how you wanted them connected...
//so just doing the obvious based on the link info
const lines = svg.selectAll('line')
.data(data.links)
.enter()
.append('line')
.attr('stroke', 'black')
.attr('x1', l => {
let node = data.nodes.filter(n => n.id === l.n1)[0];
return node.x;
})
.attr('y1', l => {
let node = data.nodes.filter(n => n.id === l.n1)[0];
return node.y;
})
.attr('x2', l => {
let node = data.nodes.filter(n => n.id === l.n2)[0];
return node.x;
})
.attr('y2', l => {
let node = data.nodes.filter(n => n.id === l.n2)[0];
return node.y;
})
//draw the circles
const circles = svg.selectAll('circle')
.data(data.nodes)
.enter()
.append('circle')
// basically just random colors
.attr('fill', () => d3.color('#'+Math.floor(Math.random() * Math.pow(2,32) ^ 0xffffff).toString(16).substr(-6)))
.attr('cx', n => n.x)
.attr('cy', n => n.y)
.attr('r', n => {
//for each node, first i find all the links that contain...
//either n1 or n2 that matches the node's id
let rels = data.links.filter(l => n.id === l.n1 || n.id === l.n2);
//just google the reduce fn... it'll be easier...
let sum = rels.reduce((a,b) => a + b.amount,0);
return sum;
});
//add labels so we know whats what
const labels = svg.selectAll('text')
.data(data.nodes)
.enter()
.append('text')
.attr('x', n => n.x)
.attr('y', n => n.y)
.attr('text-anchor', 'middle') //horizontal align
.attr('alignment-baseline', 'central') //vertical align
.text(n => n.id)
尝试更新链接中的金额以查看动态更新/调整大小!