Reputation: 556
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]);
}
};
Upvotes: 3
Views: 5457
Reputation: 279
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();
}
});
Upvotes: 3
Reputation: 3112
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.
Upvotes: 4