我试图在d3.js中创建一个力图,每个节点顶部都有一些标签,还有一些依赖于内容的样式(例如,节点的颜色取决于'type'属性)。我从其中一个examples开始,但是当我更新它时,我无法使图形显示新数据。例如,在更改数据列表上的text属性时,节点上的标签应该更改,但不会更改。我认为问题可能出在data()
/ enter()
程序中,我仍然试图完全理解。到目前为止我得到的是以下内容:https://jsfiddle.net/5Luv0btd/2/。任何帮助将不胜感激!
答案 0 :(得分:0)
这是因为一旦输入数据,您就不必再操作nodeEnter
了。原因很简单:.enter()
merges into the update selection when you append or insert.。换句话说,在链接.enter()
之后,node
有效地引用旧数据和新数据。引用d3的v3.x文档示例:
var update_sel = svg.selectAll("circle").data(data)
update_sel.attr(/* operate on old elements only */)
update_sel.enter().append("circle").attr(/* operate on new elements only */)
update_sel.attr(/* operate on old and new elements */)
update_sel.exit().remove() /* complete the enter-update-exit pattern */
因此,使用node
本身就足够了,即:
// Enter selection
node.enter().append("g")
.attr("class", "node")
.call(drag);
// From this point onwards:
// `node` will refer to both old and new data
// Do magic ;)
node.append("circle")
.attr("r", 10)
.style('fill', function(d) {
return color(d.type)
})
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 0)
.attr("dy", ".35em")
.text(function(d) {
return d.name
})
.attr("text-anchor", "middle");
请在此处查看工作小提琴:https://jsfiddle.net/teddyrised/5Luv0btd/5/,或参阅下面的代码段:
var data = {
"nodes": [{
"name": "Myriel",
"type": 1
}, {
"name": "Napoleon",
"type": 1
}, {
"name": "Mlle.Baptistine",
"type": 1
}, {
"name": "Mme.Magloire",
"type": 1
}, {
"name": "CountessdeLo",
"type": 1
}, {
"name": "Geborand",
"type": 1
}, {
"name": "Champtercier",
"type": 1
}, {
"name": "Cravatte",
"type": 1
}, {
"name": "Count",
"type": 1
}, {
"name": "OldMan",
"type": 1
}, {
"name": "Labarre",
"type": 2
}, {
"name": "Valjean",
"type": 2
}, {
"name": "Marguerite",
"type": 3
}, {
"name": "Mme.deR",
"type": 2
}, {
"name": "Isabeau",
"type": 2
}, {
"name": "Gervais",
"type": 2
}, {
"name": "Tholomyes",
"type": 3
}, {
"name": "Listolier",
"type": 3
}, {
"name": "Fameuil",
"type": 3
}, {
"name": "Blacheville",
"type": 3
}, {
"name": "Favourite",
"type": 3
}, {
"name": "Dahlia",
"type": 3
}, {
"name": "Zephine",
"type": 3
}, {
"name": "Fantine",
"type": 3
}, {
"name": "Mme.Thenardier",
"type": 4
}, {
"name": "Thenardier",
"type": 4
}, {
"name": "Cosette",
"type": 5
}, {
"name": "Javert",
"type": 4
}, {
"name": "Fauchelevent",
"type": 0
}, {
"name": "Bamatabois",
"type": 2
}, {
"name": "Perpetue",
"type": 3
}, {
"name": "Simplice",
"type": 2
}, {
"name": "Scaufflaire",
"type": 2
}, {
"name": "Woman1",
"type": 2
}, {
"name": "Judge",
"type": 2
}, {
"name": "Champmathieu",
"type": 2
}, {
"name": "Brevet",
"type": 2
}, {
"name": "Chenildieu",
"type": 2
}, {
"name": "Cochepaille",
"type": 2
}, {
"name": "Pontmercy",
"type": 4
}, {
"name": "Boulatruelle",
"type": 6
}, {
"name": "Eponine",
"type": 4
}, {
"name": "Anzelma",
"type": 4
}, {
"name": "Woman2",
"type": 5
}, {
"name": "MotherInnocent",
"type": 0
}, {
"name": "Gribier",
"type": 0
}, {
"name": "Jondrette",
"type": 7
}, {
"name": "Mme.Burgon",
"type": 7
}, {
"name": "Gavroche",
"type": 8
}, {
"name": "Gillenormand",
"type": 5
}, {
"name": "Magnon",
"type": 5
}, {
"name": "Mlle.Gillenormand",
"type": 5
}, {
"name": "Mme.Pontmercy",
"type": 5
}, {
"name": "Mlle.Vaubois",
"type": 5
}, {
"name": "Lt.Gillenormand",
"type": 5
}, {
"name": "Marius",
"type": 8
}, {
"name": "BaronessT",
"type": 5
}, {
"name": "Mabeuf",
"type": 8
}, {
"name": "Enjolras",
"type": 8
}, {
"name": "Combeferre",
"type": 8
}, {
"name": "Prouvaire",
"type": 8
}, {
"name": "Feuilly",
"type": 8
}, {
"name": "Courfeyrac",
"type": 8
}, {
"name": "Bahorel",
"type": 8
}, {
"name": "Bossuet",
"type": 8
}, {
"name": "Joly",
"type": 8
}, {
"name": "Grantaire",
"type": 8
}, {
"name": "MotherPlutarch",
"type": 9
}, {
"name": "Gueulemer",
"type": 4
}, {
"name": "Babet",
"type": 4
}, {
"name": "Claquesous",
"type": 4
}, {
"name": "Montparnasse",
"type": 4
}, {
"name": "Toussaint",
"type": 5
}, {
"name": "Child1",
"type": 10
}, {
"name": "Child2",
"type": 10
}, {
"name": "Brujon",
"type": 4
}, {
"name": "Mme.Hucheloup",
"type": 8
}],
"links": [{
"source": 1,
"target": 0,
"value": 1
}, {
"source": 2,
"target": 0,
"value": 8
}, {
"source": 3,
"target": 0,
"value": 10
}, {
"source": 3,
"target": 2,
"value": 6
}, {
"source": 4,
"target": 0,
"value": 1
}, {
"source": 5,
"target": 0,
"value": 1
}, {
"source": 6,
"target": 0,
"value": 1
}, {
"source": 7,
"target": 0,
"value": 1
}, {
"source": 8,
"target": 0,
"value": 2
}, {
"source": 9,
"target": 0,
"value": 1
}, {
"source": 11,
"target": 10,
"value": 1
}, {
"source": 11,
"target": 3,
"value": 3
}, {
"source": 11,
"target": 2,
"value": 3
}, {
"source": 11,
"target": 0,
"value": 5
}, {
"source": 12,
"target": 11,
"value": 1
}, {
"source": 13,
"target": 11,
"value": 1
}, {
"source": 14,
"target": 11,
"value": 1
}, {
"source": 15,
"target": 11,
"value": 1
}, {
"source": 17,
"target": 16,
"value": 4
}, {
"source": 18,
"target": 16,
"value": 4
}, {
"source": 18,
"target": 17,
"value": 4
}, {
"source": 19,
"target": 16,
"value": 4
}, {
"source": 19,
"target": 17,
"value": 4
}, {
"source": 19,
"target": 18,
"value": 4
}, {
"source": 20,
"target": 16,
"value": 3
}, {
"source": 20,
"target": 17,
"value": 3
}, {
"source": 20,
"target": 18,
"value": 3
}, {
"source": 20,
"target": 19,
"value": 4
}, {
"source": 21,
"target": 16,
"value": 3
}, {
"source": 21,
"target": 17,
"value": 3
}, {
"source": 21,
"target": 18,
"value": 3
}, {
"source": 21,
"target": 19,
"value": 3
}, {
"source": 21,
"target": 20,
"value": 5
}, {
"source": 22,
"target": 16,
"value": 3
}, {
"source": 22,
"target": 17,
"value": 3
}, {
"source": 22,
"target": 18,
"value": 3
}, {
"source": 22,
"target": 19,
"value": 3
}, {
"source": 22,
"target": 20,
"value": 4
}, {
"source": 22,
"target": 21,
"value": 4
}, {
"source": 23,
"target": 16,
"value": 3
}, {
"source": 23,
"target": 17,
"value": 3
}, {
"source": 23,
"target": 18,
"value": 3
}, {
"source": 23,
"target": 19,
"value": 3
}, {
"source": 23,
"target": 20,
"value": 4
}, {
"source": 23,
"target": 21,
"value": 4
}, {
"source": 23,
"target": 22,
"value": 4
}, {
"source": 23,
"target": 12,
"value": 2
}, {
"source": 23,
"target": 11,
"value": 9
}, {
"source": 24,
"target": 23,
"value": 2
}, {
"source": 24,
"target": 11,
"value": 7
}, {
"source": 25,
"target": 24,
"value": 13
}, {
"source": 25,
"target": 23,
"value": 1
}, {
"source": 25,
"target": 11,
"value": 12
}, {
"source": 26,
"target": 24,
"value": 4
}, {
"source": 26,
"target": 11,
"value": 31
}, {
"source": 26,
"target": 16,
"value": 1
}, {
"source": 26,
"target": 25,
"value": 1
}, {
"source": 27,
"target": 11,
"value": 17
}, {
"source": 27,
"target": 23,
"value": 5
}, {
"source": 27,
"target": 25,
"value": 5
}, {
"source": 27,
"target": 24,
"value": 1
}, {
"source": 27,
"target": 26,
"value": 1
}, {
"source": 28,
"target": 11,
"value": 8
}, {
"source": 28,
"target": 27,
"value": 1
}, {
"source": 29,
"target": 23,
"value": 1
}, {
"source": 29,
"target": 27,
"value": 1
}, {
"source": 29,
"target": 11,
"value": 2
}, {
"source": 30,
"target": 23,
"value": 1
}, {
"source": 31,
"target": 30,
"value": 2
}, {
"source": 31,
"target": 11,
"value": 3
}, {
"source": 31,
"target": 23,
"value": 2
}, {
"source": 31,
"target": 27,
"value": 1
}, {
"source": 32,
"target": 11,
"value": 1
}, {
"source": 33,
"target": 11,
"value": 2
}, {
"source": 33,
"target": 27,
"value": 1
}, {
"source": 34,
"target": 11,
"value": 3
}, {
"source": 34,
"target": 29,
"value": 2
}, {
"source": 35,
"target": 11,
"value": 3
}, {
"source": 35,
"target": 34,
"value": 3
}, {
"source": 35,
"target": 29,
"value": 2
}, {
"source": 36,
"target": 34,
"value": 2
}, {
"source": 36,
"target": 35,
"value": 2
}, {
"source": 36,
"target": 11,
"value": 2
}, {
"source": 36,
"target": 29,
"value": 1
}, {
"source": 37,
"target": 34,
"value": 2
}, {
"source": 37,
"target": 35,
"value": 2
}, {
"source": 37,
"target": 36,
"value": 2
}, {
"source": 37,
"target": 11,
"value": 2
}, {
"source": 37,
"target": 29,
"value": 1
}, {
"source": 38,
"target": 34,
"value": 2
}, {
"source": 38,
"target": 35,
"value": 2
}, {
"source": 38,
"target": 36,
"value": 2
}, {
"source": 38,
"target": 37,
"value": 2
}, {
"source": 38,
"target": 11,
"value": 2
}, {
"source": 38,
"target": 29,
"value": 1
}, {
"source": 39,
"target": 25,
"value": 1
}, {
"source": 40,
"target": 25,
"value": 1
}, {
"source": 41,
"target": 24,
"value": 2
}, {
"source": 41,
"target": 25,
"value": 3
}, {
"source": 42,
"target": 41,
"value": 2
}, {
"source": 42,
"target": 25,
"value": 2
}, {
"source": 42,
"target": 24,
"value": 1
}, {
"source": 43,
"target": 11,
"value": 3
}, {
"source": 43,
"target": 26,
"value": 1
}, {
"source": 43,
"target": 27,
"value": 1
}, {
"source": 44,
"target": 28,
"value": 3
}, {
"source": 44,
"target": 11,
"value": 1
}, {
"source": 45,
"target": 28,
"value": 2
}, {
"source": 47,
"target": 46,
"value": 1
}, {
"source": 48,
"target": 47,
"value": 2
}, {
"source": 48,
"target": 25,
"value": 1
}, {
"source": 48,
"target": 27,
"value": 1
}, {
"source": 48,
"target": 11,
"value": 1
}, {
"source": 49,
"target": 26,
"value": 3
}, {
"source": 49,
"target": 11,
"value": 2
}, {
"source": 50,
"target": 49,
"value": 1
}, {
"source": 50,
"target": 24,
"value": 1
}, {
"source": 51,
"target": 49,
"value": 9
}, {
"source": 51,
"target": 26,
"value": 2
}, {
"source": 51,
"target": 11,
"value": 2
}, {
"source": 52,
"target": 51,
"value": 1
}, {
"source": 52,
"target": 39,
"value": 1
}, {
"source": 53,
"target": 51,
"value": 1
}, {
"source": 54,
"target": 51,
"value": 2
}, {
"source": 54,
"target": 49,
"value": 1
}, {
"source": 54,
"target": 26,
"value": 1
}, {
"source": 55,
"target": 51,
"value": 6
}, {
"source": 55,
"target": 49,
"value": 12
}, {
"source": 55,
"target": 39,
"value": 1
}, {
"source": 55,
"target": 54,
"value": 1
}, {
"source": 55,
"target": 26,
"value": 21
}, {
"source": 55,
"target": 11,
"value": 19
}, {
"source": 55,
"target": 16,
"value": 1
}, {
"source": 55,
"target": 25,
"value": 2
}, {
"source": 55,
"target": 41,
"value": 5
}, {
"source": 55,
"target": 48,
"value": 4
}, {
"source": 56,
"target": 49,
"value": 1
}, {
"source": 56,
"target": 55,
"value": 1
}, {
"source": 57,
"target": 55,
"value": 1
}, {
"source": 57,
"target": 41,
"value": 1
}, {
"source": 57,
"target": 48,
"value": 1
}, {
"source": 58,
"target": 55,
"value": 7
}, {
"source": 58,
"target": 48,
"value": 7
}, {
"source": 58,
"target": 27,
"value": 6
}, {
"source": 58,
"target": 57,
"value": 1
}, {
"source": 58,
"target": 11,
"value": 4
}, {
"source": 59,
"target": 58,
"value": 15
}, {
"source": 59,
"target": 55,
"value": 5
}, {
"source": 59,
"target": 48,
"value": 6
}, {
"source": 59,
"target": 57,
"value": 2
}, {
"source": 60,
"target": 48,
"value": 1
}, {
"source": 60,
"target": 58,
"value": 4
}, {
"source": 60,
"target": 59,
"value": 2
}, {
"source": 61,
"target": 48,
"value": 2
}, {
"source": 61,
"target": 58,
"value": 6
}, {
"source": 61,
"target": 60,
"value": 2
}, {
"source": 61,
"target": 59,
"value": 5
}, {
"source": 61,
"target": 57,
"value": 1
}, {
"source": 61,
"target": 55,
"value": 1
}, {
"source": 62,
"target": 55,
"value": 9
}, {
"source": 62,
"target": 58,
"value": 17
}, {
"source": 62,
"target": 59,
"value": 13
}, {
"source": 62,
"target": 48,
"value": 7
}, {
"source": 62,
"target": 57,
"value": 2
}, {
"source": 62,
"target": 41,
"value": 1
}, {
"source": 62,
"target": 61,
"value": 6
}, {
"source": 62,
"target": 60,
"value": 3
}, {
"source": 63,
"target": 59,
"value": 5
}, {
"source": 63,
"target": 48,
"value": 5
}, {
"source": 63,
"target": 62,
"value": 6
}, {
"source": 63,
"target": 57,
"value": 2
}, {
"source": 63,
"target": 58,
"value": 4
}, {
"source": 63,
"target": 61,
"value": 3
}, {
"source": 63,
"target": 60,
"value": 2
}, {
"source": 63,
"target": 55,
"value": 1
}, {
"source": 64,
"target": 55,
"value": 5
}, {
"source": 64,
"target": 62,
"value": 12
}, {
"source": 64,
"target": 48,
"value": 5
}, {
"source": 64,
"target": 63,
"value": 4
}, {
"source": 64,
"target": 58,
"value": 10
}, {
"source": 64,
"target": 61,
"value": 6
}, {
"source": 64,
"target": 60,
"value": 2
}, {
"source": 64,
"target": 59,
"value": 9
}, {
"source": 64,
"target": 57,
"value": 1
}, {
"source": 64,
"target": 11,
"value": 1
}, {
"source": 65,
"target": 63,
"value": 5
}, {
"source": 65,
"target": 64,
"value": 7
}, {
"source": 65,
"target": 48,
"value": 3
}, {
"source": 65,
"target": 62,
"value": 5
}, {
"source": 65,
"target": 58,
"value": 5
}, {
"source": 65,
"target": 61,
"value": 5
}, {
"source": 65,
"target": 60,
"value": 2
}, {
"source": 65,
"target": 59,
"value": 5
}, {
"source": 65,
"target": 57,
"value": 1
}, {
"source": 65,
"target": 55,
"value": 2
}, {
"source": 66,
"target": 64,
"value": 3
}, {
"source": 66,
"target": 58,
"value": 3
}, {
"source": 66,
"target": 59,
"value": 1
}, {
"source": 66,
"target": 62,
"value": 2
}, {
"source": 66,
"target": 65,
"value": 2
}, {
"source": 66,
"target": 48,
"value": 1
}, {
"source": 66,
"target": 63,
"value": 1
}, {
"source": 66,
"target": 61,
"value": 1
}, {
"source": 66,
"target": 60,
"value": 1
}, {
"source": 67,
"target": 57,
"value": 3
}, {
"source": 68,
"target": 25,
"value": 5
}, {
"source": 68,
"target": 11,
"value": 1
}, {
"source": 68,
"target": 24,
"value": 1
}, {
"source": 68,
"target": 27,
"value": 1
}, {
"source": 68,
"target": 48,
"value": 1
}, {
"source": 68,
"target": 41,
"value": 1
}, {
"source": 69,
"target": 25,
"value": 6
}, {
"source": 69,
"target": 68,
"value": 6
}, {
"source": 69,
"target": 11,
"value": 1
}, {
"source": 69,
"target": 24,
"value": 1
}, {
"source": 69,
"target": 27,
"value": 2
}, {
"source": 69,
"target": 48,
"value": 1
}, {
"source": 69,
"target": 41,
"value": 1
}, {
"source": 70,
"target": 25,
"value": 4
}, {
"source": 70,
"target": 69,
"value": 4
}, {
"source": 70,
"target": 68,
"value": 4
}, {
"source": 70,
"target": 11,
"value": 1
}, {
"source": 70,
"target": 24,
"value": 1
}, {
"source": 70,
"target": 27,
"value": 1
}, {
"source": 70,
"target": 41,
"value": 1
}, {
"source": 70,
"target": 58,
"value": 1
}, {
"source": 71,
"target": 27,
"value": 1
}, {
"source": 71,
"target": 69,
"value": 2
}, {
"source": 71,
"target": 68,
"value": 2
}, {
"source": 71,
"target": 70,
"value": 2
}, {
"source": 71,
"target": 11,
"value": 1
}, {
"source": 71,
"target": 48,
"value": 1
}, {
"source": 71,
"target": 41,
"value": 1
}, {
"source": 71,
"target": 25,
"value": 1
}, {
"source": 72,
"target": 26,
"value": 2
}, {
"source": 72,
"target": 27,
"value": 1
}, {
"source": 72,
"target": 11,
"value": 1
}, {
"source": 73,
"target": 48,
"value": 2
}, {
"source": 74,
"target": 48,
"value": 2
}, {
"source": 74,
"target": 73,
"value": 3
}, {
"source": 75,
"target": 69,
"value": 3
}, {
"source": 75,
"target": 68,
"value": 3
}, {
"source": 75,
"target": 25,
"value": 3
}, {
"source": 75,
"target": 48,
"value": 1
}, {
"source": 75,
"target": 41,
"value": 1
}, {
"source": 75,
"target": 70,
"value": 1
}, {
"source": 75,
"target": 71,
"value": 1
}, {
"source": 76,
"target": 64,
"value": 1
}, {
"source": 76,
"target": 65,
"value": 1
}, {
"source": 76,
"target": 66,
"value": 1
}, {
"source": 76,
"target": 63,
"value": 1
}, {
"source": 76,
"target": 62,
"value": 1
}, {
"source": 76,
"target": 48,
"value": 1
}, {
"source": 76,
"target": 58,
"value": 1
}]
};
var width = 960,
height = 500,
color = d3.scale.category20();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.gravity(0.05)
.distance(100)
.charge(-100)
.size([width, height]);
var draw = function(data) {
force
.nodes(data.nodes)
.links(data.links)
.start();
var drag = d3.behavior.drag().origin(function(d) {
return d;
});
var link = svg.selectAll(".link")
.data(data.links);
var linkEnter = link.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(data.nodes, function(d) {
return d.name
});
node.enter().append("g")
.attr("class", "node")
.call(drag);
node.append("circle")
.attr("r", 10)
.style('fill', function(d) {
return color(d.type)
})
.attr("width", 16)
.attr("height", 16);
node.append("text")
.attr("dx", 0)
.attr("dy", ".35em")
.text(function(d) {
return d.name
})
.attr("text-anchor", "middle");
link.exit().remove();
node.exit().remove();
force.on("tick", function() {
link.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;
});
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
}
draw(data);
setTimeout(function(d) {
data.nodes[0].name = "A changed name";
data.nodes[0].type = 2;
// The node 'Myriel' should now have the labed 'A changed name'
draw(data)
}, 2000);
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
<script src="//d3js.org/d3.v3.min.js"></script>