Highcharts: ¿cómo puedo centrar las tags en un eje x datetime?

Me estaba costando mucho intentar averiguar cómo centrar las tags en un eje x datetime en Highcharts sin usar categorías y tickPlacement (ya que tickPlacement solo funciona en categorías).

Mi eje se creó dinámicamente, por lo que no podía simplemente establecer un desplazamiento x o un relleno, ya que esto haría que los ejes de diferentes intervalos se vieran extraños.

Después de perder el tiempo con las opciones de configuración, creo que encontré una solución que usa el formateador del eje x y algo de css / jquery noodling en la callback de Highcharts. Vea mi respuesta a continuación.

El truco es usar el objeto de tags del eje x de esta manera:

xAxis: { type: 'datetime', labels: { useHTML: true, align: 'center', formatter: function () { //using a specific class for the labels helps to ensure no other labels are moved return '' + Highcharts.dateFormat(this.dateTimeLabelFormat, this.value) + ''; } } 

Puede ver que el formateador conservará la fecha o el tiempo que el usuario haya configurado por defecto.

Luego tiene una callback que hace algo como esto:

 function (chart) { var $container = $(chart.container); var $labels = $container.find('.highcharts-axis-labels .timeline_label'); var $thisLabel, $nextLabel, thisXPos, nextXPos, delta, newXPos; $labels.each(function () { $thisLabel = $(this).parent('span'); thisXPos = parseInt($thisLabel.css('left')); $nextLabel = $thisLabel.next(); nextXPos = $nextLabel.length ? parseInt($nextLabel.css('left')) : chart.axes[0].left + chart.axes[0].width; delta = (nextXPos - thisXPos) / 2.0; newXPos = thisXPos + delta; if ($nextLabel.length || $(this).width() + newXPos < nextXPos) { $thisLabel.css('left', newXPos + 'px'); } else { $thisLabel.remove(); } }); }); 

En resumen, esto irá a través de cada etiqueta y determinará cuánto se debe mover (usando css) calculando la distancia entre ella y la siguiente etiqueta. Cuando llega a la última etiqueta, o bien la mueve sobre el extremo del eje para el cálculo o la elimina si no encaja. Esta última parte es solo la decisión que decidí tomar, probablemente puedes elegir hacer otra cosa como ajuste de palabras, etc.

Puedes ver el jsfiddle aquí.

Espero que esto ayude a algunas personas. Además, si hay mejoras, sería genial verlas aquí.

De acuerdo con la respuesta existente, hay una solución mucho más simple que también funciona al cambiar el tamaño de la ventana del navegador (o forzar el dibujo de otra manera), incluso cuando cambia el conteo de tics : http://jsfiddle.net/McNetic/eyyom2qg/3 /

Funciona al adjuntar el mismo controlador de eventos tanto a la load como a los eventos redraw :

 $('#container').highcharts({ chart: { events: { load: fixLabels, redraw: fixLabels } }, [...] 

El manejador se ve así:

  var fixLabels = function() { var labels = $('div.highcharts-xaxis-labels span', this.container).sort(function(a, b) { return +parseInt($(a).css('left')) - +parseInt($(b).css('left')); }); labels.css('margin-left', (parseInt($(labels.get(1)).css('left')) - parseInt($(labels.get(0)).css('left'))) / 2 ); $(labels.get(this.xAxis[0].tickPositions.length - 1)).remove(); }; 

Como ve, el ajuste adicional de las tags no es necesario (al menos si no tiene más de un xAxis). Basicamente funciona de esta manera:

  1. Obtenga todas las tags existentes (cuando se vuelve a dibujar, esto incluye las recién agregadas). 2. Ordenar por la propiedad css ‘izquierda’ (no se ordenan de esta manera después de algunos redibujados)
  2. Calcule el desplazamiento entre las dos primeras tags (el desplazamiento es el mismo para todas las tags)
  3. Establezca la mitad del desplazamiento como margen izquierdo de todas las tags, desplazándolos efectivamente a la mitad del desplazamiento hacia la derecha.
  4. Quite la etiqueta de la derecha (movida fuera del gráfico, a veces parcialmente visible).