Chart.js Fix issue #3589
by SAiTO TOSHiKi
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.js"></script>
<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 class="chart-container">
<canvas id="myChart4"></canvas>
</div>
</div>
<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
.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
// camvas clipping plugin
// See
// https://github.com/chartjs/Chart.js/issues/3506
// https://github.com/chartjs/Chart.js/issues/3491
// https://github.com/chartjs/Chart.js/issues/2873
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() {
var me = this;
var meta = me.getMeta();
var xScale = me.getScaleForId(meta.xAxisID);
var datasetCount = me.getBarCount();
var tickWidth = xScale.width / xScale.ticks.length;
var categoryWidth = tickWidth * xScale.options.categoryPercentage;
var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
var fullBarWidth = categoryWidth / datasetCount;
var barWidth = fullBarWidth * xScale.options.barPercentage;
var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
return {
datasetCount: datasetCount,
tickWidth: tickWidth,
categoryWidth: categoryWidth,
categorySpacing: categorySpacing,
fullBarWidth: fullBarWidth,
barWidth: barWidth,
barSpacing: barSpacing
};
},
calculateBarWidth: function(ruler) {
var xScale = this.getScaleForId(this.getMeta().xAxisID);
if (xScale.options.barThickness) {
return xScale.options.barThickness;
}
return xScale.options.stacked ? ruler.categoryWidth * xScale.options.barPercentage...