Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Give d3 ordinal axis labels different from scale names

I have an ordinal scale with certain labels for the different values. I want to display an axis for that scale, where the axis labels are not the same as the scale labels. I have this code:

var width = 1000
var height = 600
var margins = {
left: 100, // 40
right: 25,
bottom: 50,
top: 0
}

var y = d3.scale.ordinal().domain(["This", "That", "Other"]).rangePoints([margins.top, height-margins.bottom], 1);

var svg = d3.select("#plot").append("svg").attr("width",width).attr("height",height)

var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .tickValues(["This is long", "That is long", "Other is long"])

svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + margins.left + ",0)")
  .classed("yaxis", true)
  .call(yAxis);

This used to work, but apparently there has been some change in d3 in the last few months that causes it to no longer work. (This other question also says I should be able to use tickValues this way.) The tick labels do not appear. I get an error in the JavaScript console saying:

Unexpected value translate(0,NaN) parsing transform attribute. @ http://d3js.org/d3.v3.js:596

Tracing through the code, it appears that d3 is trying to call the scale on each tick value; that is, it is calling y("This is long"), which results in NaN because "This is long" is not in the scale. I don't know why it's doing this.

Here is a fiddle showing the problem. If you comment out the .tickValues line, the axis labels show up correctly. With that line uncommented, the labels don't work.

What is the way to set tick labels for an ordinal axis in d3?

like image 813
BrenBarn Avatar asked Nov 15 '13 05:11

BrenBarn


People also ask

How to set the scale of the axis in D3?

The d3.axis.scale () Function in D3.js is used to sets the scale and return the axis. If this function is not provided with a specified scale, returns the current scale. Parameters: This function accepts only a single parameter as mentioned above and described below: scale: This parameter is an optional parameter and it holds the used scale.

How do you use D3 scale in a bar chart?

D3 Scales in a Bar Chart Add a label for the x Axis A label can be added to the x Axis by appending a text and using the transform and translate to position the text. The function translate uses a string concatenation to get to translate (w/2, h-10) which is calculated to translate (500/2, 300-10) or translate (250, 290).

What do the ticks and labels mean on a D3 axis?

When rendered via a D3 axis, the ticks and their associated labels represent specific instances within this continuous domain. For example, a linear scale might have ticks and labels rendered at 0, 20, 40, 60, 80, 100 as illustrated below:

Why would I want to render axis labels in between ticks?

There is another quite different reason why you might want to render axis labels in-between ticks, and that is when using band scales. Band scales are a type of ordinal scale (where the domain is composed of a set of values rather than a continuous range) used for rendering bar or column charts.


1 Answers

After fiddling around a bit more I found the answer. It seems that now you must use the tickFormat function to define how an axis displays its ticks. The solution is to replace the .tickValues line with this:

.tickFormat(function (d) {
  var mapper = {
    "This": "This is long",
    "That": "That is long",
    "Other": "Other is long"
  }
  return mapper[d]
})

The documentation does not make this clear; it only explicitly discusses "number formatters". It does not make the API of a "formatter" clear. It seems that a formatter takes a single value from a scale as input and is supposed to return the display version of that value. For ordinal scales, though, that value may not be a number but a named value on the scale.

like image 116
BrenBarn Avatar answered Sep 25 '22 17:09

BrenBarn