首页 > 解决方案 > 无法在 d3.js 中执行类转换

问题描述

为什么我不能在 d3.js 中执行类转换?

main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>d3 playing around</title>
    <link rel="stylesheet" href="main.css">
    <!-- <script src="d3LibV5Min.js"></script> -->
    <script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>

    <div id="drawRegion">

    </div>

    <script src="main.js"></script>
</body>
</html>

main.css

#drawRegion {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

#drawRegion .mainSvg {
    border: 2px #000 solid;
    background: #ddd953;
    width: 500px;
    height: 500px;
}

#drawRegion .mainSvg .blackCircle {
    border: 2px #fff solid;
    background: #000;
}

#drawRegion .mainSvg .whiteCircle {
    border: 2px #000 solid;
    background: #fff;
}

main.js

var drawRegion = d3.select("#drawRegion");

var svg = drawRegion
    .append("svg")
    .classed("mainSvg", true);

var circle = svg
    .append("circle")
    .attr("cx", 250)
    .attr("cy", 250)
    .attr("r", 50)
    .classed("blackCircle", true);

var tr = d3
    .transition()
    .duration(5000);
circle
    .transition(tr)
    .classed("blackCircle", false)
    .classed("whiteCircle", true);

我期望从这段代码中做的是显示一个带有白色边框的黑色圆圈,并在 5 秒后逐渐过渡到一个带有黑色边框的白色圆圈。但这不会发生。我d3.js这里学习,根据教程,我做的一切都是正确的。

是小提琴。将不胜感激这里提供的任何帮助。

我知道其他方法,例如,使用css-transitions,但我想感受它的力量,d3.js因为我决定深入学习它。

标签: javascriptd3.js

解决方案


简而言之,您正在尝试这样做:

circle.classed("blackCircle",true);

circle.transition()
  .classed("blackCircle",false);
  .classed("whiteCircle",true);

问题是过渡不提供classed方法。如果您查看收到的错误消息,您可以确认:circle.transition(...).classed is not a function. (有关可用方法,请参阅文档) d3 转换在起始值和结束值之间进行插值 - 由于布尔值是真或假,因此仅使用这两个值很难在这两个点之间进行转换。因此,classed不能成为当前形式的 d3 转换方法。

如果您希望它与 d3 一起使用,您可以放弃类方法并直接使用selection.style()and应用样式transition.style()

例如:

var svg = d3.select("body")
  .append("svg");
  
var circle = svg.append("circle")
  .attr("cx",100)
  .attr("cy",50)
  .attr("r", 20)
  .style("fill","steelblue");
  
var t = d3.transition()
  .duration(3000);
  
circle.transition(t)
  .style("fill","orange");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

我还会添加类似的内容:

circle.attr("class","whiteCircle");

circle.transition().attr("class","blackCircle");

尽管 .attr() 是 d3.transition() 的一种方法,但也不能正常工作。这是因为插值器将尝试使用d3.interpolateString在开始和结束之间插入字符串值。给定两个没有数字的字符串,第二个值将用于转换的所有点(参见this fiddle)。

此外,您使用背景作为 svg 圆圈的 css 属性,在使用 svg 元素时需要使用填充。同样,您需要使用笔画、笔画宽度等来代替边框


推荐阅读