如何为不同的节点提供不同的形状或图像图标



我正在尝试为不同的节点提供不同的形状或图像图标。 就像,对于目标节点,即深蓝色,您可以在 js 小提琴中看到我想作为矩形提供给图像图标和具有不同形状或图像图标的较亮圆圈。我也点击了这个链接,但无法让它工作。 这是js小提琴: https://jsfiddle.net/AmitSah/bp6p3p92/

var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = 10;
/*svg.call(d3.zoom().on("zoom", function () {
svg.attr("transform", d3.event.transform);
}));*/
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.node_id; }).strength(1) )
//.force("charge", d3.forceManyBody())
.force("collide", d3.forceCollide(radius + 1).iterations(4))
.force("center", d3.forceCenter(width / 2, height / 2));

// projection definition
var projection = d3.geoAlbers()
.scale(1280)
.translate([width / 2, height / 2]);
// path generator definition for major cities, including point radius
var path = d3.geoPath()
.projection(projection)
.pointRadius(2);
// draws the states
d3.json("https://raw.githubusercontent.com/LogicalInsightscg/Web-Mobile-Dashboard/master/us_new.json", function(error, us_new) {
if (error) return console.error(error);
svg.selectAll(".states")
.data(topojson.feature(us_new, us_new.objects.states).features)
.enter().append("path")
.attr("class", function(d) { return "states " + d.id; })
.attr("d", path);
// adding state boundaries
svg.append("path")
.datum(topojson.mesh(us_new, us_new.objects.states))
.attr("d", path)
.attr("class", "state-boundary");

d3.json("https://raw.githubusercontent.com/LogicalInsightscg/Web-Mobile-Dashboard/master/nodesandlinks.json", function(error, graph) {
if (error) throw error;

// build the arrow.
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", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:line")
.attr("d", "M0,-5L10,0L0,5");
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.referrals); })
.attr("marker-end", "url(#end)");


var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) { return color(d.group); })
//.attr("fixed", true)
.attr("cx", function(d) {
return projection([d.longitude, d.latitude])[0];
})
.attr("cy", function(d) {
return projection([d.longitude, d.latitude])[1];
})
/*       .call(d3.drag()
.on("end", dragended)); */
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)); 

simulation
.nodes(graph.nodes)
.on("tick", ticked);  
simulation.force("link")
.links(graph.links);

node.attr('fx', function(d) { return projection([d.longitude, d.latitude])[0]; })
.attr('fy', function(d) { return projection([d.longitude, d.latitude])[1]; });
link.attr('x1', function(d) { return projection([d.source.longitude, d.source.latitude])[0]; })
.attr('y1', function(d) { return projection([d.source.longitude, d.source.latitude])[1]; })
.attr('x2', function(d) { return projection([d.target.longitude, d.target.latitude])[0]; })
.attr('y2', function(d) { return projection([d.target.longitude, d.target.latitude])[1]; });
node.append("title")
.text(function(d) { return d.node_name; });
function ticked() {
link
.attr("distance", 10)
//        .attr("x1", function(d) { return d.source.x; })
//        .attr("y1", function(d) { return d.source.y; })
.attr('x1', function(d) { return projection([d.source.longitude, d.source.latitude])[0]; })
.attr('y1', function(d) { return projection([d.source.longitude, d.source.latitude])[1]; })
.attr('x2', function(d) { return projection([d.target.longitude, d.target.latitude])[0]; })
.attr('y2', function(d) { return projection([d.target.longitude, d.target.latitude])[1]; });
node.attr('cx', function(d) {if (d.group > 0) { return projection([d.longitude, d.latitude])[0]; }
else  { return d.x; }})
.attr('cy', function(d) {if (d.group > 0) { return projection([d.longitude, d.latitude])[1]; }
else  { return d.y; }});
}

/*   function ticked() {
link.attr('x1', function(d) { return projection([d.source.longitude, d.source.latitude])[0]; })
.attr('y1', function(d) { return projection([d.source.longitude, d.source.latitude])[1]; })
.attr('x2', function(d) { return projection([d.target.longitude, d.target.latitude])[0]; })
.attr('y2', function(d) { return projection([d.target.longitude, d.target.latitude])[1]; });
node.attr('r', width/100)
.attr('cx', function(d) { return projection([d.longitude, d.latitude])[0]; })
.attr('cy', function(d) { return projection([d.longitude, d.latitude])[1]; });
} */
});
});
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}

谁能帮我做到这一点?

编辑:请看这张图片:

网络地图

d3.selectAll(".company").append("rect")
.attr("width", 20)
.attr("height", 20)
.data(someData)
.attr("x", function(d) {
if (d.cat == 2)
{
return projection([d.longitude, d.latitude])[0];
}      
})
.attr("y", function(d) {
if (d.cat == 2)
{
return projection([d.longitude, d.latitude])[1];
}      
});

谢谢 阿米特·萨

最简单的方法是在数据中包含可用于设置属性的内容,即

.attr('stroke-color', function(){
if

(d.dataAtt = someAttribute, return black) else if (d.dataAtt = otherAttribute, return white)

或者,如果要将目标节点设置为不同的颜色,可以使用 d3.select 选择目标链接数组中的所有节点 ID,然后仅更改这些节点的属性。设置节点 ID 可能有助于选择正确的节点(请参阅底行(:

var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("id", d.graph.nodes.id)//or something

编辑:

var node = svg.append("g")
.attr("class", function(){
if
(d.dataAtt = someAttribute, return Aclass)
else if
(d.dataAtt = otherAttribute, return Bclass))//it would be easiest to separate the nodes by class
.data(graph.nodes)
.enter()
.attr("id", d.graph.nodes.id)//or something
d3.selectAll(".Aclass")
.append("rect")
d3.selectAll(".Bclass")
.append("circle")

您可以使用源/目标数组来选择其中一个中有 id 的节点,但没有看到您的数据,我不知道这是否合适。

最新更新