减少nvd3折线图中对数刻度的刻度数

时间:2017-05-20 09:03:00

标签: javascript d3.js data-visualization nvd3.js

我正在使用nvd3生成折线图。我想要log - 缩放y轴。 为此,我使用以下代码:

const chart = nv.models.lineChart()
    .x(function (d) { return d[0] })
    .y(function (d) { return d[1] })
    .margin({ left: 100 })  
    .useInteractiveGuideline(true)
    .showLegend(true)       
    .showYAxis(true)        
    .showXAxis(true);

chart.xAxis.tickFormat(d3.format(',r'));
chart.yAxis.tickFormat(d3.format('.02f'));
chart.yScale(d3.scale.log());

我得到的结果如下:

result

有没有办法减少y轴的刻度数,使它们不重叠?或者是否有任何库可以用来合理地生成蜱?我想避免手动设置tickValues

1 个答案:

答案 0 :(得分:1)

有一种简单的方法可以使用 .ticks()方法指定显示的刻度数。 D3.js v3 API documentation for axis.ticks()声明:

  

合适的参数取决于相关的比例:对于线性比例,您可以指定刻度计数,例如axis.ticks(20);对于日志比例,您可以指定计数和刻度格式; ...

这似乎适用于D3.js中的日志比例,

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

但不在NVD3.js

请在此处查看D3.js Log Axis example的工作修改代码段:



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>
&#13;
&#13;
&#13;

我在NVD3.js中稍微摆弄了一下,但没有运气:

&#13;
&#13;
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'
    },
  ];
}
&#13;
.chart {
  height: 300px !important;
  width: 80%;
}
&#13;
<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>
&#13;
&#13;
&#13;

我知道你不想用 .tickValues()手动指定值,但是它可以通过一个简单的函数来维护,给定域范围,这似乎是一个胜利在这种情况下。

还有一个解决方法found here,即

  • 在显示
  • 之前修改Y值
  • 并手动格式化刻度,

但是很难控制显示哪些值,因为它可以达到D3.js。但是这样 .ticks()方法在NVD3.js中工作

&#13;
&#13;
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'
    },
  ];
}
&#13;
.chart {
  height: 300px !important;
  width: 80%;
}
&#13;
<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>
&#13;
&#13;
&#13;