D3 Y-Axis Seems Inverted

痴心易碎 提交于 2021-02-17 02:50:07

问题


I am trying to generate a graph based on some data from a CSV file.

My code:

    <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>

Everything "works" but the Y-axis seems reversed.

Not sure if you guys can see the inspection window but the Y-value should be decreasing as x value increases.

Any ideas?


回答1:


In your console output, the Y value is decreasing as X value increases. In an SVG, the 0,0 location is top left. So a lower Y value is closer to the top of the screen. Try inverting the Y value:

.attr("cy", function (d){ return height - d[' Principal Balance']/1000});



回答2:


As @genestd states in his answer, SVG y coordinates start at the top and increase in value moving down. Generally, you should be using a d3 scale to map your user space values to svg coordinate values. Looking at the classic bar chart example, you see these lines:

var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
    y = d3.scaleLinear().rangeRound([height, 0]);

Here, the x scale goes from 0 to width and the y from height to 0. They are reversed from each other because of the very thing you are seeing, x increases going left to right while y increases going top to bottom. This .range call is mapping the SVG coordinates.

Later you'll see this line:

y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

This part has now mapped the user space coordinates, saying they run from 0 to the maximum of our data.

You can then use the scales as functions when you plot your point.

In your code it might look like this:

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

  ...


来源:https://stackoverflow.com/questions/44834747/d3-y-axis-seems-inverted

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!