I am writing the following d3.js function for brush. This function works fine for me but i want to alternate the tick padding for the brush so that two consecutive ticks are not on the same height and hence do not overlap. This maintains the clarity of the ticks. Can anyone suggest the right way to do so in the following function.
$scope.drawBrush = function (span) {
var width = 400,
height = 50;
var x = d3.time.scale()
.domain([new Date($scope.range1), new Date($scope.range2)])
.range([0, width]);
d3.select('#brushd').remove();
var brush = d3.svg.brush()
.x(x)
.extent([new Date($scope.range1), new Date($scope.range2)])
.on('brush', brushed);
var svg = d3.select('#brush-div').append('svg')
.attr('id', 'brushd')
.attr('width', '400')
.attr('height', '80')
.style('margin-left', '0px')
.append('g')
.attr('transform', 'translate(' + 50 + ',' + 0 + ')');
svg.append('rect')
.attr('class', 'grid-background')
.attr('width', width)
.attr('height', height);
svg.append('g')
.attr('class', 'x grid')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.svg.axis()
.scale(x)
.orient('bottom')
.ticks(d3.time.hours, 12)
.tickSize(-height)
.tickFormat(''))
.selectAll('.tick')
.classed('minor', function (d) {
return d.getHours();
});
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.svg.axis()
.scale(x)
.orient('bottom')
.tickFormat(d3.time.format('%b-%y'))
.tickPadding(0))
.selectAll('text')
.attr('x', 6)
.style('text-anchor', null);
var gBrush = svg.append('g')
.attr('class', 'brush')
.call(brush);
gBrush.selectAll('rect')
.attr('height', height);
function brushed() {
var extent0 = brush.extent(),
extent1;
// if dragging, preserve the width of the extent
if (d3.event.mode === 'move') {
var d0 = d3.time.day.round(extent0[0]),
d1 = d3.time.day.offset(d0, Math.round((extent0[1] - extent0[0]) / 864e5));
extent1 = [d0, d1];
}
// otherwise, if resizing, round both dates
else {
if (span === 'daily') {
extent1 = extent0.map(d3.time.day.round);
// if empty when rounded, use floor & ceil instead
if (extent1[0] >= extent1[1]) {
extent1[0] = d3.time.day.floor(extent0[0]);
extent1[1] = d3.time.day.ceil(extent0[1]);
}
} else if (span === 'weekly') {
extent1 = extent0.map(d3.time.week.round);
// if empty when rounded, use floor & ceil instead
if (extent1[0] >= extent1[1]) {
extent1[0] = d3.time.week.floor(extent0[0]);
extent1[1] = d3.time.week.ceil(extent0[1]);
}
} else {
extent1 = extent0.map(d3.time.month.round);
// if empty when rounded, use floor & ceil instead
if (extent1[0] >= extent1[1]) {
extent1[0] = d3.time.month.floor(extent0[0]);
extent1[1] = d3.time.month.ceil(extent0[1]);
}
}
}
d3.select(this).call(brush.extent(extent1));
$scope.getLimit(brush.extent()[0], brush.extent()[1]);
}
};
One way to alternate between long and short ticks on your x-axis, to achieve this sort of thing:

... is like this:
// flag to alternate between long and short ticks
var alternate_ticks = false;
var short_tick_length = 4;
var long_tick_length = 16;
// Alternate the tick line between long and short ticks
d3.selectAll("g.x.axis g.tick line")
.attr("y2", function () {
if (alternate_ticks) {
alternate_ticks = false;
return long_tick_length;
} else {
alternate_ticks = true;
return short_tick_length;
}
});
var alternate_text = false;
// Alternate the tick label text to match up with the tick length
d3.selectAll("g.x.axis g.tick text")
.attr("y", function () {
if (alternate_text) {
alternate_text = false;
return long_tick_length + 1;
} else {
alternate_text = true;
return short_tick_length + 1;
}
});
It's a simpler version of the same approach as Lars K pointed out above, but using a simpler function that just alternates between false and true to determine tick length and text positioning on the relevant set of objects.
Try this for tick labeling.
// Alternate the tick label text to match up with the tick length
d3.selectAll("g.x.axis g.tick text")
.each(function (d, i) {
//console.log(i % 2);
if ((i % 2)) { //even
this.remove();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With