Я пытаюсь создать граф, основанный на некоторых данных из файла 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>
Все "работает", но ось Y кажется противоположной.
Не уверен, что вы видите окно инспекции, но значение Y должно уменьшаться по мере увеличения значения x.
Есть идеи?
На вашем консольном выходе значение Y уменьшается при увеличении значения X. В SVG расположение 0,0 находится сверху слева. Таким образом, более низкое значение Y ближе к верхней части экрана. Попробуйте инвертировать значение Y:
.attr("cy", function (d){ return height - d[' Principal Balance']/1000});
Как сообщает @genestd в своем ответе, координаты SVG y начинаются сверху и увеличиваются. Как правило, вы должны использовать шкалу d3 для сопоставления значений вашего пространства пользователя с координатами svg. Если посмотреть на классический пример гистограммы, вы увидите следующие строки:
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); });
...