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

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

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

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

最佳答案

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

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;...

这似乎适用于 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>

我在 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'));
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>

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

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

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

但是很难控制显示哪些值,因为它取决于 D3.js 。但这样 .ticks() 方法可以在 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>

关于javascript - 减少 nvd3 折线图中对数刻度的刻度数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44083949/

相关文章:

python - 在Python中,绘制具有相同x轴和y轴的不同类别数据的方法是什么?

.net - 需要在 asp.net 中实现雅虎注册表单名称字段的想法

javascript - 如何在javascript中检查对象的索引?

javascript - 如果未选中复选框,则禁用表单提交

svg - 如何获得笔画的轮廓?

javascript - v4 : pinch zooming a map when one finger is over a child element 中的 d3.js 缩放传播

javascript - Topojson属性字段,如何显示d3.js中的所有属性

javascript - 如何使用 React 正确实现 d3 svg click?

python - Django 上的实时图表

javascript - 循环中$index的值