d3.js Nice End剔除超出域名

时间:2017-02-28 15:03:52

标签: javascript d3.js

我遇到了一个问题,我需要在我的一个轴刻度上使用.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()插入的刻度线间距或等效的内容,但同时我无法从数据域中进行插值。有没有其他人有这个问题?可以带来什么?

1 个答案:

答案 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>

话虽如此,这不是一个正确的解决方案,因为我怀疑任何人都可以制作(没有繁琐的黑客)轴在确切的域限制开始和结束使所有刻度均匀分布。