My journey with d3.js is just beginning and I'm taking it slow. Currently, I'm focused on creating a bar chart where data is loaded from a json file. When I click on the bars, the data changes to another column in the json.
This is how my json file looks:
[
{
"ym": "201801",
"clients": 179,
"trans": 987,
},
{
"ym": "201802",
"clients": 178,
"trans": 334,
}
]
Initially, everything works fine when the page loads - the chart displays properly and functions well. However, upon clicking the bars, I encounter issues where the axis change, text updates but the bars disappear. The console error message reads:
d3.v4.min.js:2 Error: <rect> attribute y: Expected length, "NaN".
(anonymous) @ d3.v4.min.js:2
d3.v4.min.js:2 Error: <rect> attribute height: Expected length, "NaN".
I tried debugging by checking if the data type was causing this problem (as per another thread's suggestion), but couldn't find any discrepancies there. The main idea behind my two related functions is simple - clicking the bars should only alter their color, but somehow they disappear instead of changing color.
Here's an excerpt from the function that handles this behavior:
function alter_show() {
d3.json("testV.json", function(data) {
var y = d3.scaleLinear().range([height,1]);
var x = d3.scaleBand().rangeRound([0, width]);
y.domain([1,d3.max(data,function(d) {return d.clients})]);
x.domain(data.map(function(d) {return d.ym}));
svg.select(".x.axis").call(d3.axisBottom(x))
svg.select(".y.axis").call(d3.axisLeft(y))
bar = svg.selectAll("rect")
bar.data(data).enter().append("rect")
.attr('class','bar')
.attr("x", function (d) {return x(d.ym); })
.attr("y", function (d) {return y(d.clients); })
.attr("height", function (d) {return height - y(d.clients)})
.attr("width", x.bandwidth()*0.5)
.attr("color","black")
.attr("transform",
"translate(" + (margin.left + x.bandwidth()*0.25) + "," + margin.top + ")")
// Event Listeners for bar interaction
.on('mouseenter', function() {
d3.select(this).transition().duration(100).attr('opacity',0.5).attr('color', 'orange')})
.on('mouseleave', function() {
d3.select(this).transition().duration(100).attr('opacity',1)})
.on('click',alter_show);
// Displaying additional values inside bars
svg.append("g").selectAll("text").data(data).enter().append("text")
.attr('class','value')
.attr("x", function (d) {return x(d.ym); })
.attr("y", function (d) {return y(d.trans); })
.text(function (d) {return d.trans})
.attr('font-size','0.7em')
.attr("transform",
"translate(" + (margin.left + x.bandwidth()*0.25) + "," + (margin.top + 30) + ")");
// Updating existing bars with transitions based on new data:
bar.exit().remove();
bar.transition()
.duration(750)
.attr("y", function(d) {
return y(d.value);
})
.attr("height", function(d) {
return height - y(d.value);
})});}
In conclusion, the function performs as expected upon page load, but faces issues with bar display post-click. Any insights or additional information would be greatly appreciated. Thank you for your help!