gpt4 book ai didi

javascript - d3.js 将第二个标签添加到条形图

转载 作者:行者123 更新时间:2023-12-02 23:36:00 27 4
gpt4 key购买 nike

两部分问题:

我有一个使用多个数组创建的条形图。这些数组包含棒球队的获胜百分比;相关球队颜色;和他们的名字。

我可以在图表上创建一组标签,可以是名称,也可以是获胜百分比。但是我不能同时打开两者。见下文。 win%

Team names

我使用的代码是:

let WinsLabel = svgContainer.selectAll("text")
.data(d3.zip(TeamArray, WinPercArray, Colours));

WinsLabel.enter()
.append("text")
.attr("fill", "black")
.attr("x", function(d, i) {
return 45 + (i * 50);
})
.attr("y", 700)
.transition()
.duration(1000)
.attr("x", function(d,i){
return 70 + (i*50);
})
.attr("y", function(d){
return 685 - d[1];
})
.attr("text-anchor","middle")
.attr("font-family", "sans-serif")
.attr("font-size", "15px")
.attr("fill", "black")
.text(function(d){
return d[1]/10 + "%";
});
let TeamLabel = svgContainer.selectAll("text")
.data(d3.zip(TeamArray, WinPercArray, Colours));

TeamLabel.enter()
.append("text")
.attr("fill", "black")
.attr("x", function(d, i) {
return 45 + (i * 50);
})
.attr("y", 700)
.transition()
.duration(1000)
.attr("x", function(d,i){
return 70 + (i*50);
})
.attr("y", function(d){
return 700 - d[1]/2;
})
.attr("text-anchor","middle")
.attr("font-family", "sans-serif")
.attr("font-size", "15px")
.attr("fill", "white")
.text(function(d){
return d[0];
});

当我使用两个脚本运行代码时,仅显示 win %,但名称不显示。为了让名字显示出来,我必须删除第一个标签。

我的问题分为两部分:

  1. 如何让两组标签同时显示?
  2. 如何使名称在矩形/条形中垂直排列?

最佳答案

D3代表数据驱动的事物;它的核心原则是基于将元素/选择与数据链接起来。当您设置数据时,(var Selection = selectAll(...).data(...)),您需要考虑 3 种情况:

  1. 某些现有元素可以链接到新数据中的某些项目。您可以使用选择来访问它们
  2. 某些元素无法链接到新数据中的任何项目。您可以使用 selection.exit()
  3. 访问它们
  4. 新数据中的某些项目无法链接到选择的任何元素。您可以使用 selection.enter()
  5. 访问它们

在最简单的情况下,数据和元素之间的链接是通过索引进行的——即选择中的第一个元素与数据数组中的第一个元素链接,第二个元素与第二个元素链接,依此类推。当且仅当(在此按索引上下文中)该数据项的索引大于大小时,d3 无法找到数据项的元素(= 放入 .enter() 选择中)的选择。

在您最初选择时

let WinsLabel = svgContainer.selectAll("text")
.data(d3.zip(TeamArray, WinPercArray, Colours));

所选内容为空,因为还没有文本标记。由于其为空,因此所有要创建的占位符都位于 .enter() 选择范围内。但是,在您下次选择其他标签类型时

let TeamLabel = svgContainer.selectAll("text")
.data(d3.zip(TeamArray, WinPercArray, Colours));

选择的大小与传递数据的大小相同,因此.enter()选择为空;这是包含所有旧元素(百分比标签 text 标签)的 TeamLabel 选择,但它们的数据值已重新分配。

<小时/>

安德鲁提出了一种分配类(class)的解决方案,但就我个人而言,我会采取与同一团队相关的所有元素并将其放在一个组下。

var TeamArray = ["Yankees",  "Rays", "RedSox", "Jays","Orioles", "Twin", "Indians", "WhiteSox", "Detroit", "Royals", "Astros", "Rangers", "A's", "Angels","Mariners"];
var WinPercArray = [653, 609, 540, 400, 300, 667, 521, 458, 383, 347, 660, 511, 500, 458, 442];
var Colours = ["#003087", "#092C5C", "#BD3039", "#134A8E", "#DF4601", "#002B5C", "#0C2340", "#C4CED4", "#FA4616", "#BD9B60", "#EB6E1F", "#C0111F", "#003831", "#003263", "#005C5C"];

var data = d3.zip(TeamArray, WinPercArray, Colours);

var svg = d3.select('body').append('svg').attr('height', 300).attr('width', 800);

var teams = svg.selectAll('g.teams')
.data(data);

var scale = d3.scaleLinear()
.domain([0, 1000])
.range([200, 0]);

var teamsEnter = teams.enter()
.append('g')
.classed('team', true)
.attr('transform', function(d, i){
return 'translate(' + (i*50) + ',0)';
})

teamsEnter.append('rect')
.attr('width', 50)
.attr('y', function(d) { return scale(d[1]); })
.attr('height', function(d) { return scale(0) - scale(d[1]); })
.style('fill', function(d) { return d[2]; });

teamsEnter.append('text')
.attr('x', 25)
.attr('y', function(d) { return scale(d[1]) - 30; })
.text(function(d){ return d[0]; });

teamsEnter.append('text')
.attr('x', 25)
.attr('y', function(d) { return scale(d[1]) - 15; })
.text(function(d){ return d[1]; });
text {
text-anchor: middle;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

组在某种程度上充当内部项目的封装,因此您可以在心理上将与组的数据绑定(bind)(即何时创建/更新/删除它)与使用其子项时发生的实际逻辑分开

关于javascript - d3.js 将第二个标签添加到条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56298178/

27 4 0