Iniamudhan
Iniamudhan

Reputation: 508

chart.js label and value overlap issue

Bar chart tooptip(label) and value inside the bar gets overlapped on hover. I'm using angular2 to bind data to chart canvas. This is the output I get when the code below executed.

enter image description here

and the code below for chart.js option.

public ChartOptions: any = {
scaleShowVerticalLines: false,
responsive: true,
hover: {
  animationDuration: 0
},
tooltips: {
  headerFormat: '',
  custom: function (tooltip) {
    if (!tooltip) return;
    // disable displaying the color box;
    tooltip.displayColors = false;
    tooltip.titleFontSize = 0;
  },
  mode: 'label',
  callbacks: {

    title: function () {
    },
    label: function (tooltipItem, data) {
      return ["Year : " + tooltipItem.xLabel, "Return : " + tooltipItem.yLabel + '%'];
    }
  }
},
legend: { display: false },
animation: {
  duration: 0,
  onComplete: function () {
    var ctx = this.chart.ctx;

    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillStyle = "#fff";
    ctx.fontStyle = "bold";

    var maxBar = 0;

    this.data.datasets.forEach(dataset => {
      maxBar += Math.max.apply(null, dataset.data.map(Math.abs));
    });

    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;

        var y_pos = model.y + 18;
        //adjust negative values
        if (dataset.data[i] < 0) {
          y_pos = (model.y) - 2;
        }

        if (maxBar / Math.abs(dataset.data[i]) < 30) {

          var data = dataset.data[i];
          ctx.fillText((data == 0 || data == 0.0) ? "NA" : data + "%", model.x, y_pos);
        }
      }
    });
  }
},
scales: {
  xAxes: [{
    barPercentage: 0.7,
    ticks: {
      fontStyle: "bold",
      fontColor: "#000"
    },
    gridLines: {
      display: false
    }
  }],
  yAxes: [{
    ticks: {
      stepSize: 2,
      fontStyle: "bold",
      fontColor: "#000",
      callback: function (value, index) {
        return index % 2 === 0 ? (value + "%") : '';
      },
    },
    gridLines: {
      display: false
    },
    scaleLabel: {
      display: true,
    }
  }]
}  };

This ChartOptions is used in canvas as [options]="ChartOptions". Help me to resolve the issue. Thanks in advance.

Upvotes: 1

Views: 4514

Answers (1)

Iniamudhan
Iniamudhan

Reputation: 508

I don't have perfect workaround for my question. But I have some custom tooltip as a fix.

tooltips: {
  enabled: false,
  custom: function (tooltipModel) {
    // Tooltip Element
    var tooltipEl = document.getElementById('chartjs-tooltip');
    // Create element on first render
    if (!tooltipEl) {
      tooltipEl = document.createElement('div');
      tooltipEl.id = 'chartjs-tooltip';
      tooltipEl.innerHTML = "<table></table>";
      document.body.appendChild(tooltipEl);
    }

    // Hide if no tooltip
    if (tooltipModel.opacity === 0) {
      tooltipEl.style.opacity = '0';
      return;
    }

    // Set caret Position
    tooltipEl.classList.remove('above', 'below', 'no-transform');
    if (tooltipModel.yAlign) {
      tooltipEl.classList.add(tooltipModel.yAlign);
    } else {
      tooltipEl.classList.add('no-transform');
    }

    // Set Text
    if (tooltipModel.body) {
      let dataPoints = tooltipModel.dataPoints || [];

      let index = dataPoints[0].index;

      var innerHtml = '<thead>';

      innerHtml += '<tr><th class="text-left">Data to show</th><th >';

      innerHtml += '</thead><tbody></tbody>';
      var tableRoot = tooltipEl.querySelector('table');
      tableRoot.innerHTML = innerHtml;
    }

    var position = this._chart.canvas.getBoundingClientRect();

    // Display, position
    tooltipEl.style.opacity = '1';
    tooltipEl.style.minWidth = position.width * 0.4 + 'px';
    let middle = (position.left + position.right) / 2;
    tooltipEl.style.left = middle + 'px';
    tooltipEl.style.top = position.top + pageYOffset - 35 + 'px';

  }
},

And my result enter image description here

Upvotes: 1

Related Questions