D3散点图未显示

时间:2014-04-09 23:12:03

标签: javascript d3.js

我正在尝试使用D3进行散点图,但这些点没有显示出来。我可以看到在控制台中生成的圆圈。有谁知道为什么?

<script>
var rawData= ...;
function plotData(data){
          var concentration = [],
              uptake = [];
          for (var i=1; i<data.length; i++) {
            concentration.push(data[i][3]);
            uptake.push(data[i][4]);
          }
          var width = 1000, height = 800;
          var x = d3.scale.linear()
                    .domain([d3.min(concentration)-20, d3.max(concentration)+20])
                    .range([0, width]);
          var y = d3.scale.linear()
                    .domain([d3.min(uptake)-20, d3.max(uptake)+20])
                    .range([height, 0]);
          var svg = d3.select("#scatter").append("svg")
                      .attr("width", width)
                      .attr("height", height);
          svg.selectAll("scatterplot")
             .data(uptake)
             .enter().append("svg:circle")
             .attr("cy", function(d) {return y(d); } )
             .attr("cx", function(d,i) {return x(concentration[i]); } )
             .style("fill", "brown")
             .attr("r", 3);
     }
</script>
<body>
  <div>
    <button onclick="plotData(rawData)">Visualize</button>
  </div>
  <hr />
  <div id=scatter class=visualization></div>
</body>

控制台输出在这里: Console Output

1 个答案:

答案 0 :(得分:1)

DOM检查器显示您的程序正在为您的点分配负cx和cy值。由于您使用线性比例来设置这些属性,这表明您的比例范围或域存在问题。

您将比例定义为:

  var x = d3.scale.linear()
            .domain([d3.min(concentration)-20, d3.max(concentration)+20])
            .range([0, width]);
  var y = d3.scale.linear()
            .domain([d3.min(uptake)-20, d3.max(uptake)+20])
            .range([height, 0]);

假设widthheight都是正数,那么从比例中获得负输出值的唯一方法是输入一个小于X比例的最小域值的数字或者超过Y标度上的最大域值 - 这意味着最大/最小函数没有达到预期的效果。

d3.maxd3.min出现意外结果的最可能原因是您要对存储为字符串的数字进行排序。它甚至被称为警告in the API - 如果您的数字存储为字符串,它们将按字母顺序进行比较,而不是按数值进行比较。

您的线性比例仍然有效,因为它们将任何输入值强制转换为数字,因此您不会从编译器中获得任何错误,只会产生意外结果。

解决方案(如@Boxuan发现,请参阅注释)只是为了确保在将它们传递给max和min函数之前将所有数字都存储起来。因为您的代码中已经有一个循环,您正在重新组织数据,这是一个自然的解析位置:

  for (var i=1; i<data.length; i++) {
    concentration.push(parseFloat(data[i][3]));
    uptake.push(parseFloat(data[i][4]));
  }