D3.js: get tick format on a timeline

I am creating a timeline visualization with d3 where the domain can vary from a few days to several decades. I use the d3 timeline and axis like this:

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’s convenient to use ticks(x) , which automatically selects the tick format. My problem is that in some cases the year is not shown, which is crucial. My idea was to check the tick format after creating the axis, and if it does not contain a year, show it manually next to the axis. However, I could not get the scale format of the scale; using timeScale.tickFormat() just returns a function. How can I solve this problem?

+5
source share
2 answers

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 with different 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> 
+3
source

Formatting the time axis D3 checks to see if any of the dates displayed on the checkmarks is at midnight, the first of January, to display only the year. You can check whether the full year will be displayed by clicking the checkboxes 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); 

Fill out the demo for both cases here .

+1
source

Source: https://habr.com/ru/post/1238322/


All Articles