【问题标题】:Find original color of element before mouseover在鼠标悬停之前查找元素的原始颜色
【发布时间】:2018-04-10 03:51:28
【问题描述】:

我有一个气泡图,我在其中按以下方式制作气泡:

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")
          });

我根据学生的百分位数为气泡赋予了红色、黄色、绿色的颜色。在鼠标悬停时,我将气泡的颜色更改为“橙色”。现在的问题是,在鼠标悬停时,目前我正在将气泡的颜色设置为“蓝色”,但我想为它们分配与鼠标悬停之前相同的颜色,即红色/绿色/黄色。我如何找出气泡是什么颜色的? 一种方法是显然检查学生的百分位数,然后根据它给出颜色(就像我最初指定的绿色/黄色/红色一样),但是有没有直接的方法可以找到气泡的实际颜色? 提前致谢!

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

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

    解决方案 1:

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

    var previous;
    

    ...您分配给mouseover...上的元素颜色...

     previous = d3.select(this).style("fill");
    

    ...并在mouseout中重用:

    d3.select(this).style("fill", previous)
    

    这是一个演示:

    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)
      })
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>

    解决方案 2:

    不过,D3 有一个很好的特性,称为局部变量。您只需定义本地...

    var local = d3.local();
    

    ...,设置在mouseover:

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

    然后,在mouseout 上获取它的值:

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

    这里是演示:

    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));
      })
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>

    解决方案 3:

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

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

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

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

    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);
      })
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>

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

    PS:丢弃那一堆if...else 来设置气泡的样式。改用秤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 2020-01-28
      • 1970-01-01
      相关资源
      最近更新 更多