在鼠标悬停之前找到元素的原始颜色

时间:2017-10-28 19:37:10

标签: javascript d3.js

我有一个气泡图,我可以通过以下方式制作气泡:

var circles = svg.selectAll(null)
          .data(data)
          .enter()
          .append("circle")
          .attr("cx", width / 2)
          .attr("cy", height / 2)
          .attr("opacity", 0.3)
          .attr("r", 20)
          .style("fill", function(d){
            if(+d.student_percentile <= 40){
                return "red";
            }
            else if(+d.student_percentile > 40 && +d.student_percentile <= 70){
                return "yellow";
            }
            else{
                return "green";
            }
          })
          .attr("cx", function(d) {
            return xscale(+d.student_percentile);
          })
          .attr("cy", function(d) {
            return yscale(+d.rank);
          })
          .on('mouseover', function(d, i) {
            d3.select(this)
              .transition()
              .duration(1000)
              .ease(d3.easeBounce)
              .attr("r", 32)
              .style("fill", "orange")
              .style("cursor", "pointer")
              .attr("text-anchor", "middle");
               texts.filter(function(e) {
                    return +e.rank === +d.rank;
               })
              .attr("font-size", "20px");
            }
           )
          .on('mouseout', function(d, i) {
            d3.select(this).transition()
              .style("opacity", 0.3)
              .attr("r", 20)
              .style("fill", "blue")
              .style("cursor", "default");
              texts.filter(function(e) {
                return e.rank === d.rank;
              })
            .transition()
            .duration(1000)
            .ease(d3.easeBounce)
            .attr("font-size", "10px")
          });

根据学生的百分位数,我给了气泡红色,黄色,绿色。在鼠标悬停时,我将气泡的颜色更改为&#39; orange&#39;。现在的问题是,在mouseout上,目前我正在制作气泡颜色为&#39; blue&#39;但我想为它们分配与鼠标悬停前相同的颜色,即红色/绿色/黄色。我如何找出气泡的颜色? 一种方法是明显检查学生的百分位数,然后根据它给出颜色(就像我最初分配绿色/黄色/红色),但有没有直接的方法来找到泡沫的实际颜色? 提前谢谢!

1 个答案:

答案 0 :(得分:3)

有几种方法可以做到这一点。

解决方案1:

最明显的一个是声明一个变量......

var previous;

...您要为mouseover ...

上的元素颜色指定
 previous = d3.select(this).style("fill");

...并在mouseout

中重复使用
d3.select(this).style("fill", previous)

这是一个演示:

&#13;
&#13;
var svg = d3.select("svg");
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var previous;
var circles = svg.selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("cy", 75)
  .attr("cx", function(d, i) {
    return 50 + 50 * i
  })
  .attr("r", 20)
  .style("fill", function(d, i) {
    return colors(i)
  })
  .on("mouseover", function() {
    previous = d3.select(this).style("fill");
    d3.select(this).style("fill", "#222");
  }).on("mouseout", function() {
    d3.select(this).style("fill", previous)
  })
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
&#13;
&#13;

解决方案2:

然而,D3有一个很好的功能,称为局部变量。你只需要定义本地...

var local = d3.local();

...,将其设置在mouseover

local.set(this, d3.select(this).style("fill"));

然后,在mouseout

上获取其值
d3.select(this).style("fill", local.get(this));

以下是演示:

&#13;
&#13;
var svg = d3.select("svg");
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var local = d3.local();
var circles = svg.selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("cy", 75)
  .attr("cx", function(d, i) {
    return 50 + 50 * i
  })
  .attr("r", 20)
  .style("fill", function(d, i) {
    return colors(i)
  })
  .on("mouseover", function() {
    local.set(this, d3.select(this).style("fill"));
    d3.select(this).style("fill", "#222");
  }).on("mouseout", function() {
    d3.select(this).style("fill", local.get(this));
  })
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
&#13;
&#13;

解决方案3:

由于DDD(也称为D3)表示数据驱动文档,您可以使用绑定数据来获取以前的颜色。

首先,你设置它(在我的演示中,使用colors比例):

.style("fill", function(d, i) {
    return d.fill = colors(i);
})

然后你在mouseout中使用它。查看演示:

&#13;
&#13;
var svg = d3.select("svg");
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var circles = svg.selectAll(null)
  .data(d3.range(5).map(function(d) {
    return {
      x: d
    }
  }))
  .enter()
  .append("circle")
  .attr("cy", 75)
  .attr("cx", function(d) {
    return 50 + 50 * d.x
  })
  .attr("r", 20)
  .style("fill", function(d, i) {
    return d.fill = colors(i);
  })
  .on("mouseover", function() {
    d3.select(this).style("fill", "#222");
  }).on("mouseout", function(d) {
    d3.select(this).style("fill", d.fill);
  })
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
&#13;
&#13;

对于使用此解决方案#3,元素的数据必须是一个对象。

PS:放下一堆if...else来设置气泡的样式。请改用比例。