D3 Y轴似乎是倒置的

时间:2017-06-29 20:47:59

标签: javascript d3.js

我正在尝试根据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轴似乎相反。enter image description here

不确定你们是否可以看到检查窗口,但是随着x值的增加,Y值应该会减少。

有什么想法吗?

2 个答案:

答案 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); });

  ...