Reputation: 52
I have created a horizontal bar chart using d3.js and every thing works fine if no identical columns values(here it is 'response' field) occurs.
eg: var data = [{
"answer": "Answer2",
"response": 5,
"total": 7,
"color": "#ff4700"
}, {
"answer": "Answer3",
"response": 5,
"total": 7,
"color": "#0ED5EE"
}, {
"answer": "Answer4",
"response": 1,
"total": 7,
"color": "#31EE0E"
}];
If we provide same value on 'response' field( say repeating 5) , the resultant bar count will be not matched as expected, otherwise it will draw perfectly.
Can you please help me to sort out this issue.
Thanks and regards
Upvotes: 2
Views: 77
Reputation: 103
The y axis domain value must be unique for it to work properly.
So your response
value is not unique and in theory your answer
does not have to be unique either. Furthermore, using answer
as domain and then getting the data by index seems dirty and may cause unexpected results when (re-)sorting the data.
To get unique values for your y domain you could add an unique id to each of your data objects e.g.:
var data = [{
"uniqueId": 1,
"answer": "Answer2",
"response": 5,
"total": 7,
"color": "#ff4700"
},....]
y.domain(data.map(function(d) { return d.uniqueId; }));
And then add a tickFormat to the yAxis:
yAxis.tickFormat(function(id, i){
var d = data.find(function(d) { return d.uniqueId === id; });
var percentage = parseFloat( (d.response/d.total) * 100).toFixed(1)
return percentage + '%';
})
result: https://jsfiddle.net/rd8z5k32/1/
Alternatively you could just use the indexes of the data array as domain:
y.domain(d3.range(data.length));
yAxis.tickFormat(function(_d, i){
var d = data[i];
var percentage = parseFloat( (d.response/d.total) * 100).toFixed(1)
return percentage + '%';
})
Upvotes: 1
Reputation: 32327
For y domain give unique name in your case answer:
.domain(data.map(function(d) {
return d.answer;
}));
Then for the y axis give tick format:
.tickFormat(function(d, i){
var d = data[i];
var percentage = parseFloat( (d.response/d.total) * 100).toFixed(1)
return percentage + '%'; })
working code here
Upvotes: 2