我正在使用 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());
我得到的结果如下:
有没有办法减少 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/