score:14

Accepted answer

You could try like this

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

score:-1

What I have been able to do now:

d3.axisTop(xScale)
        .tickValues(data.map(d => d.year))
        .tickFormat((d, i) => data[i].val);

Quite ugly but it works. If I get a better solution I will accept a different one.

score: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>


Related Query