首页 > 解决方案 > 轴对齐 - 类型错误:无法读取 null 的属性“长度”

问题描述

我正在制作一个散点图,但尽管这些点在视觉上与 y 轴对齐,但我没有通过检查这一点的测试,我得到:

无法读取 null 的属性“长度”TypeError:无法 在 NodeList.forEach ()的https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:622:120652处读取 null 的属性“长度”在 Y ( https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:622:119636 ) 在 r。( https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:622:200083 ) 在 c ( https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle. js:570:31654 ) 在 ofrun ( https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:570:31590 ) 在 m.runTest ( https://cdn.freecodecamp.org/可测试项目-fcc/v1/bundle.js:570:37160)在https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:570:38022 at s ( https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js: 570:36472)在https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js:570:36541

测试如下:

var e=document.querySelector("#y-axis"),t=document.querySelectorAll(".dot"),r=e.querySelectorAll(".tick");s.assert.isTrue(Y(t,r,"cy","data-yvalue","minute","center"),"y values don't line up with y locations ")

这是我的代码:

document.addEventListener("DOMContentLoaded", function() {
  function convertToMMSS(originalSeconds) {
    let minutes = Math.floor(originalSeconds / 60);
    let seconds = originalSeconds % 60;
    let date = new Date();
    date.setMinutes(minutes);
    date.setSeconds(seconds);
    let formatTime = d3.timeFormat("%M:%S");
    let mmss = formatTime(date);
    let parseTime = d3.timeParse("%M:%S");
    return parseTime(mmss);
  }

  function formatDate(originalSeconds) {
    let minutes = Math.floor(originalSeconds / 60);
    let seconds = originalSeconds % 60;
    seconds = seconds >= 10 ? seconds : "0" + seconds;
    let time = minutes + ":" + seconds;
    return time;
  }

  $.getJSON(
    "https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json",
    function(dataset) {
      console.log(dataset);
      const w = 800;
      const h = 600;
      const padding = 60;
      const xScale = d3
        .scaleLinear()
        .domain([
          d3.min(dataset, (d, i) => dataset[i].Year) - 1,
          d3.max(dataset, (d, i) => dataset[i].Year)
        ])
        .range([padding, w]);
      const yScale = d3
        .scaleTime() //linear d3.extent
        .domain([
          d3.min(dataset, (d, i) => dataset[i].Seconds),
          d3.max(dataset, (d, i) => dataset[i].Seconds)
        ])
        .range([h - padding, 0]);
      const yAxisScale = d3
        .scaleTime()
        .domain([
          d3.min(dataset, (d, i) => convertToMMSS(dataset[i].Seconds)),
          d3.max(dataset, (d, i) => convertToMMSS(dataset[i].Seconds))////
        ])
        .range([0, h - padding]);
      const tooltip = d3
        .select("body")
        .append("div")
        .attr("class", "tooltip")
        .attr("id", "tooltip");
      const container = d3
        .select("body")
        .append("svg")
        .attr("height", h + padding)
        .attr("width", w + padding);
      container
        .selectAll("circle")
        .data(dataset)
        .enter()
        .append("circle")
        .attr("class", "dot")
        .attr("data-xvalue", d => d.Year)
        .attr("data-yvalue", d => convertToMMSS(d.Seconds))
        .attr("cx", d => xScale(d.Year))
        .attr("cy", d => h - yScale(d.Seconds))
        .attr("r", 5)
        .attr("fill", (d, i) => {
          return dataset[i].Doping != "" ? "red" : "green";
        })
        .on("mouseover", (d, i) => {
          tooltip
            .text(d.Year + " " + formatDate(d.Seconds))
            .style("left", d3.event.pageX + "px")
            .style("top", d3.event.pageY - 28 + "px")
            .style("opacity", 1)
            .attr("data-year", () => dataset[i].Year);
        })
        .on("mouseout", () => {
          tooltip.style("opacity", 0);
        });
      const xAxis = d3.axisBottom(xScale).tickFormat(d3.format("d"));
      container
        .append("g")
        .attr("id", "x-axis")
        .attr("transform", "translate(0," + h + ")")
        .call(xAxis);
      const yAxis = d3.axisLeft(yAxisScale).tickFormat(d3.timeFormat("%M:%S"));
      container
        .append("g")
        .attr("id", "y-axis")
        .attr("transform", "translate(" + padding + "," + padding + ")")
        .call(yAxis);
    }
  );
});
body {
  margin: 10vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: Monospace;
}

h1 {
  text-align: center;
  font-size: 35px;
}

.tooltip {	
  position: absolute;			
  text-align: center;			
  width: 100px;								
  padding: 2px;				
  font: 12px sans-serif;		
  background-color: white;	
  border: 1px solid black;		
  border-radius: 2px;			
  pointer-events: none;		
  color: black;
  opacity: 0;
}

#legend {
  position: absolute;
  z-index: 9999;
  margin-top: 30%;
  margin-left: 18%;
}

.bar {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.green-box {
  background-color: green;
  height: 20px;
  width: 20px;
}

.red-box {
  background-color: red;
  height: 20px;
  width: 20px;
}

h4 {
  margin: 1em;
  font-size: 15px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-scale/1.0.7/d3-scale.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h1 id="title">Doping in Professional Bicycle Racing</h1>

<div id="legend">
  <div class="bar">
    <div class="green-box"></div>
    <h4>No doping allegations</h4>
  </div>
  <div class="bar">
    <div class="red-box"></div>
    <h4>Riders with doping allegations</h4>
  </div>
</div>

这是我的

任何建议,将不胜感激!

标签: javascriptd3.jsmocha.jschai

解决方案


推荐阅读