score:2

Well there is an easy way for specifying the number of displayed ticks with the method .ticks(). D3.js v3 API documentation for axis.ticks() states:

Suitable arguments depends on the associated scale: for a linear scale, you might specify a tick count such as axis.ticks(20); for a log scale, you might specify both a count and a tick format;...

This seems to work for log scales in D3.js,

var nTicks = 10;
var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(nTicks, d3.format('.02f'))
    .tickSize(6, 0);

but not in NVD3.js.

See the working modified snippet of D3.js Log Axis example here:

var margin = {top: 210, right: 20, bottom: 220, left: 20},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.log()
    .domain([.0124123, 1230.4])
    .range([0, width]);

var nTicks = 10;
var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(nTicks, d3.format('.02f'))
    .tickSize(6, 0);
    
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.right + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append("g")
    .attr("class", "x axis")
    .call(xAxis);
.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}
<script src="//d3js.org/d3.v3.min.js"></script>

I've fiddled with it a little in NVD3.js, but with no luck:

const chart = nv.models.lineChart()
    .margin({ left: 150 })  
    .useInteractiveGuideline(true)
    .showLegend(true)       
    .showYAxis(true)        
    .showXAxis(true);

var logScale = d3.scale.log();
chart.yScale(logScale);
chart.xAxis.tickFormat(d3.format(',r'));
var nTicks = 6;
chart.yAxis.ticks(nTicks);
//chart.yAxis.tickFormat(d3.format('.02f'));

var myData = generateValues();
d3.select('.chart')
      .datum(myData) 
      .call(chart);   

function generateValues() {
  var valuesGenerated = []
  valuesGenerated.push({ x: 0, y: 1 });
  for (var i = 1; i < 100; i++) {
    valuesGenerated.push({ x: i, y: Math.random() * 10 + 10*i });
  }
  valuesGenerated.push({ x: 100, y: 1100 });

  return [
    {
      values: valuesGenerated,
      key: 'series1',
      color: '#ff7f0e'
    },
  ];
}
.chart {
  height: 300px !important;
  width: 80%;
}
<svg class="chart"></svg>

<script src="//d3js.org/d3.v3.min.js"></script>
<script src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.js"></script>

I get that you don't want to specify the values manually with .tickValues(), but it can maintained by a simple function, given the domain range, which seems like a win in this situation.

There is also a workaround found here, that

  • modifies Y values prior to displaying
  • and manually formats the ticks,

but it's harder to control which values are displayed, since it's up to D3.js . But this way the .ticks() method works in NVD3.js!

const chart = nv.models.lineChart()
    .margin({ left: 150 })  
    .useInteractiveGuideline(true)
    .showLegend(true)       
    .showYAxis(true)        
    .showXAxis(true);

var logScale = d3.scale.log();
chart.yScale(logScale);
chart.xAxis.tickFormat(d3.format(',r'));
chart.yAxis.ticks(6);
chart.yAxis.tickFormat(d3.format('.02f'));

chart.y(function(d) { return d.y>0?Math.log10(d.y+1):0 });
chart.yAxis.ticks(10);
chart.yAxis.tickFormat(function(d){return (Math.pow(10,d)-1).toFixed(2)});

var myData = generateValues();
d3.select('.chart')
      .datum(myData) 
      .call(chart);   

function generateValues() {
  var valuesGenerated = []
  valuesGenerated.push({ x: 0, y: 1 });
  for (var i = 1; i < 100; i++) {
    valuesGenerated.push({ x: i, y: Math.random() * 10 + 10*i });
  }
  valuesGenerated.push({ x: 100, y: 1100 });

  return [
    {
      values: valuesGenerated,
      key: 'series1',
      color: '#ff7f0e'
    },
  ];
}
.chart {
  height: 300px !important;
  width: 80%;
}
<svg class="chart"></svg>

<script src="//d3js.org/d3.v3.min.js"></script>
<script src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.js"></script>


Related Query

More Query from same tag