Arnaud Stephan
Arnaud Stephan

Reputation: 401

How to label my axis using words in d3.js

I would like to make a bar chart, where every bar represents the frequency of a certain word.

My data is an array of objects, with each having the property word and freq.

I declared my axis like that :

    let echelleX = d3.scaleBand()
        .domain(d3.extent(data, d => d.word))
        .range([marges.left, width - marges.right])
        .padding(0.1);

And called it :

     svg.append("g")
        .attr("class","axeX")
        .attr("transform", `translate(0,${height})`)
        .call(axeX)
        .selectAll("text")
        .attr("font-weight", "normal")
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".5em")
        .attr("transform", "rotate(-65)");

I then add my bars to the svg :

    svg.append("g").selectAll(".barre").data(data).enter()
    .append("rect")
    .attr("class", "barre")
    .attr("x", (d,i) => echelleX(d.word))
    .attr("y", (d) => echelleY(d.freq))
    .attr("width", 2.5)
    .attr("height", d => height - echelleY(d.freq))
    .attr("fill","steelblue");

But the result is this :

enter image description here

When I change this line

.attr("x", (d,i) => echelleX(d.word))

To

.attr("x", (d,i) => marges.left + i*3)

I get this, which is better, but the labels of the axis still don't match.

enter image description here

I checked the documentation of d3.scaleBand and tried a few tweaks but I can't seem to make it work the way I would want to. What am I missing? I would like every bar (d.freq) to have its corresponding label (d.word) underneath it on the axis.

Upvotes: 0

Views: 769

Answers (1)

Eric Guan
Eric Guan

Reputation: 15982

Band scales are ordinal instead of linear, which means you need to provide every possible value to the domain instead of just the min/max. D3 cannot interpolate ordinal values.

Try this

.domain(data.map(d => d.word))

You will also have to revert the change you made to the x attr, the band scale should take care of that.

EDIT: Made the mistake of thinking d3.map did the same thing as array map.

Upvotes: 1

Related Questions