1👍
✅
Well As far as I know, you can prevent the overlap with the config (more than you already did), BUT you could do it yourself just calculating the diff between the ticks. You would have to eyeball die minDiff
, and in the tick generation return null if the ticks are too close.
I tried it in the following example:
(It is not prefect, because if there are many after each other, that are too short, "too many" ticks might be skipped)
In this example
11:29
could/should be shown, because11:00
was not displayed.
const d0 = moment.duration('08:50:00').asMinutes();
const d1 = moment.duration('09:00:00').asMinutes();
const d2 = moment.duration('10:45:00').asMinutes();
const d22 = moment.duration('11:00:00').asMinutes();
const d23 = moment.duration('11:29:00').asMinutes();
const d3 = moment.duration('17:35:00').asMinutes();
const d4 = moment.duration('19:00:00').asMinutes();
let values = [d0, d1, d2, d22, d23, d3, d4];
let data = {
labels: [''],
datasets: [{
label: 'up',
axis: 'y',
data: [d1],
backgroundColor: 'red',
},{
label: 'down',
axis: 'y',
data: [d2],
backgroundColor: 'yellow',
},{
label: 'uppsy',
axis: 'y',
data: [d22],
backgroundColor: 'green',
},{
label: 'uppsy1',
axis: 'y',
data: [d23],
backgroundColor: 'red',
},{
label: 'out',
axis: 'y',
data: [d3],
backgroundColor: 'yellow',
},{
label: 'up',
axis: 'y',
data: [d4],
backgroundColor: 'red',
}
]
};
const config = {
data,
type: 'bar',
options:{
plugins: {
tooltip: {
mode: 'dataset',
callbacks: {
label: function(item){
return moment().startOf('day').add({ minute: item.raw}).format('HH:mm');
}
}
},
legend: {
display: false,
},
title: {
display: false,
},
},
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
min: d0,
border: { display: false },
ticks: {
source: 'auto',
maxRotation: 80,
minRotation: 60,
autoSkip: false,
callback: function(value, index, ticks) {
let minDiff = 30;
if(index > 0 && value - ticks[index-1].value < minDiff){
console.info(ticks[index-1].value - value )
return null;
}
return moment().startOf('day').add({ minute: value}).format('HH:mm');
}
},
afterBuildTicks: axis => axis.ticks = values.map(v => ({ value: v }))
},
y: {
stacked: true,
grid: { display: false },
},
}
}};
new Chart(document.getElementById("chart"), config);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<script src="//cdn.jsdelivr.net/npm/moment@^2"></script>
<script src="//cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
<div class="chart" style="height:84px; width:350px;">
<canvas id="chart" ></canvas>
</div>
Update –maybe better solution:
You could filter the possible ticks before drawing the ticks, this makes it easier to see, if the minDiff
is applied in the correct manner.
values = values.reduce( (pre, curr, index) => {
if(index == 0 || (curr - pre[pre.length-1] > minDiff )){
pre.push(curr);
}
return pre;
}, [])
Here the full working demo:
const d0 = moment.duration('08:50:00').asMinutes();
const d1 = moment.duration('09:00:00').asMinutes();
const d2 = moment.duration('10:45:00').asMinutes();
const d22 = moment.duration('11:00:00').asMinutes();
const d23 = moment.duration('11:29:00').asMinutes();
const d3 = moment.duration('17:35:00').asMinutes();
const d4 = moment.duration('19:00:00').asMinutes();
let minDiff = 30;
let values = [d0, d1, d2, d22, d23, d3, d4];
/* prepare the ticks */
values = values.reduce( (pre, curr, index) => {
if(index == 0 || (curr - pre[pre.length-1] > minDiff )){
pre.push(curr);
}
return pre;
}, [])
let data = {
labels: [''],
datasets: [{
label: 'up',
axis: 'y',
data: [d1],
backgroundColor: 'red',
},{
label: 'down',
axis: 'y',
data: [d2],
backgroundColor: 'yellow',
},{
label: 'uppsy',
axis: 'y',
data: [d22],
backgroundColor: 'green',
},{
label: 'uppsy1',
axis: 'y',
data: [d23],
backgroundColor: 'red',
},{
label: 'out',
axis: 'y',
data: [d3],
backgroundColor: 'yellow',
},{
label: 'up',
axis: 'y',
data: [d4],
backgroundColor: 'red',
}
]
};
const config = {
data,
type: 'bar',
options:{
plugins: {
tooltip: {
mode: 'dataset',
callbacks: {
label: function(item){
return moment().startOf('day').add({ minute: item.raw}).format('HH:mm');
}
}
},
legend: {
display: false,
},
title: {
display: false,
},
},
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
min: d0,
border: { display: false },
ticks: {
source: 'auto',
maxRotation: 80,
minRotation: 60,
autoSkip: false,
callback: function(value, index, ticks) {
return moment().startOf('day').add({ minute: value}).format('HH:mm');
}
},
afterBuildTicks: axis => axis.ticks = values.map(v => ({ value: v }))
},
y: {
stacked: true,
grid: { display: false },
},
}
}};
new Chart(document.getElementById("chart"), config);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<script src="//cdn.jsdelivr.net/npm/moment@^2"></script>
<script src="//cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
<div class="chart" style="height:84px; width:350px;">
<canvas id="chart" ></canvas>
</div>
Source:stackexchange.com