Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 - ordinal scale labels with same names

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

like image 843
Tactician Jenro Avatar asked Nov 26 '25 20:11

Tactician Jenro


2 Answers

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
like image 62
yurakis Avatar answered Nov 29 '25 09:11

yurakis


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);
             });
like image 28
xy1m Avatar answered Nov 29 '25 09:11

xy1m



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!