score:0

Accepted answer

i solved this whit following approach, it's controlled by shouldlogscale var:

nv.addgraph(() => {
  this.chart = nv.models.multibarchart()
    ...
    .y(d => {
      const y = parsefloat(d.y);
      return this.shouldlogscale ? math.log10(y <= 0 ? 1 : y) : y;
    });

  if(this.shouldlogscale) {
    this.logscale();
  } else {
    this.chart.yaxis.tickformat(d3.format(`,.${this.precision}f`));
  }

  ...
});

when initialising the chart: i modify y values, force y (chart.forcey) start and end values (map them to their log10 range), analogically i set chart.yaxis.tickvalues. lastly i map ticks (chart.yaxis.tickvalues) to their original values. just make sure to comply domain of the log function.

logscale method:

private logscale() {
  this.chart.forcey([1, 180]
    .map(v => math.log10(v)));
  this.chart.yaxis.tickvalues([1, 3, 5, 10, 20, 50, 100, 180]
    .map(v => math.log10(v)));
  this.chart.yaxis.tickformat(d => math.pow(10, d).tofixed(this.precision));
}

maybe i could use a map of y domain and range values to avoid using log and pow functions in logscale method.


Related Query

More Query from same tag