单击按钮时 Rect 元素不过渡到数据点

Rect elements not transitioning to data point when button is clicked

//button event
var nextButton = d3.selectAll("#next");
nextButton.on("click", function(d, i){
    d3.selectAll("rect")
        .transition()
        .attr("duration", 2000)
        .attr("y", function(d){ return d.startDate })
});


var resetButton = d3.selectAll("#reset");
resetButton.on("click", function(d, i){
    d3.selectAll("rect")
        .transition()
        .duration(10000)
        .attr("y", 0)
});

当我单击按钮 ("next") 时,图表中的矩形元素不会移动或移动到与 y 轴上的数据对应的垂直位置。当我点击 "reset" 按钮时,矩形元素稍微移动但随后重置到起始位置。想不通怎么让点击"next"时动画生效

我曾尝试将函数设置为 return "d.startDate",但我没有经验,无法理解为什么这不起作用。

https://jsfiddle.net/g50c29Lp/ 处链接了我的图表示例和完整代码。如果你点击 next,什么也不会发生,如果你点击 return,元素会移动一点,然后按原样重置。

我希望当按下下一个按钮时,元素会根据它们的 "startDate" 或为什么数据值垂直排列。

我还是 d3 的新手,使用这张图表作为学习的方式,所以如果这让我完全无法理解,我深表歉意。

首先,duration是方法,不是属性。应该是:

d3.selectAll("rect")
    .transition()
    .duration(2000)
    //etc...

但这不是主要问题。主要问题是,无论出于何种原因,您对日期使用的是 band scale。您应该将日期视为日期,并改用 时间尺度

因此,由于您使用的是带刻度(我再次建议您更换它),所以不要解析字符串,删除所有这些:

const parse = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
  d.startDate = parse(d.startDate);
  d.endDate = parse(d.endDate);
});

此外,不要忘记使用 y 位置的比例尺。

这是您的代码,其中包含这些更改:

// set the dimensions and margins of the graph
var margin = {top: 50, right: 150, bottom: 50, left: 0},
    width = 600 - margin.left - margin.right,
    height = 350 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#main-chart").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform",
          "translate(" + 100 + "," + 20 + ")");

//declaring other variables
var barPadding = 1;

// append the data
d3.json('https://raw.githubusercontent.com/GideonBelete/employment/master/employment.json', function(data) { 

// X axis
var x = d3.scaleBand()
  .range([ 0, width ])
  .domain(data.map(function(d) { return d.Name; }))
  .padding(0.2);
svg.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x))
  .selectAll("text")
    .attr("transform", "translate(-10,0)rotate(-45)")
    .style("text-anchor", "end");

// Y axis
var y = d3.scaleBand()
    .range([ 0, height ])
    .domain(data.map(function(d) { return d.startDate; }))
    .padding(.1);
    svg.append("g")
    .attr("transform", "translate(-10,0)rotate(0)")
    .call(d3.axisLeft(y))

// create the squares
    svg.selectAll("rect")
    .data(data)
    .enter()
    .append("rect")
    .attr("x", function(d, i) {
        return i * (width / data.length - barPadding);
    })
    .attr("y", 0)
    .attr("width", 15)
    .attr("height", 15)

// mouse events
    .on("mouseover", function() {
        tooltip.style("display", null);
    })
    .on("mouseout", function() {
        tooltip.style("display", "none");
    })
    .on("mousemove", function(d) {
        var xPos = d3.mouse(this)[0] - 15;
        var yPos = d3.mouse(this)[1] - 55;
        tooltip.attr("tranform", "translate(" + xPos + "," + yPos + ")");
        tooltip.select("text").text(d.Name + " - " + d.Position);
    })

//button event
    var nextButton = d3.selectAll("#next");
    nextButton.on("click", function(d, i){
        d3.selectAll("rect")
            .transition()
            .duration(2000)
            .attr("y", function(d){ return y(d.startDate) })
    });
    

    var resetButton = d3.selectAll("#reset");
    resetButton.on("click", function(d, i){
        d3.selectAll("rect")
            .transition()
            .duration(2000)
            .attr("y", 0)
    });

// tooltip text
    var tooltip = svg.append("g")
        .attr("class", "tooltip")
        .style("display", "none");
    
    tooltip.append("text")
        .attr("x", 0)
        .attr("dy", -10)
        .style("font-size", "12px")
        .style("font-weight", "light");

// color for past/present employees
    d3.selectAll("rect")
        .each(function(d, i) {
            if (i === 1) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 2) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 3) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 5) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 7) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 9) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 10) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        })
        .each(function(d, i) {
            if (i === 11) {
                d3.select(this)
                .style("fill", "#C2C5CC")
            }
        });
});
.title {
  margin-top: 2em;
  text-align: center;
}

.title {
  font-family: 'Raleway', sans-serif;
  letter-spacing: 2px;
  cursor: default;
}

.title h1 {
  font-weight: 400;
}

.title h4 {
  font-weight: 300;
}

.divider {
  width: 50%;
  margin: 0 auto;
  border-bottom: 1px solid black;
  margin-top: 2em;
}

rect {
  fill: #49A99D;
}

svg {
  display: flex;
  justify-content: center;
}

text {
  font-family: 'Roboto', sans-serif;
}

.information {
  margin-top: 2em;
  width: 70%;
}

.button {
  width: 70%;
  display: flex;
  justify-content: flex-end;
}

#next {
  background: #49A99D;
  outline: none;
  border-radius: 3px;
  border: none;
  color: white;
  width: 60px;
  cursor: pointer;
  height: 20px;
  margin-left: 2em;
}

#next:active {
  background: #C2C5CC;
  outline: none;
  border-radius: 3px;
  border: none;
  color: white;
  width: 60px;
  cursor: pointer;
  height: 20px;
  margin-left: 2em;
}

#reset {
  background: #49A99D;
  outline: none;
  border-radius: 3px;
  border: none;
  color: white;
  width: 60px;
  cursor: pointer;
  height: 20px;
  margin-left: 2em;
}

#reset:active {
  background: #C2C5CC;
  outline: none;
  border-radius: 3px;
  border: none;
  color: white;
  width: 60px;
  cursor: pointer;
  height: 20px;
  margin-left: 2em;
}

.information h4 {
  font-weight: 300;
  font-family: 'Raleway', sans-serif;
  letter-spacing: 1px;
  font-size: 12px;
  cursor: default;
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://fonts.googleapis.com/css?family=Raleway:300,400,700,900&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <title></title>
</head>

<body>
  <div id="main-chart"></div>
  <div class="information">
  </div>
  <div class="button">
    <button id="reset">Reset</button>
    <button id="next">Next</button>
  </div>

  <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
  <script src="app.js"></script>
</body>

</html>