简体   繁体   中英

d3.js time scale axis ticks are not equally spaced

I have drawn my x axis using d3.js-v3 time scale d3.time.scale() .
My axis ticks are not equally spaced. 在此处输入图片说明

How can I have equally spaced ticks?

Here is my code

 var customTimeFormat = d3.time.format("%d %b"); var margin = { top: 0, right: 20, bottom: 20, left: 20 }, width = 550 - margin.left - margin.right, height = 20 - margin.top - margin.bottom; var x = d3.time.scale() .domain([new Date("08/21/2019"), new Date("09/5/2019")]) .range([0, width]); var xAxis = d3.svg.axis() .scale(x) .tickFormat(customTimeFormat); 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);
 .axis text { font: 10px sans-serif; } .axis line, .axis path { fill: none; stroke: #000; shape-rendering: crispEdges; }
 <script src="https://d3js.org/d3.v3.min.js"></script>

d3.time.scale creates one tick every two days, but resets the ticks on the 1st day of the Month, giving this unwanted impression that scale is not even.

This behaviour can be controlled by using ticks function as shown below.

.ticks(d3.time.day, 1) will display one tick per day.

 var customTimeFormat = d3.time.format("%d %b"); var margin = { top: 0, right: 20, bottom: 20, left: 20 }, width = 550 - margin.left - margin.right, height = 20 - margin.top - margin.bottom; var x = d3.time.scale() .domain([new Date("08/20/2019"), new Date("09/05/2019")]) .range([0, width]); var xAxis = d3.svg.axis() .scale(x) .tickFormat(customTimeFormat) .ticks(d3.time.day, 1); 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);
 .axis text { font: 10px sans-serif; } .axis line, .axis path { fill: none; stroke: #000; shape-rendering: crispEdges; }
 <script src="https://d3js.org/d3.v3.min.js"></script>

You can get the ticks at 2 day interval by adding this to your axis definition

.ticks(d3.timeDay.filter(d => d3.timeDay.count(0, d) % 2 === 0))

see code snippet with d3 v5.7.0

 var customTimeFormat = d3.timeFormat("%d %b"); var margin = { top: 0, right: 20, bottom: 20, left: 20 }, width = 550 - margin.left - margin.right, height = 20 - margin.top - margin.bottom; var x = d3 .scaleTime() .domain([new Date("08/20/2019"), new Date("09/7/2019")]) .range([0, width]); var xAxis = d3 .axisBottom() .scale(x) .ticks(d3.timeDay.filter(d => d3.timeDay.count(0, d) % 2 === 0)) .tickFormat(customTimeFormat); 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);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <html> <body> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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