我正在尝试使用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>
控制台输出在这里:
答案 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]);
假设width
和height
都是正数,那么从比例中获得负输出值的唯一方法是输入一个小于X比例的最小域值的数字或者超过Y标度上的最大域值 - 这意味着最大/最小函数没有达到预期的效果。
d3.max
和d3.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]));
}