Peterson Peterson - 16 days ago 5
AngularJS Question

D3 Horizontal Bar Chart X-Axis Range shorter than in Data via AngularJs

I plotted a horizontal bar chart and I am fetching it with no errors. My problem is the X-Axis must reflect frequency from 0 to 35 atleast with the current set of data. Now what I can see is 0 to 8. Can someone explain me the error and help rectify it?

SNIPPET:

<html>

<head>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.12/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script>

</head>

<body ng-app="myApp" ng-controller="myCtrl">

<svg></svg>

<script>

//module declaration
var app = angular.module('myApp',[]);

//Controller declaration
app.controller('myCtrl',function($scope){

$scope.svgWidth = 800;//svg Width
$scope.svgHeight = 500;//svg Height

//Data in proper format
var data = [
{"letter": "A","frequency": "5.01"},
{"letter": "B","frequency": "7.80"},
{"letter": "C","frequency": "15.35"},
{"letter": "D","frequency": "22.70"},
{"letter": "E","frequency": "34.25"},
{"letter": "F","frequency": "10.21"},
{"letter": "G","frequency": "7.68"},
];

//removing prior svg elements ie clean up svg
d3.select('svg').selectAll("*").remove();

//resetting svg height and width in current svg
d3.select("svg").attr("width", $scope.svgWidth).attr("height", $scope.svgHeight);

//Setting up of our svg with proper calculations
var svg = d3.select("svg");
var margin = {top: 20, right: 20, bottom: 30, left: 40};
var width = svg.attr("width") - margin.left - margin.right;
var height = svg.attr("height") - margin.top - margin.bottom;

//Plotting our base area in svg in which chart will be shown
var g = svg.append("g");

//shifting the canvas area from left and top
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//X and Y scaling
var x = d3.scaleLinear().rangeRound([0, width]);
var y = d3.scaleBand().rangeRound([height, 0]).padding(0.4);

//Feeding data points on x and y axis
data.forEach(function(){

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

});

//Final Plotting

//for x axis
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));

//for y axis
g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end");

//for rectangles
g.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("y", function(d) { return y(d.letter); })
.attr("x", function(d) { return 0; })
.attr("height", y.bandwidth())
.attr("width", function(d) { return x(d.frequency); });

});

</script>

</body>

</html>


RESULT:

enter image description here

Please, help out so that I get proper length of rectangles or bars in the current bar chart, with respective data set that I am supplying it.

Answer

This part of your code is wrong:

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

try to replace it with this:

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