Abhishek Mukherjee - 1 year ago 104
Javascript Question

# d3 - how to show duration interval instead of tickValues

Let's consider a horizontal bar chart as shown in the attached photo. I need to show the duration of each segment along with the x-axis. I am able to show the tick values using d3.svg.axis().tickValues(vals). But I need to show the duration in between two ticks. Can anyone help me to achieve this using d3?

Here is my solution. I'm using D3 version 3 (because you wrote d3.svg.axis() in your question) and a linear scale, just to show you the principle. You can easily change it to a time scale.

Given this data:

``````var data = [0, 10, 40, 45, 85, 100];
``````

We're gonna plot the differences between the ticks, i.e.: 10, 30, 5, 40 and 15.

The first step is setting the scale:

``````var scale = d3.scale.linear()
.domain(d3.extent(data))
.range([margin, w - margin]);
``````

Then, in the axis generator, we set the ticks to match the data with:

``````.tickValues(data)
``````

And we calculate the correct numbers with:

``````.tickFormat(function(d,i){
if(i>0){
return data[i] - data[i-1];
} else { return ""};
});
``````

The last step is translating the text to the middle position:

``````var ticks = d3.selectAll(".tick text").each(function(d, i) {
d3.select(this).attr("transform", function() {
if (i > 0) {
return "translate(" + (-scale(data[i] - data[i - 1]) / 2 + margin/2) + ",0)";
}
})
})
``````

Check the demo:

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

var data = [0, 10, 40, 45, 85, 100];

var margin = 20;

var scale = d3.scale.linear()
.domain(d3.extent(data))
.range([margin, w - margin]);

var colors = d3.scale.category10();

var rects = svg.selectAll(".rects")
.data(data)
.enter()
.append("rect");

rects.attr("y", 10)
.attr("height", 35)
.attr("fill", (d,i)=> colors(i))
.attr("x", d=>scale(d))
.attr("width", (d,i)=> {
return scale(data[i+1] - data[i]) - margin
});

var axis = d3.svg.axis()
.scale(scale)
.orient("bottom")
.tickValues(data)
.tickFormat(function(d, i) {
if (i > 0) {
return data[i] - data[i - 1];
} else {
return ""
};
});

var gX = svg.append("g")
.attr("transform", "translate(0,50)")
.attr("class", "axis")
.call(axis);

var ticks = d3.selectAll(".tick text").each(function(d, i) {
d3.select(this).attr("transform", function() {
if (i > 0) {
return "translate(" + (-scale(data[i] - data[i - 1]) / 2 + margin / 2) + ",0)";
}
})
})``````
``````.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}``````
``<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>``

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download