En mi gráfico d3.js, tengo datos de 2002 a 2023.
Verifiqué esto usando x.domain() , que devuelve:
0: Wed Jul 31 2002 00:00:00 GMT+0200 (Central European Summer Time) {} 1: Mon Jul 31 2023 00:00:00 GMT+0200 (Central European Summer Time) {}Luego trato de crear marcas en el eje x:
let x = d3.scaleTime() .rangeRound([0, 600]); let fiscal_year_ends_month = 10; d3.axisBottom(x) .tickFormat(d3.timeFormat("%m/%y")).ticks(data.length < 60 ? d3.timeMonth : d3.timeYear) .ticks(d3.timeDay.filter(function(d) { return d.getMonth() === fiscal_year_ends_month; }))Se supone que esto itera a través de todas las fechas en el rango, encuentra las que cumplen la condición de que el mes es lo que ingresé y crea las marcas.
Sin embargo, se ejecuta para el infinito.
Específicamente, si hago esto:
.ticks(d3.timeDay.filter(function(d) { console.log(d.getFullYear(), d.getMonth(), d.getDate()); return d.getMonth() === fiscal_year_ends_month; })) Parece comenzar al final de mi x.domain (2023) y retroceder hasta el infinito. Lo dejé correr por un tiempo y la última salida de console.log fue el 10 de junio de 322 a. C.:
-322 5 10No hace falta decir que mi cuadro de datos bursátiles no debería comenzar en el siglo IV a.
¿Por qué el proceso no se ejecuta solo a través de las fechas en mi x.domain() ?
El problema se puede volver a crear así:
.ticks(d3.timeDay.filter(function(d) { console.log(d.getFullYear(), d.getMonth(), d.getDate()); return false; // <--- generates infinite loop backward in time !! }))Esto sugiere un problema en sus datos de entrada con respecto al índice de mes que está tratando de filtrar. También sugiere que hay un error en la biblioteca que permite que esto suceda...
Con fiscal_year_ends_month = 10 , ¿supongo que desea tener solo los ticks de noviembre para cada año de datos? Hay un intervalo d3.timeMonth que puede usar para este propósito, por ejemplo:
.ticks(d3.timeMonth.filter(function(d) { return d.getMonth() === fiscal_year_ends_month; }));Ejemplo de trabajo:
// your constant const fiscal_year_ends_month = 10; // sample data let data = []; for (let i= 0; i<2370; i++) { let d = new Date() data.push({ dt: d.setDate(d.getDate() + i), val: i }); } // time scale let x = d3.scaleTime() .domain(d3.extent(data, d => d.dt)) .range([0, 540]); // render let svg = d3.select("body") .append("svg") .attr("width", 600) .attr("height", 150) .append("g") .attr("transform", "translate(30,30)"); let xAxis = d3.axisBottom(x) .tickFormat(d3.timeFormat("%m/%y")) .ticks(d3.timeMonth.filter(function(d) { return d.getMonth() === fiscal_year_ends_month; })); svg.append("g") .attr("transform", "translate(0,90)") .call(xAxis); <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>