d3.select 效果不好?

d3.select doesn't work well?

我正在使用 d3 尝试更改 c3 图中的属性,我可以检测元素的唯一方法是通过其 css 属性 : "text.c3-chart-arcs-title"。 该页面有两个带有 css 属性 的元素,该函数被调用 2 次以获取这两个元素。 我的代码是:

if(d3.select("text.c3-chart-arcs-title")){
       let vari = d3.select("text.c3-chart-arcs-title");
       console.log("got here");
       vari.attr("id", "title" + name); //name is a variable that must be different between both elements
       vari.attr("class", "substitute"); //I replace the css to be able to get to the second graph
                }

但是只有第一个元素受到我的更改的影响,第二个元素没有受到影响,即使我有 2 次 "got here" 意味着第二个元素被检测到。

注意:之后我将使用这两个组件:

$("#title" + name).css('cursor', 'pointer')
                    .click(function () {
                        //function using variables of each component 1 and 2 previously selected 
                        }
                    });

你能告诉我我做错了什么以及如何访问第二个元素吗? 谢谢你的帮助,

如果我理解正确,您有一些共享相同 class 的预先存在的元素,并希望根据它们在 DOM 中的顺序为它们分配新的 ID。

您只有两个元素,但实际上是在对 select 每个元素单独进行循环。这并不是真正的 "d3 way" 做事,对于 d3 的许多常见任务来说,循环是不必要的。

让我们一次 select 所有图表并一次为所有元素分配新属性。我们可以通过两种方式做到这一点:

  • 根据每个元素的索引分配一个新的id
  • 根据我们绑定到 selected 元素的数据分配一个新 ID

方法一相当简单:

// select all charts and give them an id based on their index:
d3.selectAll(".chart")
  .attr("id", function(d,i) { return "Chart"+i; });
  
// adding buttons for demonstration:
d3.select("body").selectAll(null)
  .data([0,1,2])
  .enter()
  .append("p")
  .style("cursor","pointer")
  .text(function(d) { return "Chart:" + d; })
  .on("click", function(d) {
    d3.selectAll(".chart")
      .style("background-color","white");
    d3.select("#Chart"+d)
      .style("background-color","yellow");
  });
.chart {
  padding: 20px;
  display: inline-block;
  border: 1px dotted #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

<div class="chart">This is Chart 1</div>
<div class="chart">This is Chart 2</div>
<div class="chart">This is Chart 3</div>

<p> Select a div: </p>

但是,方法二也是如此,它还允许您轻松地为图表指定特定名称:

// deterimne some id's beforehand
var names = ["Chart1","Chart2","Chart3"];

// select all charts and bind the id array to it
// then set the id of each chart based on the bound data:
d3.selectAll(".chart")
  .data(names)
  .attr("id", function(d) { return d; });
  
// and buttons for demonstration:  
d3.select("body").selectAll(null)
  .data(names)
  .enter()
  .append("p")
  .style("cursor","pointer")
  .text(function(d) { return d; })
  .on("click", function(d) {
    d3.selectAll(".chart")
      .style("background-color","white");
    d3.select("#"+d)
      .style("background-color","yellow");
  });
.chart {
  padding: 20px;
  display: inline-block;
  border: 1px dotted #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

<div class="chart">This is Chart 1</div>
<div class="chart">This is Chart 2</div>
<div class="chart">This is Chart 3</div>

<p> Select a div: </p>


你的方法可以工作,它在下面进行了表面修改(这使得问题的陈述问题不可重现,但它有点 x,y 问题,因为你的问题可能真的是如何实现结果 ("how to access the second element"),而不是代码有什么问题),但您选择的方法有点超出通常的 d3 方法。这是您按预期工作的代码:

var names = ["chart2","chart1"]

function test() {

  if(d3.select(".chart")){
       let vari = d3.select(".chart");
       console.log("got here");
       vari.attr("id", names.pop()); 
       vari.attr("class", "substitute"); //I replace the css to be able to get to the second graph
                }
}

test();
test();

d3.select("#chart1")
  .style("border","1px solid black");
  
d3.select("#chart2")
  .style("background-color","#ccc");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

<div class="chart">Chart 1</div>
<div class="chart">Chart 2</div>