我正在尝试根据CSV文件中的某些数据生成图表。
我的代码:
<script>
var svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 1000);
function render(data){
var circles = svg.selectAll("circle").data(data);
circles.enter().append("circle")
.attr("r", 1);
circles
.attr("cx", function (d){return d[' Monthly Term']})
.attr("cy", function (d){ return d[' Principal Balance']/1000});
circles.exit().remove();
}
d3.csv("{% static "data/Total.csv" %}" , type, function(myArray){
render(myArray);
myArray.forEach(function(d){
console.log(d[' Principal Payment'] + ", " + d[' Interest Payment'] + ", " + d[' Principal Balance'] + ", " +d[' Monthly Term']);
});
});
function type(d){
d.value = +d.value;
return d;
}
</script>
不确定你们是否可以看到检查窗口,但是随着x值的增加,Y值应该会减少。
有什么想法吗?
答案 0 :(得分:3)
在控制台输出中,Y值随着X值的增加而减小。在SVG中,0,0位置在左上角。因此较低的Y值更接近屏幕顶部。尝试反转Y值:
.attr("cy", function (d){ return height - d[' Principal Balance']/1000});
答案 1 :(得分:2)
正如@genestd在他的回答中所述,SVG y坐标从顶部开始并且值向下移动。通常,您应该使用d3 scale将用户空间值映射到 svg坐标值。查看classic bar chart example,您会看到以下这些行:
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
这里,x标度从 0变为宽度,y从高度变为0 。由于你所看到的东西,它们彼此相反,x从左到右增加,而y从上到下增加。此.range
调用正在映射SVG坐标。
稍后你会看到这一行:
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
此部分现已映射用户空间坐标,表示它们从0到我们数据的最大值。
然后,您可以在绘制点时使用比例作为函数。
在您的代码中,它可能如下所示:
var svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 1000);
var x = d3.scaleLinear().range([0, 1000]),
y = d3.scaleLinear().range([1000, 0]);
function render(data){
x.domain([0, d3.max(data, function(d){
return d[' Monthly Term'];
});
y.domain([0, d3.max(data, function(d){
return d[' Principal Balance']/1000;
});
var circles = svg.selectAll("circle").data(data);
circles.enter().append("circle")
.attr("r", 1);
circles
.attr("cx", function (d){return x(d[' Monthly Term']); })
.attr("cy", function (d){ return y(d[' Principal Balance']/1000); });
...