d3 的值<path>无效



我是d3.js的新手,下面是http://code.tutsplus.com/tutorials/building-a-multi-line-chart-using-d3js-part-2--cms-22973为我的应用程序构建嵌套的时间序列。

然而,尽管数据看起来像示例中的嵌套数据,我还是遇到了这个错误

Error: Invalid value for <path> attribute d="MNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaN"

我的代码在这里,jsfiddle在http://jsfiddle.net/absail/h9hds98f/

nested_data = [{"key":"False","values":[{"date":"09/04/2015","val":0},{"date":"09/05/2015","val":222},{"date":"09/06/2015","val":168},{"date":"09/07/2015","val":203},{"date":"09/08/2015","val":219},{"date":"09/09/2015","val":237},{"date":"09/10/2015","val":241},{"date":"09/11/2015","val":397},{"date":"09/12/2015","val":158},{"date":"09/13/2015","val":154},{"date":"09/14/2015","val":193},{"date":"09/15/2015","val":202},{"date":"09/16/2015","val":218},{"date":"09/17/2015","val":466},{"date":"09/18/2015","val":439},{"date":"09/19/2015","val":278},{"date":"09/20/2015","val":271},{"date":"09/21/2015","val":475},{"date":"09/22/2015","val":494},{"date":"09/23/2015","val":498},{"date":"09/24/2015","val":503},{"date":"09/25/2015","val":437},{"date":"09/26/2015","val":286},{"date":"09/27/2015","val":280},{"date":"09/28/2015","val":496},{"date":"09/29/2015","val":514}]},{"key":"True","values":[{"date":"09/05/2015","val":3170},{"date":"09/11/2015","val":8643},{"date":"09/04/2015","val":0},{"date":"09/08/2015","val":6146},{"date":"09/12/2015","val":2414},{"date":"09/14/2015","val":5711},{"date":"09/19/2015","val":4118},{"date":"09/26/2015","val":3990},{"date":"09/06/2015","val":2565},{"date":"09/09/2015","val":6426},{"date":"09/13/2015","val":2514},{"date":"09/15/2015","val":5690},{"date":"09/16/2015","val":6222},{"date":"09/17/2015","val":10858},{"date":"09/18/2015","val":9718},{"date":"09/20/2015","val":4006},{"date":"09/21/2015","val":11135},{"date":"09/23/2015","val":11264},{"date":"09/25/2015","val":8831},{"date":"09/27/2015","val":3984},{"date":"09/28/2015","val":11554},{"date":"09/07/2015","val":5562},{"date":"09/10/2015","val":6505},{"date":"09/22/2015","val":11405},{"date":"09/24/2015","val":11411},{"date":"09/29/2015","val":12086}]}];
var parseDate = d3.time.format("%m/%d/%Y").parse;
var color = d3.scale.category10();
var vis = d3.select("#visualisation"),
WIDTH = 1000,
HEIGHT = 500,
MARGINS = {
    top: 50,
    right: 20,
    bottom: 50,
    left: 50
},
lSpace = WIDTH/nested_data.length;
xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(nested_data, function(d) {
    return d.date;
}), d3.max(data, function(d) {
    return d.date;
})]),
yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(nested_data, function(d) {
    return d.val;
}), d3.max(data, function(d) {
    return d.val;
})]),
xAxis = d3.svg.axis()
.scale(xScale),
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
vis.append("svg:g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
  .call(xAxis);
vis.append("svg:g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + (MARGINS.left) + ",0)")
  .call(yAxis);
var lineGen = d3.svg.line()
.x(function(d) {
    return xScale(d.date);
})
.y(function(d) {
    return yScale(d.val);
});
// .interpolate("basis");
// Loop through each symbol / key
nested_data.forEach(function(d, i) {
    vis.append('svg:path')
    .attr('d', lineGen(d.values))
    .attr('stroke', function(d,j) { 
            return "hsl(" + Math.random() * 360 + ",100%,50%)";
    })
    .attr('stroke-width', 2)
    .attr('id', 'line_'+d.key)
    .attr('fill', 'none');
    vis.append("text")
        .attr("x", (lSpace/2)+i*lSpace)
        .attr("y", HEIGHT)
        .style("fill", "black")
        .attr("class","legend")
        .on('click',function(){
            var active   = d.active ? false : true;
            var opacity = active ? 0 : 1;
            d3.select("#line_" + d.key).style("opacity", opacity);
            d.active = active;
        })
        .text(d.key);
});

我意识到这是其他人面临的常见错误,但似乎每次的解决方案都不一样。一些建议包括解析日期,但这似乎并没有解决我的问题。任何帮助都将不胜感激,因为我已经盯着这个问题看了好几个小时了。谢谢

错误1:

计算最大值和最小值的方法是错误的:

yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(nested_data, function(d) {
    return d.val;
}), d3.max(data, function(d) {
    return d.val;
})]),

这里nested_data是一个具有值数组的对象数组。因此,max-min将无法正常工作。

修复:

你需要收集数组中的所有值,并制作一个像这样的数组:

//get the array of all values.
var arrays = nested_data.map(function (k) {
    return k.values
});
var collect = [].concat.apply([], arrays);

错误2:

未正确处理代码中的日期。

xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(nested_data, function(d) {
    return d.date;
}), d3.max(data, function(d) {
    return d.date;//this is a string d3 does not know its a date
})]),

修复:

你需要像这个一样把它转换成日期

var parseDate = d3.time.format("%m/%d/%Y").parse;
//get the array of all values.
var arrays = nested_data.map(function (k) {
    return k.values
});
var collect = [].concat.apply([], arrays);
//converting date
collect.forEach(function(d){d.date1 = parseDate(d.date)});

然后x轴最大最小函数将类似

xScale = d3.time.scale().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(collect, function (d) {
    return d.date1;
}), d3.max(collect, function (d) {
    return d.date1;
})]),
yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(collect, function (d) {
    return d.val;
}), d3.max(collect, function (d) {
    return d.val;
})]),

完整的工作纠正代码在这里

希望这能有所帮助!

问题是,您将错误的值设置为xScaleyScaledomain。要设置正确的域值,您应该更改如下所示的数据结构,然后使用数据数组来设置域。

var data = [{"date":"09/04/2015","val":0,"status":false},
{"date":"09/05/2015","val":222,"status":false},
{"date":"09/06/2015","val":168,"status":false},
{"date":"09/07/2015","val":203,"status":false},
{"date":"09/08/2015","val":219,"status":false}, 
{"date":"09/09/2015","val":237,"status":false},
{"date":"09/10/2015","val":241,"status":false},   
{"date":"09/11/2015","val":397,"status":false},  
{"date":"09/12/2015","val":158,"status":false},
{"date":"09/13/2015","val":154,"status":false},
{"date":"09/14/2015","val":193,"status":false},
{"date":"09/15/2015","val":202,"status":false},
{"date":"09/16/2015","val":218,"status":false},
{"date":"09/17/2015","val":466,"status":false},
{"date":"09/18/2015","val":439,"status":false},
{"date":"09/19/2015","val":278,"status":false},
{"date":"09/20/2015","val":271,"status":false},
{"date":"09/21/2015","val":475,"status":false},
{"date":"09/22/2015","val":494,"status":false},
{"date":"09/23/2015","val":498,"status":false},
{"date":"09/24/2015","val":503,"status":false},
{"date":"09/25/2015","val":437,"status":false},
{"date":"09/26/2015","val":286,"status":false},
{"date":"09/27/2015","val":280,"status":false},
{"date":"09/28/2015","val":496,"status":false},
{"date":"09/29/2015","val":514,"status":false},   
{"date":"09/05/2015","val":3170,"status":true},  
{"date":"09/11/2015","val":8643,"status":true},
{"date":"09/04/2015","val":0,"status":true},
{"date":"09/08/2015","val":6146,"status":true},
{"date":"09/12/2015","val":2414,"status":true},
{"date":"09/14/2015","val":5711,"status":true},
{"date":"09/19/2015","val":4118,"status":true},
{"date":"09/26/2015","val":3990,"status":true},
{"date":"09/06/2015","val":2565,"status":true},
{"date":"09/09/2015","val":6426,"status":true},
{"date":"09/13/2015","val":2514,"status":true},
{"date":"09/15/2015","val":5690,"status":true},
{"date":"09/16/2015","val":6222,"status":true},
{"date":"09/17/2015","val":10858,"status":true},
{"date":"09/18/2015","val":9718,"status":true},
{"date":"09/20/2015","val":4006,"status":true},
{"date":"09/21/2015","val":11135,"status":true},
{"date":"09/23/2015","val":11264,"status":true},
{"date":"09/25/2015","val":8831,"status":true},
{"date":"09/27/2015","val":3984,"status":true},
{"date":"09/28/2015","val":11554,"status":true},
{"date":"09/07/2015","val":5562,"status":true},
{"date":"09/10/2015","val":6505,"status":true},
{"date":"09/22/2015","val":11405,"status":true},
{"date":"09/24/2015","val":11411,"status":true},
{"date":"09/29/2015","val":12086,"status":true}];
var nested_data = d3.nest()
   .key(function(d) {
      return d.status;
   })
   .entries(data);
var xScale = d3.scale.linear()
   .range([MARGINS.left, WIDTH - MARGINS.right])
   .domain([d3.min(data, function(d) {
        return new Date(d.date);
   }), d3.max(data, function(d) {       
        return new Date(d.date);
   })]),
yScale = d3.scale.linear()
   .range([HEIGHT - MARGINS.top, MARGINS.bottom])
   .domain([d3.min(data,function(d) {
       return d.val;
   }), d3.max(data, function(d) {
       return d.val;
   })]);

保持nested_data数组的原样,并生成日期和值的总列表以设置查找域值。

var allValues = nested_data.map(function(d){ return d.values }).reduce(function(a,b){ return d3.merge([a,b]); });
var xScale = d3.scale.linear()
   .range([MARGINS.left, WIDTH - MARGINS.right])
   .domain([d3.min(allValues, function(d) {
        return new Date(d.date);
   }), d3.max(allValues, function(d) {       
        return new Date(d.date);
   })]),
yScale = d3.scale.linear()
   .range([HEIGHT - MARGINS.top, MARGINS.bottom])
   .domain([d3.min(allValues,function(d) {
       return d.val;
   }), d3.max(allValues, function(d) {
       return d.val;
   })]);

注意:也使用new Date(d.date);而不是d.date

相关内容

最新更新