d3.js, how can i create an axis with custom labels and customs ticks?

11,019

Solution 1

You could try like this

const xAxis = d3.axisTop(xScale)
        .tickValues(data)
        .tickFormat(d => (d.year +":"+ d.val));

Solution 2

Since you didn't show the scale in your question we don't know what type of scale you have and what are the domain values. But one thing is sure: you cannot pass the whole object to it. Therefore, your tickFormat doesn't have access to one of the properties in each object.

A simple solution is using the index of the tick to get the other property, provided that you are displaying all the ticks (and that you are using an ordinal scale):

var axis = d3.axisBottom(scale)
  .tickFormat(function(d, i) {
    return d + ": " + data[i].val;
  });

Here is a demo:

var svg = d3.select("body")
  .append("svg")
  .attr("width", 500)
  .attr("height", 100);

var data = [{
  year: 1999,
  val: 5
}, {
  year: 2002,
  val: 8
}, {
  year: 2005,
  val: 1
}, {
  year: 2008,
  val: 4
}, {
  year: 2011,
  val: 9
}, {
  year: 2014,
  val: 2
}];

var scale = d3.scalePoint()
  .range([20, 480])
  .domain(data.map(function(d) {
    return d.year
  }));

var axis = d3.axisBottom(scale)
  .tickFormat(function(d, i) {
    return d + ": " + data[i].val;
  });

var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);
<script src="https://d3js.org/d3.v4.min.js"></script>

Share:
11,019
heapOverflow
Author by

heapOverflow

Updated on July 23, 2022

Comments

  • heapOverflow
    heapOverflow almost 2 years

    I have an array similar to this:

    [{year: 1999, val: 5}, {year: 2002, val: 8}]
    

    and I would like to add an axis where I have one tick for each year value (something I can do with tickValues and tickFormat) but where the tick label is not only the year but has a custom format, so the result could be something like "1999: 5" for the first array element.

    To rephrase it:

    Where I'm now

    const xAxis = d3.axisTop(xScale)
            .tickValues(data.map(d => d.year);
    

    This is not ok because only the year is visualized on the label of the tick and I would like to use a custom format.

    Is this possible with d3?

  • heapOverflow
    heapOverflow almost 7 years
    Sorry I wrote one wrong piece of code that I have now corrected. This solution (as the one I wrote before) cannot work because the elements of the array that are used for the ticks are not numeric values.
  • heapOverflow
    heapOverflow almost 7 years
    Thanks, we posted together the same solution! It's a bit ugly but it's the best I've been able to figure out.
  • Gerardo Furtado
    Gerardo Furtado almost 7 years
    @heapOverflow Our solutions are not the same. Your solution will show only the val value on the ticks, and in your question you clearly ask for the year and val in the ticks. Since you said that it works, I can only assume that your question is not correctly worded... that being the case, nobody can help you as the desired outcome is not clear.