Как удалить эти ошибки журнала консоли D3.js - PullRequest
1 голос
/ 28 октября 2019

У меня есть ошибка, приведенная ниже, после того, как я попробовал некоторые другие способы решения проблемы (например, попытался предложить решение аналогичной проблемы) - успеха не было.

Error: <rect> attribute height: Expected length, "NaN"

Может кто-товзгляните на мой код и помогите мне изменить его так, чтобы эти ошибки исчезли?

Мой образец данных можно найти здесь .

Это , как выглядели ошибки до получения помощи из комментариев.

Это , как в настоящее время выглядят ошибки

Ниже приведен мой js-код:

Я не использую текущую последнюю версию D3.js - вместо этого яЯ использую старую версию 4

Я еще не настолько силен в D3.js (все еще учусь).

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// The scale spacing the groups:
var x0 = d3.scaleBand()
    .rangeRound([0, width])
    .paddingInner(0.1);

// The scale for spacing each group's bar:
var x1 = d3.scaleBand()
    .padding(0.05);

var y = d3.scaleLinear()
    .rangeRound([height, 0]);

var z = d3.scaleOrdinal()
    .range(["#008000", "#8a89a6", "#7b6888", "#008080", "#ff0000", "#d0743c", "#ff8c00"]);


   // trying to add tooltips 
var div = d3.select("body").append("div")   
    .attr("class", "tooltip")               
    .style("opacity", 0);

d3.csv("data.csv", function(d, i, columns) {
  for (var i = 1, n = columns.length; i < n; ++i) d[columns[i]] = +d[columns[i]];
  return d;
}, function(error, data) {
  if (error) throw error;

  var keys = data.columns.slice(1);

  x0.domain(data.map(function(d) { return d.years; }));
  x1.domain(keys).rangeRound([0, x0.bandwidth()]);
  y.domain([0, d3.max(data, function(d) { return d3.max(keys, function(key) { return d[key]; }); })]).nice();

 g.append("g")
    .selectAll("g")
    .data(data)
    .enter().append("g")
    .attr("class","bar")
    .attr("transform", function(d) { return "translate(" + x0(d.years) + ",0)"; })
    .selectAll("rect")
    .data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })
    .enter().append("rect")
      .attr("x", function(d) { return x1(d.key); })
      .attr("y", function(d) { return y(d.value); })
      .attr("width", x1.bandwidth())
      .attr("height", function(d) { return height - y(d.value); })
      .attr("fill", function(d) { return z(d.key); });

  g.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x0));

  g.append("g")
      .attr("class", "y axis")
      .call(d3.axisLeft(y).ticks(null, "s"))
    .append("text")
      .attr("x", 2)
      .attr("y", y(y.ticks().pop()) + 0.5)
      .attr("dy", "0.32em")
      .attr("fill", "#000")
      .attr("font-weight", "bold")
      .attr("text-anchor", "start")
      .text("ZAR");

  var legend = g.append("g")
      .attr("font-family", "sans-serif")
      .attr("font-size", 10)
      .attr("text-anchor", "end")
    .selectAll("g")
    .data(keys.slice().reverse())
    .enter().append("g")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

  legend.append("rect")
      .attr("x", width - 17)
      .attr("width", 15)
      .attr("height", 15)
      .attr("fill", z)
      .attr("stroke", z)
      .attr("stroke-width",2)
      .on("click",function(d) { update(d) });

  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 4.5)
      .attr("dy", "0.32em")
      .text(function(d) { return d;});


  var filtered = [];

  ////
  //// Update and transition on click:
  ////

  function update(d) {  

    //
    // Update the array to filter the chart by:
    //

    // add the clicked key if not included:
    if (filtered.indexOf(d) == -1) {
     filtered.push(d); 
      // if all bars are un-checked, reset:
      if(filtered.length == keys.length) filtered = [];
    }
    // otherwise remove it:
    else {
      filtered.splice(filtered.indexOf(d), 1);
    }

    //
    // Update the scales for each group(/years)'s items:
    //
    var newKeys = [];
    keys.forEach(function(d) {
      if (filtered.indexOf(d) == -1 ) {
        newKeys.push(d);
      }
    })
    x1.domain(newKeys).rangeRound([0, x0.bandwidth()]);
    y.domain([0, d3.max(data, function(d) { return d3.max(keys, function(key) { if (filtered.indexOf(key) == -1) return d[key]; }); })]).nice();

    // update the y axis:
            svg.select(".y")
            .transition()
            .call(d3.axisLeft(y).ticks(null, "s"))
            .duration(500);


    //
    // Filter out the bands that need to be hidden:
    //
    var bars = svg.selectAll(".bar").selectAll("rect")
      .data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); })

   bars.filter(function(d) {
         return filtered.indexOf(d.key) > -1;
      })
      .transition()
      .attr("x", function(d) {
        return (+d3.select(this).attr("x")) + (+d3.select(this).attr("width"))/2;  
      })
      .attr("height",0)
      .attr("width",0)     
      .attr("y", function(d) { return height; })
      .duration(500);

    //


    // Adjust the remaining bars:
    //
    bars.filter(function(d) {
        return filtered.indexOf(d.key) == -1;
      })
      .transition()
      .attr("x", function(d) { return x1(d.key); })
      .attr("y", function(d) { return y(d.value); })
      .attr("height", function(d) { return height - y(d.value); })
      .attr("width", x1.bandwidth())
      .attr("fill", function(d) { return z(d.key); })
      .duration(500);


    // update legend:
    legend.selectAll("rect")
      .transition()
      .attr("fill",function(d) {
        if (filtered.length) {
          if (filtered.indexOf(d) == -1) {
            return z(d); 
          }
           else {
            return "white"; 
          }
        }
        else {
         return z(d); 
        }
      })
      .duration(100);

      legend.selectAll("bar")
      .text(function(d, i) { return label[i]; });


  }

});

</script>

Ответы [ 2 ]

1 голос
/ 04 ноября 2019

Основной причиной этой проблемы являются дополнительные строки в конце файла данных. Когда метод d3.csv анализирует этот файл, он создаст массив данных с дополнительным элементом, где каждое значение равно NaN. Файл данных действительно имеет только 7 данных:

enter image description here

Поскольку ОП не хотел изменять файл CSV для удаления этих строк, мы можем обойтиневерные данные путем удаления плохих строк в обратном вызове d3.csv после анализа с помощью:

function(error, data) {
  if (error) throw error;
  // copy the columns since filter will remove this property
  let c = data.columns;
  // filter the data to remove the rows without a year
  data = data.filter(function(d){
    return d.years != "";
  })
  // add the columns property back in
  data.columns = c;

Вот код, работающий правильно .

1 голос
/ 31 октября 2019

Должна быть проблема с вашим y. Проверьте тип значения, возвращаемого y. Если возвращаемое значение является массивом или объектом, то любое математическое выражение, которое включает его, приведет к NaN (с исключением к +, объединяя значения в виде строк).

Скажем, например:

var x = 100 - [1, 2, 3] // returns NaN
var y = 100 / {} // returns NaN

Так что может быть проблема с этим:

.attr("height", function(d) { return height - y(d.value); })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...