如何在d3中修复此切换功能?

时间:2017-08-29 11:19:59

标签: d3.js toggle

我有两个问题:

1 /这些按钮(你可以运行下面的代码片段)应该在第二次点击时反转回原来的不透明度但是他们不会!有人可以解释一下我的代码有什么问题吗?

2 /如何在第二次点击时反转回text以前的颜色,而无需在切换功能中定义前一种颜色(再次!)。 ?

说明:正如您在运行以下代码段时所看到的那样,text(1,2,3 ...)在第一个white处转为click。我想在第二次点击时将其设置回原来的颜色,而不必写:

var newTextFill = active ? "white" : "**former_color**";

例如,在this example中,作者没有指定图例应该在第二次点击时返回的font-size,但您可以看到它缩小回原始大小。我怎么能用字体颜色做同样的事情?



 var name = ["123456789"];
 
 
 var color = d3.scaleOrdinal()
               .range(["#00baff", "#0014fe", "#00dbaf", "#f4bf02", "#ffa600",                        "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);
 
 
 var svg = d3.select("body")
             .append("svg")
             .attr("width", 300)
             .attr("height",300)
 
 var legende = svg.selectAll("bar")
                  .data(name)
                  .enter()
                  .append("g")
                  .attr("x",  0)
                  .attr("y", function (d,i) {return 12 + i * 20})

    legende.append("text")
           .text(function(d,i) { return name[i]})
           .attr("class", "legtext")
           .style("font-family", "helvetica")
           .style("fill-opacity", 0.8)
           .attr("x",  4)
           .attr("y", function (d,i) {return 12 + i * 20})
           .style("font-size", 10)
           .style("fill", function(d,i) { return color(i)})
           .style("text-decoration", "none")
           .style("opacity", 1);

    legende.append("rect")
           .attr("class", "recta")
           .attr("x",  2)
           .attr("y", function (d,i) {return 1 + i * 20})
           .attr("width", 65)
           .attr("height", 15)
           .style("fill", function(d,i) { return color(i)})
           .style("opacity", 0.09);

    legende.append("rect")
           .attr("class", "rectastroke")
           .attr("id", function(d,i) {return "str" + i})
           .attr("x",  2)
           .attr("y", function (d,i) {return 1 + i * 20})
           .attr("width", 65)
           .attr("height", 15)
           .style("stroke", function(d,i) { return color(i)})
           .style("stroke-width", 0.5) 
           .style("fill", "none")
           .attr("display", "none");
           
           
           
    legende.on("click", function (d,i) 
               {var active = d.active ? false : true;
                var newOpacity = active ? 1 : 0.1;
                var newTextFill = active ? "white" : "blue";
               
               d3.select(this)
                 .select("rect")
                 .style("opacity", newOpacity)
                 
                 
               d3.select(this)
                 .select("text")
                 .style("fill", newTextFill)
                 .raise()
                 
               d.active = active  });  
           
           
           
           
    legende.on("mouseover", function(d, i)      
        {d3.select(this).selectAll(".rectastroke").attr("display", "true")});
        
    legende.on("mouseout", function(d, i)      
        {d3.select(this).selectAll(".rectastroke").attr("display", "none")});    

body {font-family: 'Open Sans', sans-serif;
          font-size: 11px;
          font-weight: 300;
          fill: #242424;
          text-align: center;
          cursor: default;}
          
     .legende {cursor: pointer;}
     .recta {cursor: pointer;}

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>


  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

   

<body>
     <div class="colored buttons"></div>
</body>
</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

在您链接的bl.ocks中,实际上,她指定了图例在CSS中第二次点击时将返回的字体大小。

如果active为false,则设置者将返回undefined ...

d3.select(this)
    .style("font-size", function() {
        if (active) {return "25px"}
    })

... UA将根据CSS设置样式。

您可以对矩形执行相同的操作,而无需指定任何newOpacity

d3.select(this)
    .select("rect")
    .style("opacity", function() {
        if (active) return 1;
    })

以下是演示:

var data = "123456789".split("").map(function(d) {
  return {
    value: d
  }
});

var color = d3.scaleOrdinal()
  .range(["#00baff", "#0014fe", "#00dbaf", "#f4bf02", "#ffa600", "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);

var svg = d3.select("body")
  .append("svg")
  .attr("width", 300)
  .attr("height", 300)

var legende = svg.selectAll("bar")
  .data(data)
  .enter()
  .append("g")
  .attr("x", 0)
  .attr("y", function(d, i) {
    return 12 + i * 20
  })

legende.append("text")
  .text(function(d, i) {
    return d.value
  })
  .attr("class", "legtext")
  .style("font-family", "helvetica")
  .style("fill-opacity", 0.8)
  .attr("x", 4)
  .attr("y", function(d, i) {
    return 12 + i * 20
  })
  .style("font-size", 10)
  .style("fill", function(d, i) {
    return color(i)
  })
  .style("text-decoration", "none")
  .style("opacity", 1);

legende.append("rect")
  .attr("class", "recta")
  .attr("x", 2)
  .attr("y", function(d, i) {
    return 1 + i * 20
  })
  .attr("width", 65)
  .attr("height", 15)
  .style("fill", function(d, i) {
    return color(i)
  });

legende.on("click", function(d, i) {
  var active = d.active ? false : true;

  d3.select(this)
    .select("rect")
    .style("opacity", function() {
      if (active) return 1;
    })

  d3.select(this)
    .select("text")
    .style("fill", function(e, j) {
      if (active) {
        return "white";
      } else {
        return color(i)
      }
    })
    .raise()

  d.active = active
});
.legende {
  cursor: pointer;
}

.recta {
  opacity: 0.1;
  cursor: pointer;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

但是,对于文本颜色,由于您没有在CSS中指定它,因此您必须使用普通的if...else代码。