简体   繁体   English

d3.js:从时间尺度获取刻度格式

[英]d3.js: get tick format from time scale

I'm building a timeline visualisation with d3 where the domain can vary from a couple of days to several decades. 我正在使用d3构建时间轴可视化,其中域可以从几天到几十年不等。 I'm using a d3 time scale and axis like this: 我正在使用d3时标和轴这样:

var timeScale = d3.time.scale()
    .domain([firstEvent, lastEvent])
    .range([leftPadding, w - rightPadding]);
var timeAxis = d3.svg.axis()
    .scale(timeScale)
    .orient("bottom");
timeAxis.ticks(5);

Since the domain is so variable, it is convenient to use ticks(x) which will automatically choose the tick format. 由于域是如此可变,因此使用ticks(x)会很方便,它会自动选择tick格式。 My problem is that in some cases, the year is not shown, which is crucial. 我的问题是,在某些情况下,未显示年份,这是至关重要的。 My idea was to check the tick format after the axis is created, and if it doesn't contain a year, show it manually next to the axis. 我的想法是在创建轴后检查刻度线格式,如果它不包含年份,则在轴旁边手动显示。 However, I haven't been able to get the scale's tick format; 但是,我无法获得比例尺的刻度格式; using timeScale.tickFormat() just returns a function. 使用timeScale.tickFormat()只返回一个函数。 How can I solve this problem? 我怎么解决这个问题?

How about a simple regex test? 简单的正则表达式测试怎么样?

var hasYear = false;
var re = /^\d{4}$/;
// get the ticks text    
d3.selectAll('.x>.tick>text').each(function(d){
  // does the text look like a year?
  var txt = this.textContent;
  if (re.test(txt)){
    hasYear = true;
  }
});
console.log(hasYear);

Used this sample code and played around with various ranges: 使用此示例代码并使用各种范围:

 <!DOCTYPE html> <meta charset="utf-8"> <style> .axis text { font: 10px sans-serif; } .axis line, .axis path { fill: none; stroke: #000; shape-rendering: crispEdges; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var margin = {top: 250, right: 40, bottom: 250, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var x = d3.time.scale() .domain([new Date(2013, 12, 2), new Date(2013, 12, 6)]) .range([0, width]); var xAxis = d3.svg.axis() .scale(x) .ticks(5); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); xAxis.ticks().some(function(d){ return /^\\d{4}$/.exec("3434") }) var hasYear = false; var re = /^\\d{4}$/; d3.selectAll('.x>.tick>text').each(function(d){ var txt = this.textContent; if (re.test(txt)){ hasYear = true; } }); console.log(hasYear); </script> 

D3's time axis formatting checks whether any of the dates displayed on the ticks is on midnight, first of January to display only the year. D3的时间轴格式化检查刻度线上显示的任何日期是否在1月1日的午夜,以仅显示年份。 You can check whether a full year will be displayed by getting the ticks and then checking this condition: 您可以通过获取刻度并检查此条件来检查是否显示全年:

function isYear(t) {
  return +t == +(new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0));
}
var ticks = timeScale.ticks();
var willDisplayYear = ticks.some(isYear);

Complete demo for both cases here . 完整演示了这两种情况下在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM