1
votes

Chart.js - Modification des positions de graduation / étiquette pour les séries chronologiques de l'axe X

J'ai une série datetime le long de l'axe des x d'un graphique dans Chart.js mais j'ai changé la position de la graduation / des étiquettes pour qu'elle soit entre les barres selon la méthode ici:

Chart.js: Comment je change les graduations des axes x l'alignement des étiquettes dans toutes les tailles?

Cela a entraîné le déplacement des datetimes vers la droite de la barre à laquelle ils se rapportaient, alors que j'en avais besoin sur la gauche. J'ai donc changé le calcul du retour pour soustraire le montant au lieu d'ajouter:

var TimeCenterScale = Chart.scaleService.getScaleConstructor('time').extend({
    getPixelForTick: function(index) {
        var ticks = this.getTicks();
        if (index < 0 || index >= ticks.length) {
            return null;
        }
        // Get the pixel value for the current tick.
        var px = this.getPixelForOffset(ticks[index].value);

        // Get the next tick's pixel value.
        var nextPx = this.right;
        var nextTick = ticks[index + 1];
        if (nextTick) {
            nextPx = this.getPixelForOffset(nextTick.value);
        }

        // Align the labels in the middle of the current and next tick.
        return px - (nextPx - px) / 2;
    },
});

Cela fonctionne principalement sauf pour la dernière colonne. Comment puis-je aligner correctement cette dernière colonne?

 entrez la description de l'image ici


0 commentaires

3 Réponses :


0
votes

Je pense que le problème se situe à ces lignes

    var nextPx = this.right;
    var nextTick = ticks[index + 1];
    if (nextTick) {
       nextPx = this.getPixelForOffset(nextTick.value);
       return px - (nextPx - px) / 2;
    }
    else{
       var prevTick = ticks[index - 1];
       prevPx = this.getPixelForOffset(prevTick .value);
       return px - (px - prevPx ) / 2;
//       return px + (px - prevPx ) / 2;   if the above statement don't work

    }

Quand nextTick est nul, nextPx prend la valeur de this.right, ce qui crée un problème. Vous devez ajouter un bloc else pour que nextTick gère l'étiquette la plus à droite. J'ai mis à jour le code du bloc else . C'est juste une idée, vous trouverez peut-être un meilleur moyen.


1 commentaires

Je pense que tu as raison. Je pense que j'ai une solution maintenant, même si cela semble être un peu un hack! Je posterai une réponse



0
votes

Vous pouvez simplement définir offset: true sur vos axes x comme suit:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="chart" height="120"></canvas>

Veuillez consulter l'extrait de code exécutable ci-dessous.

new Chart("chart", {
  type: 'bar',
  data: {
    labels: ["2020-05-13", "2020-05-11", "2020-05-12", "2020-05-14", "2020-05-09", "2020-05-10"],
    datasets: [{
      label: "My Dataset",
      backgroundColor: "#02a499",
      borderColor: "#ffffff",
      borderWidth: 1,
      hoverBackgroundColor: "#02a499",
      hoverBorderColor: "#02a499",
      data: [20, 11, 9, 22, 11, 9]
    }]
  },
  options: {
    scales: {
      xAxes: [{
        offset: true,
        type: 'time',
        time: {
          unit: 'day',
          source: 'data',
          tooltipFormat: 'MMM DD'
        },
        gridLines: {
          display: false
        }
      }],
      yAxes: [{
        ticks: {
          beginAtZero: true
        },
        gridLines: {
          display: false
        }
      }]
    }
  }
});
options: {
  scales: {
    xAxes: [{
      offset: true,
      ...


1 commentaires

J'ai déjà offset: true dans les options de l'axe des x. Sans cela, les barres ne sont contenues dans le graphique à aucune extrémité, mais les graduations sont dans la bonne position!



0
votes

Sur la base de la réponse @MuhammadUmarFarooq, j'ai implémenté le code suivant pour vérifier la coche précédente s'il n'y en a pas une suivante. J'utilise distribution: 'series' donc toutes les graduations sur l'axe des x doivent être de la même distance, donc je ne fais que calculer la distance entre deux.

// Get the next tick's pixel value.
        var nextPx = this.right;
        var nextTick = ticks[index + 1];
        if (nextTick) {
            nextPx = this.getPixelForOffset(nextTick.value);
        } else {
            var previousPx = this.left;
            var previousTick = ticks[index - 1];
            previousPx = this.getPixelForOffset(previousTick.value);
            return previousPx + (px - previousPx) / 2;
        }

p >


2 commentaires

Je veux voter pour votre réponse, mais cette dernière déclaration n'a aucun sens pour moi return previousPx + (px - previousPx) / 2;


Le problème est qu'il n'y a pas de prochaine graduation, donc je ne peux pas réaligner la dernière graduation sur l'axe des x en utilisant la valeur nextPx. Comme la distance entre chaque graduation est la même, je peux utiliser la valeur de graduation précédente, mais au lieu de soustraire la moitié de la différence entre la valeur de graduation actuelle et suivante, j'ajoute la moitié de la différence entre la valeur de graduation précédente et actuelle, ce qui équivaut à à la même chose (s'il y avait eu un tick suivant). J'espère que cela a du sens!