web-dev-qa-db-fra.com

Chart.js - Écriture d'étiquettes à l'intérieur de barres horizontales?

Dans Chart.js, existe-t-il un moyen d'écrire les étiquettes à l'intérieur des barres horizontales dans un "horizontalBar" graphique? Comme dans quelque chose comme:

this graph

Est-ce que quelque chose de similaire est possible dans Chart.js?

Merci!

12
antonin_scalia

Il y a maintenant l'option "miroir" pour faire apparaître l'étiquette à l'intérieur de la barre.

Exemple de configuration "options" pour un graphique horizontalBar:

options: {
    scales: {
        yAxes: [{ticks: {mirror: true}}]
    }
}

Doc: http://www.chartjs.org/docs/latest/axes/cartesian/#common-configuration

19
Elie

En référence à la solution originale pour afficher la valeur des données en utilisant la méthode HTML5 Canvas fillText() dans le animation's onComplete, le code ci-dessous vous obtiendra De quoi as-tu besoin:

La clé de l'affichage personnalisé des données liées au graphique consiste à inspecter le jeu de données du graphique comme dans this.data.datasets au dessous de. J'ai fait cela en inspectant où se trouvent les différentes valeurs dans cet ensemble de données, ainsi que la position pour les placer pour la méthode fillText.

Inspection de l'ensemble de données du graphique: Image

Script (Chart.js 2.0 et plus):

var barOptions = {
      events: false,
        showTooltips: false,
      legend: {
        display: false
      },
      scales:{
        yAxes: [{
          display: false
        }]
      },
        animation: {
        onComplete: function () {
          var ctx = this.chart.ctx;
          ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
          ctx.textAlign = 'left';
          ctx.textBaseline = 'bottom';

          this.data.datasets.forEach(function (dataset) {
            for (var i = 0; i < dataset.data.length; i++) {
              var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
                  left = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.left;
              ctx.fillStyle = '#444'; // label color
              var label = model.label;
              ctx.fillText(label, left + 15, model.y + 8);
            }
          });               
        }
        }
    };

jsFiddle: http://jsfiddle.net/jfvy12h9/

7
Hung Tran

Vous pouvez obtenir cet effet dans chartjs 2.0 + en faisant pivoter les étiquettes de 90 degrés et en appliquant un remplissage négatif, de sorte que l'étiquette remonte à l'intérieur de la "barre". Quelque chose comme ça:

new Chart(document.getElementById(id), {
  type: 'bar',
  data: data,
  options: {
    scales: {
      xAxes: [
        {
          ticks: {
            autoSkip: false,
            maxRotation: 90,
            minRotation: 90,
            padding: -110
          }
        }
      ]
    }
  }
});

Voir la cochez la documentation de configuration pour plus d'informations.

2
omnikron

Il semble qu'il n'y ait pas d'option directe pour cela en ce moment. Une implémentation possible consiste à parcourir les barres/colonnes en utilisant le crochet onAnimationComplete. Vous pouvez afficher cette question pour des explications détaillées comment afficher les valeurs de données sur Chart.js

J'aimerais que vous rappeliez que cela a un inconvénient. Puisqu'il utilise onAnimationComplete, chaque fois qu'une animation se produit sur le graphique, les valeurs disparaissent pendant une seconde et réapparaissent.

0
Kubilay Karpat

Étant donné que le graphique "à barres" ne fonctionne pas, l'option "miroir" ...

J'ai trouvé une solution de contournement: lien Fiddle

J'ai utilisé une version de chart.js 2.8.0 modifiée en ce lien

<html>
    <body>
        <canvas id="myChart" width="800" height="600">
        </canvas>
    </body>
</html>





var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: "bar",
data: {
labels: ["ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT"],
datasets: [{
    label: "Quota Eni mensile",
    backgroundColor: [
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)"
    ],
    borderColor: [
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)",
        "rgba(255, 255, 153, 1)"
    ],
    borderWidth: 1,
    data: [10, 11, 18, 10, 13, 28, 12, 16]
  }
  ]
},
options: {
    legend: {
        display: false
    },
    scales: {
        xAxes: [{
            ticks:{
                maxRotation: 90,
                minRotation: 90,
                display: "top"
             },          
         }],
         yAxes: [{
             display: false
         }]
     },
     tooltips: {
         enabled: true
     },
     maintainAspectRatio: true,
     responsive: true
 }

});

Chart.plugins.register({
/* Adjust axis labelling font size according to chart size */
  id: "responsiveXlabels",
  beforeDraw: function(c) {
      var chartHeight = c.chart.height;
      var size = (chartHeight * 2.5) / 100;
      var xAxis = c.scales["x-axis-0"];
      xAxis.options.ticks.minor.fontSize = size;
      xAxis.height = 10;
      xAxis.minSize.height = 10;
      c.options.scales.xAxes[0].ticks.padding = -size * 4.5;
      xAxis.margins.bottom = size * 12.5;
  },
  afterDraw: function(c) {
      c.options.scales.xAxes[0].ticks.padding = -158;
  }

});

le plugin responsiveXlabel est utilisé pour transformer le texte lors du redimensionnement. Il ne reste qu'une chose à résoudre: aligner le texte en bas de l'axe.

J'espère que cela aide ceux qui souhaitent implémenter la mise en miroir sur l'axe X et satisfaire la demande réactive.

0
erikthered65