Tactician Jenro
Tactician Jenro

Reputation: 89

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

Upvotes: 3

Views: 2160

Answers (3)

yurakis
yurakis

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

xy1m
xy1m

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

Nithin CV
Nithin CV

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

Related Questions