I'm new with d3.js and I'm trying to build a bar chart with a json file. Here is my code :
// scale to ordinal because x axis is not numerical
var x = d3.scaleBand().rangeRound([0, width]);
//scale to numerical value by height
var y = d3.scaleLinear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.axisBottom(); //orient bottom because x-axis will appear below the bars
var yAxis = d3.axisLeft();
d3.json("coucou.json", function (error, data) {
x.domain(data.map(function (d) {
return d.time
}));
y.domain([0, d3.max(data, function (d) {
return d.value
})]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function (d, i) {
return "translate(" + x(d.receive_date) + ", 0)";
});
bar.append("rect")
.attr("y", function (d) {
return y(d.responses);
})
.attr("x", function (d, i) {
return x.rangeBand() + (margin.left / 2);
})
.attr("height", function (d) {
return height - y(d.responses);
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", x.rangeBand() + margin.left)
.attr("y", function (d) {
return y(d.responses) - 10;
})
.attr("dy", ".75em")
.text(function (d) {
return d.responses;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("responses");
});
And my json file:
[{
"data": [{
"time": "11:30:00",
"value": 121863
},
{
"time": "11:35:00",
"value": 121822
},
{
"time": "11:40:00",
"value": 121528
},
{
"time": "11:45:00",
"value": 121288
}
]
}]
When I load my html page, I have this error : TypeError: data.map is not a function on this line :
x.domain(data.map(function (d) {
return d.time
}));
I don't understand why. Did the syntax has changed with a new version ? But I don't find the way to write it...
Thanks for your help :)
I'm new with d3.js and I'm trying to build a bar chart with a json file. Here is my code :
// scale to ordinal because x axis is not numerical
var x = d3.scaleBand().rangeRound([0, width]);
//scale to numerical value by height
var y = d3.scaleLinear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.axisBottom(); //orient bottom because x-axis will appear below the bars
var yAxis = d3.axisLeft();
d3.json("coucou.json", function (error, data) {
x.domain(data.map(function (d) {
return d.time
}));
y.domain([0, d3.max(data, function (d) {
return d.value
})]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function (d, i) {
return "translate(" + x(d.receive_date) + ", 0)";
});
bar.append("rect")
.attr("y", function (d) {
return y(d.responses);
})
.attr("x", function (d, i) {
return x.rangeBand() + (margin.left / 2);
})
.attr("height", function (d) {
return height - y(d.responses);
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", x.rangeBand() + margin.left)
.attr("y", function (d) {
return y(d.responses) - 10;
})
.attr("dy", ".75em")
.text(function (d) {
return d.responses;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("responses");
});
And my json file:
[{
"data": [{
"time": "11:30:00",
"value": 121863
},
{
"time": "11:35:00",
"value": 121822
},
{
"time": "11:40:00",
"value": 121528
},
{
"time": "11:45:00",
"value": 121288
}
]
}]
When I load my html page, I have this error : TypeError: data.map is not a function on this line :
x.domain(data.map(function (d) {
return d.time
}));
I don't understand why. Did the syntax has changed with a new version ? But I don't find the way to write it...
Thanks for your help :)
In my case it was because the data was not loading pletely the way the example is. So I fixed the error doing this:
var dataCsv = d3.csv("../dashboard/sample-dataset.csv");
dataCsv.then(function (data) {
...
your function
...
});
Here are a few things I had to change.
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
You forgot to add (x)
& (y)
var chart = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
Append the g
alongside the chart variable, it's a lot easier
In your data snippet there were no d.responses
so I changed it to d.value
And here's how you'd acces your json data
var data = data1[0].data;
Here's a working Plunker