Chart.js 2.9.4 minBarLength issue with multiple chart
- Dominant language
- JavaScript
- Stars
- 67.7k
- Forks
- 11.9k
- Avg merge
- 7h 39m
- Merged PRs (30d)
- 5
Description
### Feature Proposal
Using the Chart.js 2.9.4 version, we are using both bar-type charts and line-type charts.
The problem is that the minimum value of the bar type chart is specified as 74 using the minBarLength option, but the line type chart does not keep up with the minimum value.
In other words, the line type should be drawn above the bar type, but it is not.

/////////// code
```
chartOptions: function() {
var pricePack = ["5000000", null, "7777000", "10000", "7777000"];
var dataPack = ["2월 2일", "2월 9일", "2월 16일", "2월 23일", "3월 2일"];
var ctx = document.getElementById("chartType-bar");
$mainColor = "#eaf9fa";
$pointColor = "#89e5ee";
$borderColor = "#62d4e2";
$linePointColor = "#1d7f97";
Chart.elements.Rectangle.prototype.draw = function() {
var ctx = this._chart.ctx;
var vm = this._view;
var left, right, top, bottom, signX, signY, borderSkipped, radius;
var borderWidth = vm.borderWidth;
var cornerRadius = this._chart.config.options.cornerRadius;
if (cornerRadius < 0) {
cornerRadius = 0;
}
if (typeof cornerRadius == "undefined") {
cornerRadius = 0;
}
if (!vm.horizontal) {
left = vm.x - vm.width / 2;
right = vm.x + vm.width / 2;
top = vm.y;
bottom = vm.base;
signX = 1;
signY = bottom > top ? 1 : -1;
borderSkipped = vm.borderSkipped || "bottom";
} else {
left = vm.base;
right = vm.x;
top = vm.y - vm.height / 2;
bottom = vm.y + vm.height / 2;
signX = right > left ? 1 : -1;
signY = 1;
borderSkipped = vm.borderSkipped || "left";
}
if (borderWidth) {
var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
borderWidth = borderWidth > barSize ? barSize : borderWidth;
var halfStroke = borderWidth / 2;
var borderLeft =
left + (borderSkipped !== "left" ? halfStroke * signX : 0);
var borderRight =
right + (borderSkipped !== "right" ? -halfStroke * signX : 0);
var borderTop =
top + (borderSkipped !== "top" ? halfStroke * signY : 0);
var borderBottom =
bottom + (borderSkipped !== "bottom" ? -halfStroke * signY : 0);
if (borderLeft !== borderRight) {
top = borderTop;
bottom = borderBottom;
}
if (borderTop !== borderBottom) {
left = borderLeft;
right = borderRight;
}
}
ctx.beginPath();
ctx.fillStyle = vm.backgroundColor;
ctx.strokeStyle = vm.borderColor;
ctx.lineWidth = borderWidth;
var corners = [
[left, bottom],
[left, top],
[right, top],
[right, bottom],
];
var borders = ["bottom", "left", "top", "right"];
var startCorner = borders.indexOf(borderSkipped, 0);
if (startCorner === -1) {
startCorner = 0;
}
function cornerAt(index) {
return corners[(startCorner + index) % 4];
}
var corner = cornerAt(0);
ctx.moveTo(corner[0], corner[1]);
for (var i = 1; i < 4; i++) {
corner = cornerAt(i);
nextCornerId = i + 1;
if (nextCornerId == 4) {
nextCornerId = 0;
}
nextCorner = cornerAt(nextCornerId);
width = corners[2][0] - corners[1][0];
height = corners[0][1] - corners[1][1];
x = corners[1][0];
y = corners[1][1];
var radius = cornerRadius;
if (radius > Math.abs(height) / 2) {
radius = Math.floor(Math.abs(height) / 1);
}
if (radius > Math.abs(width) / 2) {
radius = Math.floor(Math.abs(width) / 2);
}
if (height < 0) {
x_tl = x;
x_tr = x + width;
y_tl = y + height;
y_tr = y + height;
x_bl = x;
x_br = x + width;
y_bl = y;
y_br = y;
ctx.moveTo(x_bl + radius, y_bl);
ctx.lineTo(x_br - radius, y_br);
ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius);
ctx.lineTo(x_tr, y_tr + radius);
ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr);
ctx.lineTo(x_tl + radius, y_tl);
ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius);
ctx.lineTo(x_bl, y_bl - radius);
ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl);
} else if (width < 0) {
x_tl = x + width;
x_tr = x;
y_tl = y;
y_tr = y;
x_bl = x + width;
x_br = x;
y_bl = y + height;
y_br = y + height;
ctx.moveTo(x_bl + radius, y_bl);
ctx.lineTo(x_br - radius, y_br);
ctx.quadraticCurveTo(x_br, y_br, x_br, y_br - radius);
ctx.lineTo(x_tr, y_tr + radius);
ctx.quadraticCurveTo(x_tr, y_tr, x_tr - radius, y_tr);
ctx.lineTo(x_tl + radius, y_tl);
ctx.quadraticCurveTo(x_tl, y_tl, x_tl, y_tl + radius);
ctx.lineTo(x_bl, y_bl - radius);
ctx.quadraticCurveTo(x_bl, y_bl, x_bl + radius, y_bl);
} else {
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height);
ctx.quadraticCurveTo(
x + width,
y + height,
x + width - radius,
y + height
);
ctx.lineTo(x, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
}
}
ctx.fill();
if (borderWidth) {
ctx.stroke();
}
};
Chart.defaults.global.defaultFontSize = 11;
var chartWrap = new Chart(ctx, {
type: "bar",
plugins: [{
afterDraw: function(chart) {
var ctx = chart.chart.ctx;
var xAxis = chart.scales["x-axis-0"];
var yAxis = chart.scales["y-axis-0"];
ctx.save();
ctx.textAlign = "center";
chart.data.labels.forEach(function(l, i) {
var value = chart.data.labels[i];
var x = xAxis.getPixelForValue(l);
var color = i === 0 ? $linePointColor : (chart.data.datasets[0].data[i] === null ? "#9e9e9e" : "#424242");
ctx.fillStyle = color;
ctx.fillText(value, x, yAxis.bottom + 18);
});
ctx.restore();
},
}, ],
data: {
datasets: [{
data: pricePack,
type: "line",
pointStyle: "circleRot",
pointBorderWidth: 3,
pointRadius: 7,
pointHoverRadius: 7,
pointHoverBackgroundColor: "#fff",
pointBorderColor: [
$linePointColor,
$pointColor,
$pointColor,
$pointColor,
$pointColor,
],
backgroundColor: "#fff",
borderColor: $borderColor,
lineTension: 0,
hoverBorderColor: [
$linePointColor,
$pointColor,
$pointColor,
$pointColor,
$pointColor,
],
hoverBorderWidth: "3",
borderWidth: 1,
spanGaps: true,
datalabels: {
font: function(context) {
if (context.dataIndex === 0) {
return {
weight: 700,
};
} else {
return {
weight: 500,
};
}
},
},
},
{
data: pricePack.map(function(val) {
return val || 0;
}),
type: "bar",
backgroundColor: pricePack.map(function(val, index) {
if (val === null) {
return "#e0e0e0";
} else if (index === 0) {
return $pointColor;
} else {
return $mainColor;
}
}),
borderColor: "#D3687F",
barThickness: 40,
minBarLength: pricePack.map(function(val, index) {
if (val === null) {
return 8;
} else {
return 74;
}
}),
hoverBackgroundColor: [
$pointColor,
$mainColor,
$mainColor,
$mainColor,
$mainColor,
],
},
],
labels: dataPack,
},
options: {
layout: {
padding: {
top: 24,
left: 0,
right: 0,
bottom: 20,
},
},
aspectRatio: 1,
maintainAspectRatio: false,
tooltips: false,
cornerRadius: 8,
legend: {
display: false,
},
plugins: {
datalabels: {
position: 'outside',
display: function(context) {
if (context.dataset.type === 'line' && context.dataset.data[context.dataIndex] !== null) {
return true;
} else if (context.dataset.type === 'bar' && context.dataset.data[context.dataIndex] === 0) {
return true;
} else {
return false;
}
},
color: function(context) {
if (context.dataset.type === 'bar' && context.dataset.data[context.dataIndex] === 0) {
return "#bdbdbd";
} else {
return ["#1d7f97", "#9e9e9e", "#9e9e9e", "#9e9e9e", "#9e9e9e"];
}
},
clamp: true,
clip: false,
anchor: "top",
align: "top",
overlap: 'auto',
offset: function(context) {
if (context.dataset.type === 'bar' && context.dataset.data[context.dataIndex] === 0) {
return 3;
} else {
return 8;
}
},
formatter: function(value, context) {
var result = value
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if (value === 0) {
this.color = 'red';
return '수집중..';
} else {
return result;
}
}
},
},
scales: {
xAxes: [{
ticks: {
display: false,
beginAtZero: true,
},
gridLines: {
display: false,
},
}, ],
yAxes: [{
gridLines: {
display: false,
},
ticks: {
display: false,
beginAtZero: true,
},
}, ],
},
},
});
}
```
### Possible Implementation
Like the minBarLength of bar type, the minimum height value is added to the line type,
I hope it is added so that the line type can be drawn naturally by finding the offset top value of the bar type.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.