Reputation: 1
I was trying to make a Bar Chart using D3 by calling the data from the JSON API, I was able to make a single bar visible but not able to make other bars visible. I hope there is some issue placing of the bars.
Different rectangles are visible in the developer tool, but all are coming up in a same place.
Any help would be much appreciated.
// javascript
const svg = d3.select('svg');
const width = +svg.attr('width');
const height = +svg.attr('height');
// Get the data from the JSON api
d3.json("https://api.covid19india.org/data.json")
.then( data => {
// Store the data in two variales
var stateNames = [];
var confirmedCases = [];
for (let i=1; i <= 10; i++){ //i <= (data.statewise.length) - 1
stateNames.push(data.statewise[i].state);
confirmedCases.push(+(data.statewise[i].confirmed));
}
//console.log(stateNames);
//console.log(confirmedCases);
// Max number of cases
let sortedData = [...confirmedCases];
let sortedCases = sortedData.sort(function(a,b){
return a-b;
})
// Measurement of the SVG Element
const margin = { top: 20, right: 20, bottom: 20, left: 100};
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
// Horizontal Visualization of Bar Graph
// X scale
const xScale = d3.scaleLinear()
.domain([0, sortedCases[sortedCases.length-1]])
.range([0, innerWidth]);
//console.log(xScale.domain());
//console.log(xScale.range());
const yScale = d3.scaleBand()
.domain(stateNames)
.range([0, innerHeight])
.padding(0.2);
//console.log(yScale.domain());
const yAxis = d3.axisLeft(yScale);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
g.append('g').call(d3.axisLeft(yScale));
g.append('g').call(d3.axisBottom(xScale))
.attr('transform', `translate(0,${innerHeight})`);
g.selectAll('rect').data(confirmedCases).enter()
.append('rect')
.attr('width', xScale)
.attr('height', 30)
})
Reference to the codepen link, where I have tried
https://codepen.io/Jagat_Nayan/pen/mdepwgZ
Upvotes: 0
Views: 56
Reputation: 3543
You need to defin y property to relate the states to Y asix, and for that you need to pass both stateName and cases while creating rect.
I created an array inputData which containes both stateName and their respective cases and used it while creating rectangles. Below is your updated working code.
// javascript
const svg = d3.select("svg");
const width = +svg.attr("width");
const height = +svg.attr("height");
// Get the data from the JSON api
d3.json("https://api.covid19india.org/data.json").then((data) => {
var inputData = [];
for (let i = 1; i <= 10; i++) {
inputData.push({stateName: data.statewise[i].state, cases: +data.statewise[i].confirmed})
}
// Measurement of the SVG Element
const margin = { top: 20, right: 20, bottom: 20, left: 100 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
//const barWidth = innerWidth;
//const barPadding = 5;
// Horizontal Visualization of Bar Graph
// X scale
const xScale = d3
.scaleLinear()
.domain([0, d3.max(inputData, function(d){ return d.cases; })])
.range([0, innerWidth]);
const yScale = d3
.scaleBand()
.domain(inputData.map(function(d) { return d.stateName; }))
.range([0, innerHeight])
.padding(0.2);
const yAxis = d3.axisLeft(yScale);
const g = svg
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
g.append("g").call(d3.axisLeft(yScale));
g.append("g")
.call(d3.axisBottom(xScale))
.attr("transform", `translate(0,${innerHeight})`);
g.selectAll("rect")
.data(inputData)
.enter()
.append("rect")
.attr("width", function(d) {return xScale(d.cases); })
.attr("y", function(d) {return yScale(d.stateName); })
.attr("height", 30);
});
Working graph on codepen - https://codepen.io/puneet2412/pen/LYpeOzd
Upvotes: 1