我正在尝试使用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>
控制台输出在这里:
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标尺的最大域值-这意味着max / min函数没有达到您的期望。
d3.max
和产生意外结果的最可能原因d3.min
是您正在对存储为字符串的数字进行排序。在API中甚至提到它作为警告-如果您的数字存储为字符串,则将按字母顺序而不是数字值对它们进行比较。
您的线性比例尺仍然有效,因为它们将任何输入值都强制转换为数字,因此您不会从编译器中得到任何错误,而只是得到意想不到的结果。
解决方案(如@Boxuan发现的,请参阅注释)仅是要确保将所有数字存储为照原样,然后再将它们传递给max和min函数。由于您的代码中已经有一个循环,您需要在其中重新组织数据,因此很自然地进行了解析:
for (var i=1; i<data.length; i++) {
concentration.push(parseFloat(data[i][3]));
uptake.push(parseFloat(data[i][4]));
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句