score:6

Accepted answer

This is the expected behaviour for a time scale. In D3, the axis is automatically generated, you don't have much control on the ticks.

The easiest alternative seems to be passing an array of the dates you have in your data to tickValues:

var axis = d3.axisBottom(scale)
    .tickValues(uniqueValues);

Here, uniqueValues is an array with the dates you have in your CSV, filtered to only unique dates (otherwise you'll have several ticks in the same position).

here is the demo with the CSV you shared:

var svg = d3.select("svg");
var csv = `date,close 
16-Dec-12,53.98
16-Dec-12,67.00
16-Dec-12,89.70
16-Dec-12,99.00
16-Dec-12,130.28
23-Dec-12,166.70
23-Dec-12,234.98
23-Dec-12,345.44
23-Dec-12,443.34
23-Dec-12,543.70
23-Dec-12,580.13
30-Dec-12,605.23
30-Dec-12,622.77
30-Dec-12,626.20
30-Dec-12,628.44
30-Dec-12,636.23
30-Dec-12,633.68`;
var data = d3.csvParse(csv, function(d) {
  d.date = d3.timeParse("%d-%b-%y")(d.date);
  return d
});
var uniqueValues = [...new Set(data.map(function(d) {
  return d.date.getTime()
}))].map(function(d) {
  return new Date(d);
});
var scale = d3.scaleTime()
  .range([30, 570])
  .domain(d3.extent(data, function(d) {
    return d.date
  }));
var axis = d3.axisBottom(scale)
  .tickValues(uniqueValues);
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="100"></svg>

PS: I'm using D3 v4 in the demo, but the principle is the same.

score:0

If .ticks(3) doesn't work, you can pass a custom function into .ticks to ensure you get the ticks you want.

Here is a fairly comprehensive axis tutorial.


Related Query