Arun AK
Arun AK

Reputation: 4370

Data is not plotted properly using scale() values in d3.js

i created a chart in d3 and i created xaxis and yaxis. When plotting the data in the chart, the dots are not plotted correctly. This is the Plnkr link

I am setting the cx and cy values using xAxisScale and yAxisScale. But its not working properly. Here is the data :

var data = [{
          "x": 82,
          "y": 1730
        }, {
          "x": 533,
          "y": 16385
        }, {
          "x": 41,
          "y": 783
        }, {
          "x": 20.5,
          "y": 5873
        }, {
          "x": 553.5,
          "y": 25200
        }, {
          "x": 61.5,
          "y": 30952
        }, {
          "x": 184.5,
          "y": 2853
        }, {
          "x": 1476,
          "y": 83775
        }];

Here is the JS code :

    var xAxisScale = d3.scale.linear()
      .domain([800, 83800])
      .range([0, containerWidth]);

    var xAxis = d3.svg.axis().scale(xAxisScale).orient("bottom");

    chartContainer.append('g')
      .attr("class", "xAxis")
      .call(xAxis)
      .attr('transform', 'translate(50 ,' + (containerHeight - 20) + ')');

    /* Code for adding y axis in chart
     * 
     * */
    var yAxisScale = d3.scale.linear()
      .domain([500, 1500])
      .range([containerHeight, 0]);

    var yAxis = d3.svg.axis().scale(yAxisScale).orient("left");

    chartContainer.append('g')
      .attr("class", "yAxis")
      .call(yAxis)
      .attr('transform', 'translate(50 ,-20)');

    chartContainer.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("cx", function(d) {
        return yAxisScale(d.x);
      })
      .attr("cy", function(d) {
        return xAxisScale(d.y);
      })
      .attr("r", 4)
      .attr("fill", "red")
      .attr({
        "z-index": "9999"
      });

I dont know where i am missing guys.

Upvotes: 0

Views: 148

Answers (1)

Cyril Cherian
Cyril Cherian

Reputation: 32327

The correct way to set the domain and range would be:

var xAxisScale = d3.scale.linear()
         .domain([0, d3.max(data, function(d) { return d.x; })])
       .range([padding, containerWidth - padding * 2]);

You are not considering the padding and you are hard coding the domain .domain([800, 83800]).

Same for the y axis scale:

    var yAxisScale = d3.scale.linear()
      .domain([0, d3.max(data, function(d){return d.y})])
      .range([containerHeight-padding, padding ]);

Translate for y axis and x axis should have been:

    chartContainer.append('g')
      .attr("class", "xAxis")
      .call(xAxis)
      .attr('transform', 'translate(0 ,' + (containerHeight -padding) + ')');


    chartContainer.append('g')
      .attr("class", "yAxis")
      .call(yAxis)
      .attr('transform', 'translate('+padding + ',0)');

Instead of

chartContainer.append('g')
      .attr("class", "xAxis")
      .call(xAxis)
      .attr('transform', 'translate(50 ,' + (containerHeight - 20) + ')');

Lastly

You doing center calculation like this:

.attr("cx", function(d) {
        return yAxisScale(d.x);
      })
      .attr("cy", function(d) {
        return xAxisScale(d.y);
      })

it should have been:

.attr("cx", function(d) {
            return xAxisScale(d.x);//hey! you passing x value in yaxis :)
          })
          .attr("cy", function(d) {
            return yAxisScale(d.y);
          })

Working code here

Upvotes: 1

Related Questions