我遇到了一个问题,我需要在我的一个轴刻度上使用.nice()
,以便刻度线可以利用端点并正确展开(而不是使端点未使用)。
现在我解决了这个问题,出现了意想不到的问题。我打电话给.nice()
之后:
var x = d3.time.scale().range([0, width])
x.domain(d3.extent(data, function(d) { return d.date; })).nice();
轴现在可以达到2018年。这可能会带来麻烦,因为它看起来非常自命不凡,因为它只是2017年2月。显然我没有水晶球,我的数据中没有2018在任何地方,所以我唯一的猜测是当插值时函数过分。
我喜欢/字面上需要从.nice()
插入的刻度线间距或等效的内容,但同时我无法从数据域中进行插值。有没有其他人有这个问题?可以带来什么?
答案 0 :(得分:2)
你在一块岩石和一个坚硬的地方之间。
这里的问题是D3轴生成器(特别是在使用时间刻度时)没有创建这样的自定义。
让我们来看看你的问题:当使用nice()
时,你得到了结束标记。但是,正如您所说,最终值可能会超出域名,这是一个众所周知的问题。
这是一个演示,结束日期是今天,但轴到2020年:
var svg = d3.select("svg");
var xScale = d3.scaleTime().domain([new Date("1980-01-01"), new Date()]).range([20,480]).nice();
var xAxis = d3.axisBottom(xScale);
var gX = svg.append("g").attr("transform","translate(0,50)").call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="80"></svg>
一种可能的解决方案是使用concat
和scale的域来保证域中的第一个和最后一个值是第一个和最后一个滴答,如下所示:
.tickValues(xScale.ticks(10).concat(xScale.domain()))
使用ticks
设置大致的刻度数。这是演示:
var svg = d3.select("svg");
var xScale = d3.scaleTime().domain([new Date("1980-01-01"), new Date()]).range([20,480]);
var xAxis = d3.axisBottom(xScale).tickFormat(d3.timeFormat("%Y")).tickValues(xScale.ticks(10).concat(xScale.domain()));
var gX = svg.append("g").attr("transform","translate(0,50)").call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="80"></svg>
但是,正如您所看到的,刻度线的间距不均匀,如您所愿。
因此,仍然使用此concat
方法的问题的替代解决方案是调整ticks
值,直到我们使得滴答声显示为或多或少隔开:
var svg = d3.select("svg");
var xScale = d3.scaleTime().domain([new Date("1980-01-01"), new Date()]).range([20,480]);
var xAxis = d3.axisBottom(xScale).tickFormat(d3.timeFormat("%Y")).tickValues(xScale.ticks(5).concat(xScale.domain()));
var gX = svg.append("g").attr("transform","translate(0,50)").call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="80"></svg>
话虽如此,这不是一个正确的解决方案,因为我怀疑任何人都可以制作(没有繁琐的黑客)轴在确切的域限制开始和结束和使所有刻度均匀分布。