d3 v4 scaleBand ticks
d3.js
Solution
This can be done using `tickValues` indeed. For instance, in this demo, we have 200 values, so the axis is absolutely crowded:
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 100);
var data = d3.range(200);
var xScale = d3.scaleBand()
.domain(data.map(function(d){ return d}))
.range([10, 490]);
var xAxis = d3.axisBottom(xScale);
var gX = svg.append("g").call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
Now, the same code using `tickValues`:
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 100);
var data = d3.range(200);
var xScale = d3.scaleBand()
.domain(data.map(function(d){ return d}))
.range([10, 490]);
var xAxis = d3.axisBottom(xScale)
.tickValues(xScale.domain().filter(function(d,i){ return !(i%10)}));
var gX = svg.append("g").call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
In this last snippet, `tickValues` uses the remainder operator to show only 1 in every 10 ticks:
.tickValues(xScale.domain().filter(function(d,i){
return !(i%10)
}));
Problem
I have data like the following ``` date,values 2016-10-01,10 2016-10-02,20 2016-10-03,30 2016-10-04,5 2016-10-05,50 2016-10-06,2 2016-10-07,7 2016-10-08,17 ``` and am generating a bar chart using the following code ``` var margin = {top: 20, right: 20, bottom: 70, left: 40}, width = 800 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; var parseDate = d3.timeParse("%Y-%m-%d"); var x = d3.scaleBand().range([0, width]); var y = d3.scaleLinear().range([height, 0]); var xAxis = d3.axisBottom(x); var yAxis = d3.axisLeft(y); var tip = d3.tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function(d) { return "<strong>Month of " + d.date + ":</strong> <span style='color:red'>" + d.value + " sales</span>"; }) var svg = d3.select("#barg").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.call(tip); data = d3.csvParse(d3.select("pre#data2").text()); data.forEach(function(d) { d.date = parseDate(d.date); d.value = +d.value; }); x.domain(data.map(function(d) { return d.date; })); y.domain([0, d3.max(data, function(d) { return d.value; })]); svg.append("g") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", "-.55em") .attr("transform", "rotate(-90)" ) svg.append("g") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Value ($)"); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.date); }) .attr("width", x.bandwidth() - 5) .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }) .on('mouseover', tip.show) .on('mouseout', tip.hide) ``` So the problem I am having is that I have ordinal data, but for large cardinality (for instance, 120 data points) The x axis has way too many ticks. I have tried a few things like `tickValues`, but when I use this, my x axis tick points all show up on top of each other. Ideally I would like 10 tick points or so, when the cardinality is high. Any ideas?