Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

272
Vistas
¿Cómo puedo eliminar las marcas no enteras mientras hago zoom con D3.js?

Problema: estoy tratando de crear un eje X lineal paneable/ampliable con marcas en cada número entero desde 0 hasta un número grande predefinido (digamos 1000 pero podría ser mucho más alto). Obviamente, esto no cabrá en la pantalla ni será legible, por lo que necesito que salga de la pantalla y sea paneable. Empezar con 0 a 10 es aceptable. Hay una serie de problemas con mi solución hasta ahora, pero el primero es que si hago zoom, D3 automáticamente agrega marcas entre los números enteros en lugares decimales para continuar teniendo 10 marcas en la pantalla. El segundo es cuando alejo el zoom, el rango se mostrará más allá de 1000.

Una nota rápida: los datos que se mostrarán son irrelevantes. El eje tiene que ir de 0 a 1000, independientemente de si hay un punto de datos en 1000 o no, por lo que no puedo determinar el dominio en función de mi conjunto de datos.

Soluciones que he probado:

  • .garrapatas(). Esto me permite especificar el número de ticks que quiero. Sin embargo, esto parece poner todas las marcas en el rango inicial especificado. Si aumento el ancho del rango más allá del tamaño de svg, se extienden las marcas, pero no de forma controlable (que yo sepa). Además, me encuentro con problemas de rendimiento en la panorámica y el zoom. Encuentro este comportamiento extraño ya que si no especifico ticks, hace un número infinito que puedo recorrer sin ningún retraso. Supongo que el retraso ocurre porque está tratando de generar los 1000 tics de inmediato y la funcionalidad d3.js predeterminada los procesa dinámicamente a medida que se desplaza. Esto parece una solución potencial, pero no estoy seguro de cómo ejecutarlo.
  • .tickValores(). Puedo proporcionar una matriz de 0 a 1000 y esto funciona, pero muestra exactamente el mismo comportamiento de retraso que .ticks(). Esto tampoco combina dinámicamente los ticks en 10 o 100 a medida que alejo el zoom.
  • .tickFormato(). Puedo ejecutar una función para que cualquier número no entero se convierta en una cadena vacía. Sin embargo, esto todavía deja la línea de verificación.

Aquí están las partes relevantes de mi código usando la última versión de D3.js(7.3):

 const height = 500 const width = 1200 const margin = { top: 20, right: 20, bottom: 20, left: 35 } const innerWidth = width - margin.left - margin.right const innerHeight = height - margin.top - margin.bottom const xScale = d3.scaleLinear() .domain([0, 10]) .range([0, innerWidth]) const svg = d3.select('svg') .attr("width", width) .attr("height", height) svg.append('defs').append('clipPath') .attr('id', 'clip') .append('rect') .attr('width', innerWidth) .attr('height', innerHeight) const zoom = d3.zoom() .scaleExtent([1, 8]) .translateExtent([ [0, 0], [xScale(upperBound), 0] ]) .on('zoom', zoomed) const g = svg.append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`) const xAxis = d3.axisBottom() .scale(xScale) const xAxisG = g.append('g') .style('clip-path', 'url(#clip)') .attr("class", "x-axis") .call(xAxis) .attr('transform', `translate(0, ${innerHeight})`) svg.call(zoom) function zoomed(event) { const updateX = event.transform.rescaleX(xScale) const zx = xAxis.scale(updateX) xAxisG.call(zx) }
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

En lugar de lidiar con los métodos del eje, simplemente puede seleccionar las marcas en el grupo de contenedores, eliminando los números no enteros:

 xAxisG.call(zx) .selectAll(".tick") .filter(e => e % 1) .remove();

Aquí está su código con ese cambio:

 const upperBound = 1000 const height = 100 const width = 600 const margin = { top: 20, right: 20, bottom: 20, left: 35 } const innerWidth = width - margin.left - margin.right const innerHeight = height - margin.top - margin.bottom const xScale = d3.scaleLinear() .domain([0, 10]) .range([0, innerWidth]) const svg = d3.select('svg') .attr("width", width) .attr("height", height) svg.append('defs').append('clipPath') .attr('id', 'clip') .append('rect') .attr('width', innerWidth) .attr('height', innerHeight) const zoom = d3.zoom() .scaleExtent([1, 8]) .translateExtent([ [0, 0], [xScale(upperBound), 0] ]) .on('zoom', zoomed) const g = svg.append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`) const xAxis = d3.axisBottom() .scale(xScale) .tickFormat(d => ~~d) const xAxisG = g.append('g') .style('clip-path', 'url(#clip)') .attr("class", "x-axis") .call(xAxis) .attr('transform', `translate(0, ${innerHeight})`) svg.call(zoom) function zoomed(event) { const updateX = event.transform.rescaleX(xScale) const zx = xAxis.scale(updateX) xAxisG.call(zx) .selectAll(".tick") .filter(e => e % 1) .remove(); }
 <script src="https://d3js.org/d3.v7.min.js"></script> <svg></svg>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda