首页 > 解决方案 > 更改类时未应用 D3 css

问题描述

我有一个条形图,我想在单击条形时更改颜色。我想在单击的元素上设置一个 CSS 类。除了填充样式(单击的栏的颜色)没有改变之外,一切正常,但应用了绿色笔触。我不明白为什么。

这是点击图表最后一个柱之前和之后的屏幕 在此处输入图像描述

这就是我想要实现的 在此处输入图像描述

这是我的代码的一部分,有什么建议吗?

JS

//CREATE THE BAR CHART
var bars = d3
  .select("#bars")
  .selectAll("rect")
  .data(data);

bars
  .enter()
  .append("rect")
  .attr("x", function(d) {
    return xScale(d.year);
  })
  .attr("y", function(d) {
    return yScale(d.cost);
  })
  .attr("width", xScale.bandwidth)
  .attr("height", function(d) {
    return height - yScale(d.cost);
  })
  .style("fill", function(d) {
    return colorScale(d.cost);
  });

//EVENT ON CLICK
d3.select("#bars")
  .selectAll("rect")
  .on("click", function() {
    //reset the previus bar selected
    d3.select("#bars")
      .select(".selected")
      .classed("selected", false)
      .style("fill", function(d) {
        return colorScale(d.cost);  //reset the original color
      });
    //set the current bar as selected
    d3.select(this).classed("selected", true);
  });

CSS

.selected {
  fill: red;
  stroke: green;
  stroke-width: 3;
}

标签: javascripthtmlcssd3.js

解决方案


通常,属性样式会被 CSS 样式使用选择器覆盖,而后者又会被内联 CSS 样式覆盖。

  • .attr("fill", "blue")设置属性fill="blue"
  • .selected { fill: "red"; }应用样式fill: red;
  • .style("fill", "green")设置属性style="fill: steelblue;",内联样式。

如果将所有这些应用于同一元素,则最后一个具有优先权。通过取消选择先前选择的条,您将其赋予.style("fill",从而覆盖任何潜在的未来样式。我建议检查你是否真的需要应用这些样式,.attr()如果需要就使用。

我在下面添加了一个小展示。

let settings = {
  attr: false,
  class: false,
  style: false,
};
draw();

function draw() {
  d3.select("rect")
    .attr("fill", settings.attr ? "red" : null)
    .attr("class", settings.class ? "blue" : "")
    .style("fill", settings.style ? "green" : null);
}

d3.selectAll("[type='checkbox']")
  .on("change", function() {
    settings[this.getAttribute("id")] = this.checked;
    draw();
  });
.blue {
  fill: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div>
  <input type="checkbox" id="attr"/><label for="attr">attr</label>
  <input type="checkbox" id="class"/><label for="class">class</label>
  <input type="checkbox" id="style"/><label for="style">style</label>
</div>
<svg>
  <rect width="30" height="30"></rect>
</svg>


推荐阅读