使用单独的固定x& d和d3.js画线。 y输入数组

时间:2014-04-26 02:07:27

标签: svg d3.js

我有单独的x和y数组,想要使用线路连接点。这似乎是关于最简单的可能示例,但我不太喜欢写函数。这是我的代码:

<!DOCTYPE html>
<meta charset="utf-8">

<body>
<script src = "http://d3js.org/d3.v3.min.js"> </script>
<script>

var margin = {top: 20, right: 20, bottom: 20, left: 20},
    width = 600 - margin.left - margin.right,
    height = 270 - margin.top - margin.bottom;

var xdata = d3.range(20);
var ydata = [1, 4, 5, 9, 10, 14, 15, 15, 11, 10, 5, 5, 4, 8, 7, 5, 5, 5, 8, 10];

var xscl = d3.scale.linear()
    .domain(d3.extent(xdata))
    .range([0, width])

var yscl = d3.scale.linear()
    .domain(d3.extent(ydata))
    .range([height, 0])

var slice = d3.svg.line()
    .x(function(d) { return xscl(xdata[d]);})
    .y(function(d) { return yscl(ydata[d]);})

var svg = d3.select("body")
    .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)

svg.append("path")
    .attr("class", "line")
    .attr("d", slice)

</script>
</body>

但它返回错误Uncaught TypeError: Cannot read property 'length' of undefined,因此d3.svg.line()返回的函数显然没有正确的形式。怎么了?我祈祷不是一个错字!

3 个答案:

答案 0 :(得分:6)

我知道已经有一年多了,但我也不得不处理这个问题。 将路径数据(x,y)存储在2个单独的数组中比2D数组d3.svg.line期望的内存效率高得多。对于非常多的点,通过循环遍历所有元素来创建2D数组,接受的答案也是低效的。

我在没有添加任何循环的情况下找到的解决方案是为d3.svg.line编写一个包装函数,如下所示:

var line = function(x, y){
    return d3.svg.line()
    .x(function(d,i) { return x[i]; }) 
    .y(function(d,i) { return y[i]; })
    (Array(x.length));
}

然后设置路径属性:

svg.append("path")
    .attr("d", line(x_array, y_array))

查看更新的小提琴here

答案 1 :(得分:3)

根据Elijah关于d3.svg.line的评论,我认为如果没有按照此功能的预期放置数组,我很难做到这一点。所以:

var xy = [];
for(var i=0;i<xdata.length;i++){
   xy.push({x:xdata[i],y:ydata[i]});
}

我对.domainslice功能本身做了其他更改。这是一个FIDDLE,其结果是我的努力。

答案 2 :(得分:1)

d3.svg.line只能占用一个数据源。但是,您可以通过将它们放入对象中来提供两个数据源:

newData = {x: xdata, y: ydata};

 var slice = d3.svg.line()
  .x(function(d,i) { return xscl(d.xdata[i]);})
  .y(function(d,i) { return yscl(d.ydata[i]);})

然后将你的行函数指向newData,你应该设置:

 svg.append("path")
  .attr("class", "line")
  .attr("d", slice(newData))

但是,通常,你最好建立一个坐标对数组,因为这是它所期望的。