我正在尝试将某些矩形的x和y坐标存储到数组中。有20个rect,我将值存储在20个数组的数组中。数组中的每个项目如下所示:
[
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0}
];
我在自己的矩形追加中添加了.each()
,如下所示:
.each(function(d,i) {
return polyMaster[i][0].y = d3.select(this).attr('y');
})
在这一点上,我注意到所有y
值都相同。我通过尝试确认了这一点
.each(function(d,i) {
return polyMaster[i][0].y = i;
})
哪个返回了19
-最后一个索引。因此,看来我以前所有的索引y
都被新的索引所覆盖。
var margins = {top:20, bottom:300, left:30, right:100};
var height = 600;
var width = 900;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var outerRadius = (400 / 2);
var innerRadius = 15;
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 heightScale = d3.scaleLinear()
.domain([.01,.09])
.range([7,50]);
var data = [{'manager': 'Mirae Asset', 'share': 0.016},
{'manager': 'Manulife', 'share': 0.015},
{'manager': 'ChinaAMC', 'share': 0.012},
{'manager': 'Principal', 'share': 0.015},
{'manager': 'Aberdeen Standard', 'share': 0.013},
{'manager': 'CSOP', 'share': 0.015},
{'manager': 'BOCI-Prudential', 'share': 0.019},
{'manager': 'Allianz', 'share': 0.016},
{'manager': 'HSBC', 'share': 0.027},
{'manager': 'Deutsche Bank', 'share': 0.014},
{'manager': 'Invesco', 'share': 0.025},
{'manager': 'First State', 'share': 0.033},
{'manager': 'JP Morgan', 'share': 0.041},
{'manager': 'Value Partners', 'share': 0.04},
{'manager': 'Schroders', 'share': 0.051},
{'manager': 'Hang Seng', 'share': 0.063},
{'manager': 'UBS', 'share': 0.056},
{'manager': 'SSgA', 'share': 0.066},
{'manager': 'Fidelity', 'share': 0.088},
{'manager': 'BlackRock', 'share': 0.084}];
var poly = [
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0}
];
var polyMaster = new Array(20).fill(poly);
var colorMap = {
'Fidelity':"#003366",
'BlackRock':"#366092",
'SSgA':"#4f81b9",
'Hang Seng':"#95b3d7",
'UBS':"#b8cce4",
'Schroders':"#e7eef8",
'JP Morgan':"#a6a6a6",
'Value Partners':"#d9d9d9",
'Yuanta':"#ffffcc",
'First State':"#ffffcc",
'HSBC':'#f6d18b',
'Invesco':'#e4a733',
'BOCI-Prudential':"#b29866",
'Allianz':'#a6a6a6',
'Mirae Asset':'#d9d9d9',
'Manulife':'#e7eef8',
'CSOP':'#b8cce4',
'Principal':'#95b3d7',
'Deutsche Bank':'#4f81b9',
'Aberdeen Standard':'#366092',
'ChinaAMC':'#003366'
};
var sortedData = data.sort(function(a,b) {
return b.share - a.share;
});
let counterRect = 0,
counterText = 0;
var column = graphGroup.selectAll('.ranks')
.data(sortedData)
.attr('class', 'ranks')
.enter().append("g");
column.append("rect")
.attr("width", 120)
.attr("height", function(d) {
return heightScale(d.share)
})
.attr('x', function(d) {return 0})
.attr('y', function(d, i) {
let previous = counterRect;
return (counterRect += heightScale(d.share)+2, previous)
})
.each(function(d,i) {
if (i>=0) {
return polyMaster[i][0].x = 120;
}
})
.each(function(d,i) {
if (i>=0) {
const index = i;
polyMaster[index][0].y = d3.select(this).attr('y');
}
})
.style('fill',function(d,i) {return colorMap[d.manager]});
column.append("text")
.attr('x', function(d) {return 60})
.attr('y', function(d, i) {
let previous = counterText;
return (counterText += heightScale(d.share)+2, previous + (heightScale(d.share)/2))
})
.attr("dominant-baseline", "central")
.attr('text-anchor', 'middle')
.text(function(d) {
return d.manager;
});
console.log(polyMaster)
<script src="https://d3js.org/d3.v5.min.js"></script>
我如何迭代存储我的rect的y
属性,但是一次仍然存储一次(以避免被覆盖)?
注意::我只是担心x
和y
的第一个对象。一旦我确定了上面的操作,其余三个将在以后映射。
答案 0 :(得分:2)
您的问题与d3.each
或其索引无关。您的问题出在这里:
var poly = [
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0}
];
var polyMaster = new Array(20).fill(poly);
所有数组中的所有对象都指向同一对象(poly
)。更改一个将全部更改。
一种快速解决方案是将JSON.parse
与JSON.stringify
一起使用来复制对象:
var polyMaster = d3.range(20).map(()=>JSON.parse(JSON.stringify(poly)))
不过,有几种选择。另一个简单的方法就是直接在map
内部传递数组:
var polyMaster = d3.range(20).map(()=>[
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0}
])
此外,正如您所注意到的,我使用的是d3.range
而不是new Array
+ fill
。
这是更改后的代码:
var margins = {top:20, bottom:300, left:30, right:100};
var height = 600;
var width = 900;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var outerRadius = (400 / 2);
var innerRadius = 15;
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 heightScale = d3.scaleLinear()
.domain([.01,.09])
.range([7,50]);
var data = [{'manager': 'Mirae Asset', 'share': 0.016},
{'manager': 'Manulife', 'share': 0.015},
{'manager': 'ChinaAMC', 'share': 0.012},
{'manager': 'Principal', 'share': 0.015},
{'manager': 'Aberdeen Standard', 'share': 0.013},
{'manager': 'CSOP', 'share': 0.015},
{'manager': 'BOCI-Prudential', 'share': 0.019},
{'manager': 'Allianz', 'share': 0.016},
{'manager': 'HSBC', 'share': 0.027},
{'manager': 'Deutsche Bank', 'share': 0.014},
{'manager': 'Invesco', 'share': 0.025},
{'manager': 'First State', 'share': 0.033},
{'manager': 'JP Morgan', 'share': 0.041},
{'manager': 'Value Partners', 'share': 0.04},
{'manager': 'Schroders', 'share': 0.051},
{'manager': 'Hang Seng', 'share': 0.063},
{'manager': 'UBS', 'share': 0.056},
{'manager': 'SSgA', 'share': 0.066},
{'manager': 'Fidelity', 'share': 0.088},
{'manager': 'BlackRock', 'share': 0.084}];
var poly = [
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0},
{'x':0,'y':0}
];
var polyMaster = d3.range(20).map(()=>JSON.parse(JSON.stringify(poly)))
var colorMap = {
'Fidelity':"#003366",
'BlackRock':"#366092",
'SSgA':"#4f81b9",
'Hang Seng':"#95b3d7",
'UBS':"#b8cce4",
'Schroders':"#e7eef8",
'JP Morgan':"#a6a6a6",
'Value Partners':"#d9d9d9",
'Yuanta':"#ffffcc",
'First State':"#ffffcc",
'HSBC':'#f6d18b',
'Invesco':'#e4a733',
'BOCI-Prudential':"#b29866",
'Allianz':'#a6a6a6',
'Mirae Asset':'#d9d9d9',
'Manulife':'#e7eef8',
'CSOP':'#b8cce4',
'Principal':'#95b3d7',
'Deutsche Bank':'#4f81b9',
'Aberdeen Standard':'#366092',
'ChinaAMC':'#003366'
};
var sortedData = data.sort(function(a,b) {
return b.share - a.share;
});
let counterRect = 0,
counterText = 0;
var column = graphGroup.selectAll('.ranks')
.data(sortedData)
.attr('class', 'ranks')
.enter().append("g");
column.append("rect")
.attr("width", 120)
.attr("height", function(d) {
return heightScale(d.share)
})
.attr('x', function(d) {return 0})
.attr('y', function(d, i) {
let previous = counterRect;
return (counterRect += heightScale(d.share)+2, previous)
})
.each(function(d,i) {
if (i>=0) {
return polyMaster[i][0].x = 120;
}
})
.each(function(d,i) {
if (i>=0) {
const index = i;
polyMaster[index][0].y = d3.select(this).attr('y');
}
})
.style('fill',function(d,i) {return colorMap[d.manager]});
column.append("text")
.attr('x', function(d) {return 60})
.attr('y', function(d, i) {
let previous = counterText;
return (counterText += heightScale(d.share)+2, previous + (heightScale(d.share)/2))
})
.attr("dominant-baseline", "central")
.attr('text-anchor', 'middle')
.text(function(d) {
return d.manager;
});
console.log(polyMaster)
<script src="https://d3js.org/d3.v5.min.js"></script>