Reputation: 89
Just encountered a problem with D3. I want a bar chart that displays a single bar for each data value. The problem is these labels have the same name.
Example:
var x = d3.scale.ordinal()
.domain(["Bob", "Bob", "Terry", "Joe", "Bob", "Terry", "Joe", "Shiva", "Terry", "Joe"])
.rangeBands([margin.left, width - margin.right, width], .35);
When viewed in the browser, all the data with the same name (e.g. "Bob"
) is combined. In this case there are only four labels, whereas there should be 10.
How do I make it so that D3 treats each name as separate?
Also would be cool to have a solution where the names are stored in a data file (.json or .csv) where names are in d.Name
Upvotes: 3
Views: 2160
Reputation: 331
I think you can use
const names = ["Bob", "Bob", "Terry", "Joe", "Bob", "Terry", "Joe", "Shiva", "Terry", "Joe"];
const x = d3.scale.ordinal()
.domain(names.map((name, index) => index + name)) // it allows to create unique names
.rangeBands([margin.left, width - margin.right, width], .35);
svg.selectAll('.x-axis .name-container').text((name) => name.substr(1)); // removing useless indexes
Upvotes: 2
Reputation: 61
You can use linear and tickFormat for output
var raw = ["Bob", "Bob", "Terry", "Joe", "Bob", "Terry", "Joe", "Shiva", "Terry", "Joe"]
var linear = d3.scale.linear()
.domain([0, raw.length])
.range([0, w]);
Add code below to your axis
var axis = d3.svg.axis()
.scale(linear)
.orient("top")
.ticks(raw.length)
.tickFormat(function(d) {
return raw.charAt(d);
});
Upvotes: 1
Reputation: 1136
As far as I know ,D3 using mathematical concept of domain and ranges of a function ( f(x)=y
) and strictly domain elements should be unique.
So make your domain unique, for example if you want Bob multiple times, you need to make Bob s as unique element by adding Bob-1, Bob-2, Bob-3 etc.
var x=d3.scale.ordinal().domain(["Bob1", "Bob2","Joe0", "Joe1", "Shiva", "Joe2"])
.rangeBands([0,500]);
Upvotes: 0