chartjs issue #3589

by SAiTO TOSHiKi

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
<body>
  <div class="container">
    <div class="chart-container">
      <canvas id="myChart1"></canvas>
    </div>
    <div class="chart-container">
      <canvas id="myChart2"></canvas>
    </div>
    <div class="chart-container">
      <canvas id="myChart3"></canvas>
    </div>
  </div>
</body>

<script>
  window.chartColors = {
    red: 'rgb(255, 99, 132)',
    orange: 'rgb(255, 159, 64)',
    yellow: 'rgb(255, 205, 86)',
    green: 'rgb(75, 192, 192)',
    blue: 'rgb(54, 162, 235)',
    purple: 'rgb(153, 102, 255)',
    grey: 'rgb(231,233,237)'
  };

</script>

CSS

canvas {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

.chart-container {
  width: 500px;
  margin-left: 40px;
  margin-right: 40px;
  margin-bottom: 40px;
}

.container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
}

JavaScript

// report for chart.js v2.4.0
// Wrong category size of Bar with min option.

//------------------------------
// patch for chart.js v2.4.0
// fix / issue #3589 
// https://github.com/chartjs/Chart.js/issues/3589
//------------------------------

Chart.plugins.register({
    beforeDatasetsDraw: function (chartInstance) {
        var ctx = chartInstance.chart.ctx;
        var chartArea = chartInstance.chartArea;
        ctx.save();
        ctx.beginPath();
        ctx.rect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
        ctx.clip();
    },
    afterDatasetsDraw: function (chartInstance) {
        chartInstance.chart.ctx.restore();
    },
});

// temporaly override function for Bar controller
var oldConBar = Chart.controllers.bar;
Chart.controllers.bar = oldConBar.extend({

    getRuler: function (index) {
        var me = this;
        var meta = me.getMeta();
        var xScale = me.getScaleForId(meta.xAxisID);
        var datasetCount = me.getBarCount();

        var tickWidth;

        if (xScale.options.type === 'category') {
            tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index);
        } else {
            // Average width
            tickWidth = xScale.width / xScale.ticks.length;
        }
        var categoryWidth = tickWidth * xScale.options.categoryPercentage;
        var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
        var fullBarWidth = categoryWidth / datasetCount;

        // if (xScale.ticks.length !== me.chart.data.labels.length) {
        //     var perc = xScale.ticks.length / me.chart.data.labels.length;
        //     fullBarWidth = fullBarWidth * perc;
        // }

        var barWidth = fullBarWidth * xScale.options.barPercentage;
        var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);

        return {
            datasetCount: datasetCount,
            tickWidth:...