简体   繁体   English

基于 D3 贝塞尔链接的 id 合并对象数组

[英]Merge array of objects based on id for D3 bezier links

Here is a quick look at my data:快速浏览一下我的数据:

var data = [
  {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':1},
  {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':2},
  {'bankid': 2016, 'sub': 0, 'applied':2016, 'id':1},
  {'bankid': 2017, 'sub': 0, 'applied':2016, 'id':2},
...
];

Basically, I have a visualization where some circles are on the top of page and some are at the bottom.基本上,我有一个可视化,其中一些圆圈位于页面顶部,而一些圆圈位于底部。 And I'm trying to append bezier links to some of my circles.我正在尝试将 append 贝塞尔链接指向我的一些圈子。 I took the data() call of my desired selection of top nodes and bottom nodes of the links.我对我想要的链接的顶部节点和底部节点进行了data()调用。 I then stored the x and y values of the top and bottom circles in two different arrays.然后我将顶部和底部圆圈的xy值存储在两个不同的 arrays 中。 My link function will need one consolidated array, so I attempted to merge them based on id .我的链接 function 将需要一个合并数组,因此我尝试根据id合并它们。 Like this:像这样:

var multiLinkData = topLinks.map(t1 => ({...t1, ...bottomLinks.find(t2 => t2.id === t1.id)}));

However, this created an array that had the correct top circle coordinates but incorrect bottom circle coordinates (the bezier lines all wound up in the same bottom circle).但是,这创建了一个具有正确顶部圆坐标但不正确底部圆坐标的数组(贝塞尔线都缠绕在同一个底部圆中)。

Result here:结果在这里:

 var margins = {top:20, bottom:300, left:200, right:100}; var height = 150; var width = 950; var totalWidth = width+margins.left+margins.right; var totalHeight = height+margins.top+margins.bottom; var svg = d3.select('body').append('svg').attr('width', totalWidth).attr('height', totalHeight); var graphGroup = svg.append('g').attr('transform', "translate("+margins.left+","+margins.top+")"); var xScale = d3.scalePoint().range([0, width]); var data = [ {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':1}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':2}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':3}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':4}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':5}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':6}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':7}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':8}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':9}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':10}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':11}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':12}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':13}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':14}, {'bankid': 2016, 'sub': 1, 'showLink':true, 'id':15}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 1}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2015}, {'bankid': 2016, 'sub': 0, 'applied':2016, 'id':1}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':16}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':17}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':18}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':19}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':20}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':21}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':22}, {'bankid': 2017, 'sub': 1, 'showLink':true, 'id':23}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 1}, {'bankid': 2017, 'sub': 0, 'applied':2015}, {'bankid': 2017, 'sub': 0, 'applied':2015}, {'bankid': 2017, 'sub': 0, 'applied':2015}, {'bankid': 2017, 'sub': 0, 'applied':2016, 'id':2}, {'bankid': 2017, 'sub': 0, 'applied':2016, 'id':3}, {'bankid': 2017, 'sub': 0, 'applied':2016, 'id':4}, {'bankid': 2018, 'sub': 1}, {'bankid': 2018, 'sub': 1}, {'bankid': 2018, 'sub': 1}, {'bankid': 2018, 'sub': 0, 'applied':2015}, {'bankid': 2018, 'sub': 0, 'applied':2015}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':5}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':6}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':7}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':8}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':9}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':10}, {'bankid': 2018, 'sub': 0, 'applied':2016, 'id':11}, {'bankid': 2018, 'sub': 0, 'applied':2017, 'id':16}, {'bankid': 2018, 'sub': 0, 'applied':2017, 'id':17}, {'bankid': 2018, 'sub': 0, 'applied':2017, 'id':18}, {'bankid': 2019, 'sub': 1, 'showLink':true, 'id':24}, {'bankid': 2019, 'sub': 1}, {'bankid': 2019, 'sub': 1}, {'bankid': 2019, 'sub': 0, 'applied':2016, 'id':12}, {'bankid': 2019, 'sub': 0, 'applied':2016, 'id':13}, {'bankid': 2019, 'sub': 0, 'applied':2017, 'id':19}, {'bankid': 2020, 'sub': 1, 'showLink':true, 'id':25}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 1}, {'bankid': 2020, 'sub': 0, 'applied':2016, 'id':14}, {'bankid': 2020, 'sub': 0, 'applied':2016, 'id':15}, {'bankid': 2020, 'sub': 0, 'applied':2017, 'id':20}, {'bankid': 2020, 'sub': 0, 'applied':2017, 'id':21}, {'bankid': 2020, 'sub': 0, 'applied':2017, 'id':22}, {'bankid': 2020, 'sub': 0, 'applied':2017, 'id':23}, {'bankid': 2020, 'sub': 0, 'applied':2020, 'id':25}, {'bankid': 2021, 'sub': 1}, {'bankid': 2021, 'sub': 0, 'applied':2019, 'id':24}, ]; var colorScale = d3.scaleOrdinal(["#003366","#366092","#4f81b9","#95b3d7","#b8cce4","#e7eef8"]); xScale.domain([2015,2016,2017,2018,2019,2020,2021]); //colorScale.domain(d3.extent(data, function(d) {return d.age; })); data.forEach(function (d) { dx = xScale(d.bankid); dy = d.sub? height - 15: height + 250; }); var simulation = d3.forceSimulation(data).force("x", d3.forceX(function(d) { return xScale(d.bankid); }).strength(0.08)).force("y", d3.forceY(function(d) { return d.sub? height - 15: height + 250 }).strength(0.05)).force("collide", d3.forceCollide(6).iterations(1)).stop(); for (var i = 0; i < 240; ++i) { simulation.tick(); data.forEach(function (d) { if (d.sub) { dy = Math.min(dy, height - 15); } else { dy = Math.max(dy, height + 250); } }); } var colorMap = { 2015:"#003366", 2016:"#4f81b9", 2017:"#95b3d7", 2018:"#e7eef8", 2019:"#d9d9d9", 2020:"#a6a6a6", 2021:"#f6d18b" }; var circles = graphGroup.selectAll(null).data(data).enter().append("circle").attr("r", 5).attr("cx", function(d) { return dx; }).attr("cy", function(d) { return dy; }).style('fill', function(d) {return d.sub ==1? colorMap[d.bankid]: colorMap[d.applied];}); var topCircles = d3.selectAll('circle').filter(function(d) {return d.showLink == true}).data(); var bottomCircles = d3.selectAll('circle').filter(function(d) {return d.sub == 0 && d.applied.== 2015});data(). var topLinks = topCircles:map(function(d) { return {source. [d,x. d;y]} }). var bottomLinks = bottomCircles:map(function(d) { return {target. [d,x. d;y]} }). var multiLinkData = topLinks.map(t1 => ({..,t1. ...bottomLinks.find(t2 => t2.id === t1;id)})). //console;log(bottomCircles). //console;log(multiLinkData). var link = d3;linkHorizontal(). graphGroup.selectAll("path").data(multiLinkData).join("path"),attr("d". link),attr("fill". "none"),attr("stroke"; "#d9d9d9");
 <script src="https://d3js.org/d3.v5.min.js"></script>

Not sure how my merge went sideways on me.不知道我的合并是如何对我产生影响的。

Question问题

What would be the syntax fix for this kind of merge?这种合并的语法修复是什么?

You're not populating topLinks and bottomLinks with the IDs.您没有使用 ID 填充topLinksbottomLinks It should be:它应该是:

var topLinks = topCircles.map(function(d) {
  return {source: [d.x, d.y], id: d.id}
});

var bottomLinks = bottomCircles.map(function(d) {
  return {target: [d.x, d.y], id: d.id}
});

Here is your code with that change:这是您进行更改的代码:

 var margins = { top: 20, bottom: 300, left: 200, right: 100 }; var height = 150; var width = 950; var totalWidth = width + margins.left + margins.right; var totalHeight = height + margins.top + margins.bottom; var svg = d3.select('body').append('svg').attr('width', totalWidth).attr('height', totalHeight); var graphGroup = svg.append('g').attr('transform', "translate(" + margins.left + "," + margins.top + ")"); var xScale = d3.scalePoint().range([0, width]); var data = [{ 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 1 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 2 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 3 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 4 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 5 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 6 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 7 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 8 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 9 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 10 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 11 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 12 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 13 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 14 }, { 'bankid': 2016, 'sub': 1, 'showLink': true, 'id': 15 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 1 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2015 }, { 'bankid': 2016, 'sub': 0, 'applied': 2016, 'id': 1 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 16 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 17 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 18 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 19 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 20 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 21 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 22 }, { 'bankid': 2017, 'sub': 1, 'showLink': true, 'id': 23 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 1 }, { 'bankid': 2017, 'sub': 0, 'applied': 2015 }, { 'bankid': 2017, 'sub': 0, 'applied': 2015 }, { 'bankid': 2017, 'sub': 0, 'applied': 2015 }, { 'bankid': 2017, 'sub': 0, 'applied': 2016, 'id': 2 }, { 'bankid': 2017, 'sub': 0, 'applied': 2016, 'id': 3 }, { 'bankid': 2017, 'sub': 0, 'applied': 2016, 'id': 4 }, { 'bankid': 2018, 'sub': 1 }, { 'bankid': 2018, 'sub': 1 }, { 'bankid': 2018, 'sub': 1 }, { 'bankid': 2018, 'sub': 0, 'applied': 2015 }, { 'bankid': 2018, 'sub': 0, 'applied': 2015 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 5 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 6 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 7 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 8 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 9 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 10 }, { 'bankid': 2018, 'sub': 0, 'applied': 2016, 'id': 11 }, { 'bankid': 2018, 'sub': 0, 'applied': 2017, 'id': 16 }, { 'bankid': 2018, 'sub': 0, 'applied': 2017, 'id': 17 }, { 'bankid': 2018, 'sub': 0, 'applied': 2017, 'id': 18 }, { 'bankid': 2019, 'sub': 1, 'showLink': true, 'id': 24 }, { 'bankid': 2019, 'sub': 1 }, { 'bankid': 2019, 'sub': 1 }, { 'bankid': 2019, 'sub': 0, 'applied': 2016, 'id': 12 }, { 'bankid': 2019, 'sub': 0, 'applied': 2016, 'id': 13 }, { 'bankid': 2019, 'sub': 0, 'applied': 2017, 'id': 19 }, { 'bankid': 2020, 'sub': 1, 'showLink': true, 'id': 25 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 1 }, { 'bankid': 2020, 'sub': 0, 'applied': 2016, 'id': 14 }, { 'bankid': 2020, 'sub': 0, 'applied': 2016, 'id': 15 }, { 'bankid': 2020, 'sub': 0, 'applied': 2017, 'id': 20 }, { 'bankid': 2020, 'sub': 0, 'applied': 2017, 'id': 21 }, { 'bankid': 2020, 'sub': 0, 'applied': 2017, 'id': 22 }, { 'bankid': 2020, 'sub': 0, 'applied': 2017, 'id': 23 }, { 'bankid': 2020, 'sub': 0, 'applied': 2020, 'id': 25 }, { 'bankid': 2021, 'sub': 1 }, { 'bankid': 2021, 'sub': 0, 'applied': 2019, 'id': 24 }, ]; var colorScale = d3.scaleOrdinal(["#003366", "#366092", "#4f81b9", "#95b3d7", "#b8cce4", "#e7eef8"]); xScale.domain([2015, 2016, 2017, 2018, 2019, 2020, 2021]); //colorScale.domain(d3.extent(data, function(d) {return d.age; })); data.forEach(function(d) { dx = xScale(d.bankid); dy = d.sub? height - 15: height + 250; }); var simulation = d3.forceSimulation(data).force("x", d3.forceX(function(d) { return xScale(d.bankid); }).strength(0.08)).force("y", d3.forceY(function(d) { return d.sub? height - 15: height + 250 }).strength(0.05)).force("collide", d3.forceCollide(6).iterations(1)).stop(); for (var i = 0; i < 240; ++i) { simulation.tick(); data.forEach(function(d) { if (d.sub) { dy = Math.min(dy, height - 15); } else { dy = Math.max(dy, height + 250); } }); } var colorMap = { 2015: "#003366", 2016: "#4f81b9", 2017: "#95b3d7", 2018: "#e7eef8", 2019: "#d9d9d9", 2020: "#a6a6a6", 2021: "#f6d18b" }; var circles = graphGroup.selectAll(null).data(data).enter().append("circle").attr("r", 5).attr("cx", function(d) { return dx; }).attr("cy", function(d) { return dy; }).style('fill', function(d) { return d.sub == 1? colorMap[d.bankid]: colorMap[d.applied]; }); var topCircles = d3.selectAll('circle').filter(function(d) { return d.showLink == true }).data(); var bottomCircles = d3.selectAll('circle').filter(function(d) { return d.sub == 0 && d.applied.== 2015 });data(). var topLinks = topCircles:map(function(d) { return { source. [d,x. d,y]: id. d;id } }). var bottomLinks = bottomCircles:map(function(d) { return { target. [d,x. d,y]: id. d;id } }). var multiLinkData = topLinks.map(t1 => ({..,t1. ...bottomLinks.find(t2 => t2.id === t1;id) })). //console;log(bottomCircles). //console;log(multiLinkData). var link = d3;linkHorizontal(). graphGroup.selectAll("path").data(multiLinkData).join("path"),attr("d". link),attr("fill". "none"),attr("stroke"; "#d9d9d9");
 <script src="https://d3js.org/d3.v5.min.js"></script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM