ChartJS: Show all labels of a mixed chart in the tooltip - javascript

I have the below mixed chart, with bars & lines:
Below the code that generate the above chart:
var data = [{
label: 'Varience 1',
data: [15, -6, -6, 7],
borderColor: '#03A9F4',
pointBackgroundColor: '#03A9F4',
pointBorderWidth: 2,
pointStyle: 'rect',
type: 'line',
steppedLine: true,
borderWidth: 2
}, {
label: 'Varience 2',
data: [24, -2, 3, 19],
borderColor: '#FF5722',
pointBackgroundColor: '#FF5722',
pointBorderWidth: 2,
pointStyle: 'rect',
type: 'line',
steppedLine: true,
borderWidth: 2
}, {
label: 'Available',
data: [72, 62, 55, 65],
borderDash: [5, 5],
borderColor: '#bbb',
pointBackgroundColor: '#bbb',
pointBorderWidth: 2,
borderWidth: 2,
type: 'line'
}, {
label: 'Budget',
data: [50, 55, 45, 51],
borderDash: [5, 5],
borderColor: '#f0ab00',
pointBackgroundColor: '#fff',
pointBorderWidth: 2,
borderWidth: 2,
type: 'line'
}, {
label: 'Actual',
data: [65, 49, 39, 58],
backgroundColor: '#607D8B',
pointBorderWidth: 3,
borderWidth: 3
}, {
label: 'Last Year',
data: [41, 51, 36, 39],
borderColor: '#607D8B',
backgroundColor: 'rgba(96, 125, 139, 0.25)',
pointBorderWidth: 3,
borderWidth: 3
}];
data.forEach(function (obj) {
obj.fill = 'false';
});
Below the code to show the custom tooltip:
tooltips: {
callbacks: {
label: function tooltipWithoutTotal(tooltipItem, data) {
var type = data.datasets[tooltipItem.datasetIndex].label;
var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
if (tooltipItem.datasetIndex !== data.datasets.length - 1) {
return type + " : " + value.toFixed(0).replace(/(\d)(?=(\d{3})+\.)/g, '1,');
} else {
return [type + " : " + value.toFixed(0).replace(/(\d)(?=(\d{3})+\.)/g, '1,')];
}
}
}
}
With the above tooltip code I expected to list all the values in the tooltip (like this: https://jsfiddle.net/kingBethal/r23y0h6n/).
However, in the tooltip it is showing only individual values.
Here is the JSFiddle: https://jsfiddle.net/kingBethal/dqpusowy/6/

Set the tooltip interaction mode to index:
options = {
tooltips: {
mode: 'index'
}
}
Result:

The new syntax for Chart JS 3+ :
options: {
interaction: {
intersect: false,
mode: 'index',
}
}

Related

How to customize chart.js tooltip (react-chartjs-2)?

I need to create a customized external tooltip for my project.
This is how it looks like now >>
2nd image is how it should look like >>
My dataset:
datasets: [
//Systolic Avarage Line --------
{
label: 'Systolic Avarage Line',
backgroundColor: 'transparent',
data: bloodPressureData?.systolicAvarageLine?.data,
borderWidth: 2,
borderColor: 'rgb(0,0,0,0.15)',
pointBorderWidth: 0,
pointRadius: 1,
order: 9,
type: 'line'
},
//Diastolic Avarage Line --------
{
label: 'Diastolic Avarage Line',
backgroundColor: 'transparent',
data: bloodPressureData?.diastolicAvarageLine?.data,
borderWidth: 2,
borderColor: 'rgb(0,0,0,0.15)',
pointBorderWidth: 0,
pointRadius: 1,
order: 9,
type: 'line'
},
//Systolic Bar --------
{
label: 'Systolic Bar',
backgroundColor: bloodPressureData?.sysBar?.map((item) => {
const colorsArr = item?.colors;
const colorFound = colorsArr?.reduce((prev, current) =>
+prev?.riskScore > +current?.riskScore ? prev : current
);
return colorFound?.color;
}),
data: bloodPressureData?.sysBar?.map((v) => [v?.max, v?.min]),
barThickness: 14,
maxBarThickness: 14,
barPercentage: 1,
categoryPercentage: 1,
borderRadius: 50,
order: 2
},
//Diastolic Bar --------
{
label: 'Diastolic Bar',
backgroundColor: theme.palette.primary.main,
data: bloodPressureData?.diaBar?.map((v) => [v?.max, v?.min]),
barThickness: 14,
maxBarThickness: 14,
barPercentage: 1,
categoryPercentage: 1,
borderRadius: 50,
order: 8
},
//Systolic Min Scatter --------
{
label: 'Systolic Min Scatter',
backgroundColor: () => {
const selectedColorArr = bloodPressureData?.sysMin?.colors?.map(
(item) => {
const colorObj = item.reduce((prev, current) =>
+prev?.riskScore > +current?.riskScore ? prev : current
);
return colorObj?.color;
}
);
return selectedColorArr;
},
data: bloodPressureData?.sysMin?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 1,
type: 'scatter'
},
//Systolic Max Scatter --------
{
label: 'Systolic Max Scatter',
backgroundColor: () => {
const selectedColorArr = bloodPressureData?.sysMax?.colors?.map(
(item) => {
const colorObj = item?.reduce((prev, current) =>
+prev?.riskScore > +current?.riskScore ? prev : current
);
return colorObj?.color;
}
);
return selectedColorArr;
},
data: bloodPressureData?.sysMax?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 1,
type: 'scatter'
},
//Diastolic Min Scatter --------
{
label: 'Diastolic Min Scatter',
backgroundColor: theme.palette.primary.main,
data: bloodPressureData?.diaMin?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 6,
type: 'scatter'
},
//Diastolic Max Scatter --------
{
label: 'Diastolic Max Scatter',
backgroundColor: theme.palette.primary.main,
data: bloodPressureData?.diaMax?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 7,
type: 'scatter'
}
]
And my options.tooltips looks like below:
tooltips: {
enabled: true,
callbacks: {
title: (tooltipItem, data) => {
if (selectedTimeSpan === TimeSpan.TODAY) {
return `${data['labels'][tooltipItem[0]['index']]}:00`;
} else if (selectedTimeSpan === TimeSpan.WEEK) {
return `${getWeekHoverTitle(
data['labels'][tooltipItem[0]['index']]
)} ${moment(selectedDateTime).format('MMMM').slice(0,3)} ${
data['labels'][tooltipItem[0]['index']]
}`;
} else if (selectedTimeSpan === TimeSpan.MONTH) {
return `${data['labels'][tooltipItem[0]['index']]} ${moment(
selectedDateTime
).format('MMMM')} `;
} else {
return `${moment(
`${data['labels'][tooltipItem[0]['index']]}`,
'MM'
).format('MMMM')}`;
}
},
beforeLabel: function () {
return `Systolic`;
},
label: function (tooltipItem, data) {
return `${data['datasets'][2]['data'][tooltipItem['index']]} ${measurementValueKey}`;
// data['datasets'][0]['data'][tooltipItem['index']]
},
afterLabel: function (tooltipItem, data) {
return `${data['datasets'][2]['data'][tooltipItem['index']]} ${measurementValueKey}`;
// data['datasets'][0]['data'][tooltipItem['index']]
},
},
mode: 'index',
intersect: false,
caretSize: 6,
displayColors: true,
yPadding: 10,
xPadding: 20,
borderWidth: 0,
bodySpacing: 10,
titleFontSize: 16,
backgroundColor: '#6E759F',
titleFontColor: theme.palette.common.white,
bodyFontColor: theme.palette.common.white,
footerFontColor: theme.palette.common.white
},

How can I animate my line charts as soon as I click on a specific tab?

I am looking for a solution to load my line chart as soon as I click on different tabs. In this case, I need to admit that I use Webflow as my platform and based on that I embed my code so even if you do not see any tabs in my code I can easily link it to my Webflow Tabs. Hope you can help me out to fit it into my almost finished product. Attached you find an image:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<div class="wrapper" id='front-end-engineer' style="height:600px;position: relative;margin-top:50px;">
<canvas id="mychart2" style="display: block; width: 958px; height: 478px;"></canvas>
</div>
<script>
var canvas2 = document.getElementById("mychart2");
var ctx2 = canvas2.getContext('2d');
const decimals2 = 0;
var config2 = {
type: 'line',
data: {
labels: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9+'],
datasets: [{
label: "25th Percentile",
backgroundColor: '#c4c1ff',
pointBackgroundColor: "#645bff",
borderColor: '#645bff',
fill: 4,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3, //no fill here
data: [31, 32, 35, 42, 50, 50, 58, 60, 74]
}, {
label: "10th - 90th Percentile",
backgroundColor: '#c4c1ff',
pointBackgroundColor: "#c4c1ff",
borderColor: '#c4c1ff',
pointHoverBackgroundColor: "#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderWidth: 1,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
fill: 3,
//no fill here
data: [36, 45, 45, 55, 55, 59, 75, 85, 119]
}, {
label: "Median",
backgroundColor: '#0d0e25',
pointBackgroundColor: "#0d0e25",
borderColor: '#0d0e25',
borderWidth: 1,
pointRadius: 2,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
fill: false, //no fill here
data: [31, 38, 40, 45, 50, 55, 60, 75, 90]
},
{
label: "25th - 75th Percentile",
showInLegend: false,
backgroundColor: '#645bff',
pointBackgroundColor: "#645bff",
borderColor: '#645bff',
pointRadius: 0,
lineTension: 0.1,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
fill: 0,
//fill until previous dataset
data: [34, 42, 45, 50, 54, 58, 66, 80, 110]
}, {
label: "10th Percentile",
backgroundColor: "#c4c1ff",
pointBackgroundColor: "#c4c1ff",
pointHoverBackgroundColor: "#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderColor: "#c4c1ff",
pointStyle: "circle",
borderWidth: 1,
lineWidth: 1,
hoverRadius: 9,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
lineTension: 0.3,
fill: '0',
data: [25, 30, 36, 39, 45, 49, 53, 56, 60, 68]
}
]
},
options: {responsive:true,maintainAspectRatio:false,
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
if (label === "25th - 75th Percentile: ") {
label = "75th Percentile: "
}
if (label === "10th - 90th Percentile: ") {
label = "90th Percentile: "
}
label += tooltipItem.yLabel
return label;
}
}
},
title: {
display: true,
text: 'Backend Engineer salaries (1242 datapoints)',
fontSize: 20,position:'top'
},
maintainAspectRatio: false,
legend: {
onClick: (e) => e.stopPropagation(),
display: true,
labels: {
filter: function(item,
mychart2) {
return item.datasetIndex !== 0 && item.datasetIndex !== 4;
}
}
},
spanGaps: false,
elements: {
line: {
tension: 0.000001
}
},
plugins: {
filler: {
propagate: false
}
},
scales: { yAxes: [{
id: 'a',
type: 'linear',
position: 'left',
gridLines: {
drawOnChartArea:false
},
scaleLabel: {
display: true,
labelString: 'Salary',
fontSize: 20
},
ticks: {
beginAtZero: true,
stepSize: 20,
callback: function(value, index, values) {
return '$' + value.toFixed(decimals)
}
}
}, {
id: 'b',
type: 'linear',
position: 'right',
ticks: {
display: false},
gridLines: {
lineWidth:0.5
},
scaleLabel: {
display: false
},
ticks: {
display: false,
beginAtZero: true,
stepSize: 20
}
}] ,xAxes: [{
gridLines: {
drawOnChartArea:false
},
ticks: {
beginAtZero: true,
stepSize: 20,
},
scaleLabel: {
display: true,
labelString: 'Years of relevant experience',
fontSize: 20
}
}]
}
}
};
var chart2 = new Chart(ctx2, config2);
</script>

How can I change the legend label without affecting my tooltip label?

I am trying to find a solution to my problem. I have changed the legend label into 25th - 75th Percentile. So far so good this is correct. However, the problem arises when I hover over the line. It should be 75th Percentile when I am on top and not 25th - 75th Percentile. This is an issue that I could not figure out yet. I hope you can help me out. Additionally, I want to make this for each line so in case I have 10th - 90th Percentile. I want to hover over the two lines and get 90th percentile or 10th Percentile. I also attach an imageenter image description here
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="mychart2" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById("mychart2");
var ctx = canvas.getContext('2d');
const decimals = 0;
var config = { //configure the chart
type: 'line',
data: {
labels: ['0', '1', '2', '3','4','5','6','7','8','9+'],
datasets: [{
label: "25th Percentile",
showInLegend: true,
backgroundColor: '#c4c1ff',
pointBackgroundColor:"#645bff",
borderColor: '#645bff',
fill: 4,
pointRadius:0,
pointBorderWidth:3,
pointHoverRadius:3,
pointHitRadius:3,//no fill here
data: [28, 35, 40, 45,50,55,62,66,70,78]
},{
label: "90th Percentile",
backgroundColor: '#c4c1ff',
pointBackgroundColor:"#c4c1ff",
borderColor: '#c4c1ff',
pointHoverBackgroundColor:"#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderWidth:1,
pointRadius:0,
pointBorderWidth:3,
pointHoverRadius:3,
pointHitRadius:3,
fill: 3,
//no fill here
data: [40, 65, 63, 64,72,79,83,87,100,108]
},{
label: "Median",
backgroundColor: '#0d0e25',
pointBackgroundColor:"#0d0e25",
borderColor: '#0d0e25',
borderWidth:1,
pointRadius:2,
pointBorderWidth:3,
pointHoverRadius:3,
pointHitRadius:3,
fill: false, //no fill here
data: [30, 40, 45, 50, 56, 60, 66,73 ,78,85]},
{
label: "25th - 75th Percentile",
tooltipTitle:"75th Percentile",
showInLegend: false,
backgroundColor: '#645bff',
pointBackgroundColor:"#645bff",
borderColor: '#645bff',
pointRadius:0,
lineTension: 0.1,
pointBorderWidth:3,
pointHoverRadius:3,
pointHitRadius:3,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
fill:0 ,
//fill until previous dataset
data: [35, 50, 51, 55,63,69,73,80,85,94]
},{
label: "10th Percentile",
backgroundColor: "#c4c1ff",
pointBackgroundColor:"#c4c1ff",
pointHoverBackgroundColor:"#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderColor: "#c4c1ff",
pointStyle:"circle",
borderWidth:1,
lineWidth:1,
hoverRadius:9,
pointRadius:0,
pointBorderWidth:3,
pointHoverRadius:3,
pointHitRadius:3,
lineTension:0.3,
fill: '0', //fill until previous dataset
data: [25, 30, 36, 39, 45, 49, 53,56,60,68]
}]
},
options: {title: {display:true, text: 'Frontend Engineer salaries (753 datapoints)',fontSize:20},
maintainAspectRatio: false,
legend: {onClick: (e) => e.stopPropagation(),display:true, labels: {filter:function(item,
mychart2)
{return !item.text.includes("10th - 90th Percentile" & "10th Percentile");}}},
spanGaps: false,
elements: {
line: {
tension: 0.000001
}
},
plugins: {
filler: {
propagate: false
}
},
scales: {
yAxes: [{gridLines: {display:false}, scaleLabel: {display: true, labelString: 'Salary',
fontSize:20},
ticks: {beginAtZero:true, stepSize: 20,callback: function(value, index, values) {
return '$' + value.toFixed(decimals)}
}
}], xAxes: [{gridLines: {display:false},
ticks: {beginAtZero:true, stepSize: 20,
}, scaleLabel: {
display: true,
labelString: 'Years of relevant experience',
fontSize: 20 }
}]
}
}
};
var chart = new Chart(ctx, config);
</script>
tooltipTitle is not a property in chart.js. To adjust the title you will have to implement a custom callback like this:
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
if (label === "25th - 75th Percentile: ") {
label = "75th Percentile: "
}
if (label === "10th - 90th Percentile: ") {
label = "90th Percentile: "
}
label += tooltipItem.yLabel
return label;
}
}
}
}
Example:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<canvas id="mychart2" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById("mychart2");
var ctx = canvas.getContext('2d');
const decimals = 0;
var config = { //configure the chart
type: 'line',
data: {
labels: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9+'],
datasets: [{
label: "25th Percentile",
showInLegend: true,
backgroundColor: '#c4c1ff',
pointBackgroundColor: "#645bff",
borderColor: '#645bff',
fill: 4,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3, //no fill here
data: [28, 35, 40, 45, 50, 55, 62, 66, 70, 78]
}, {
label: "90th Percentile",
backgroundColor: '#c4c1ff',
pointBackgroundColor: "#c4c1ff",
borderColor: '#c4c1ff',
pointHoverBackgroundColor: "#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderWidth: 1,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
fill: 3,
//no fill here
data: [40, 65, 63, 64, 72, 79, 83, 87, 100, 108]
}, {
label: "Median",
backgroundColor: '#0d0e25',
pointBackgroundColor: "#0d0e25",
borderColor: '#0d0e25',
borderWidth: 1,
pointRadius: 2,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
fill: false, //no fill here
data: [30, 40, 45, 50, 56, 60, 66, 73, 78, 85]
},
{
label: "25th - 75th Percentile",
showInLegend: false,
backgroundColor: '#645bff',
pointBackgroundColor: "#645bff",
borderColor: '#645bff',
pointRadius: 0,
lineTension: 0.1,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
fill: 0,
//fill until previous dataset
data: [35, 50, 51, 55, 63, 69, 73, 80, 85, 94]
}, {
label: "10th Percentile",
backgroundColor: "#c4c1ff",
pointBackgroundColor: "#c4c1ff",
pointHoverBackgroundColor: "#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderColor: "#c4c1ff",
pointStyle: "circle",
borderWidth: 1,
lineWidth: 1,
hoverRadius: 9,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
lineTension: 0.3,
fill: '0', //fill until previous dataset
data: [25, 30, 36, 39, 45, 49, 53, 56, 60, 68]
}
]
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
if (label === "25th - 75th Percentile: ") {
label = "75th Percentile: "
}
label += tooltipItem.yLabel
return label;
}
}
},
title: {
display: true,
text: 'Frontend Engineer salaries (753 datapoints)',
fontSize: 20
},
maintainAspectRatio: false,
legend: {
onClick: (e) => e.stopPropagation(),
display: true,
labels: {
filter: function(item,
mychart2) {
return !item.text.includes("10th - 90th Percentile" & "10th Percentile");
}
}
},
spanGaps: false,
elements: {
line: {
tension: 0.000001
}
},
plugins: {
filler: {
propagate: false
}
},
scales: {
yAxes: [{
gridLines: {
display: false
},
scaleLabel: {
display: true,
labelString: 'Salary',
fontSize: 20
},
ticks: {
beginAtZero: true,
stepSize: 20,
callback: function(value, index, values) {
return '$' + value.toFixed(decimals)
}
}
}],
xAxes: [{
gridLines: {
display: false
},
ticks: {
beginAtZero: true,
stepSize: 20,
},
scaleLabel: {
display: true,
labelString: 'Years of relevant experience',
fontSize: 20
}
}]
}
}
};
var chart = new Chart(ctx, config);
</script>

How can I build a vertical line without going through my dots on my line graph? (charts.js)

Hey guys I have created a line chart that is almost done. The only thing that annoys me is the fact that there is some white space on the right-hand side of the graph. I would like to create a vertical line that does not go through the dots. It should be a smooth line without affecting the dots at the end of the line chart
enter image description here
[<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<canvas id="mychart2" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById("mychart2");
var ctx = canvas.getContext('2d');
const decimals = 0;var originalLineDraw = Chart.controllers.line.prototype.draw;
Chart.helpers.extend(Chart.controllers.line.prototype, {
draw: function() {
originalLineDraw.apply(this, arguments);
var chart = this.chart;
var ctx = chart.chart.ctx;
var index = chart.config.data.lineAtIndex;
if (index) {
var xaxis = chart.scales\['x-axis-0'\];
var yaxis = chart.scales\['y-axis-0'\];
ctx.save();
ctx.beginPath();
ctx.moveTo(xaxis.getPixelForValue(undefined, index), yaxis.top);
ctx.strokeStyle = '#F6F6F6';
ctx.lineWidth = 1;
ctx.borderDashOffset = 0.0;
ctx.color = 'rgba(0, 0, 0, 1)';
ctx.zeroLineColor = "rgba(0, 0, 0, 0.25)";
ctx.tickMarkLength = 10;
ctx.lineTo(xaxis.getPixelForValue(undefined, index), yaxis.bottom);
ctx.stroke();
ctx.restore();
}
}
});
var config = { //configure the chart
type: 'line',
data: {
labels: \['0', '1', '2', '3', '4', '5', '6', '7', '8', '9+'\],
datasets: \[{
label: "25th Percentile",
showInLegend: false,
backgroundColor: '#c4c1ff',
pointBackgroundColor: "#645bff",
borderColor: '#645bff',
fill: 4,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3, //no fill here
data: \[28, 35, 40, 45, 50, 55, 62, 66, 70, 78\]
}, {
label: "90th Percentile",
backgroundColor: '#c4c1ff',
pointBackgroundColor: "#c4c1ff",
borderColor: '#c4c1ff',
pointHoverBackgroundColor: "#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderWidth: 1,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
fill: 3,
//no fill here
data: \[40, 65, 63, 64, 72, 79, 83, 87, 100, 108\]
}, {
label: "Median",
backgroundColor: '#0d0e25',
pointBackgroundColor: "#0d0e25",
borderColor: '#0d0e25',
borderWidth: 1,
pointRadius: 2,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
fill: false, //no fill here
data: \[30, 40, 45, 50, 56, 60, 66, 73, 78, 85\]
},
{
label: "25th - 75th Percentile",
showInLegend: false,
backgroundColor: '#645bff',
pointBackgroundColor: "#645bff",
borderColor: '#645bff',
pointRadius: 0,
lineTension: 0.5,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
borderCapStyle: 'butt',
borderDash: \[\],
borderDashOffset: 0.1,
borderJoinStyle: 'miter',
fill: 0,
//fill until previous dataset
data: \[35, 50, 51, 55, 63, 69, 73, 80, 85, 94\]
}, {
label: "10th Percentile",
backgroundColor: "#c4c1ff",
pointBackgroundColor: "#c4c1ff",
pointHoverBackgroundColor: "#c4c1ff",
pointHoverBorderColor: "#c4c1ff",
borderColor: "#c4c1ff",
pointStyle: "circle",
borderWidth: 1,
lineWidth: 1,
hoverRadius: 9,
pointRadius: 0,
pointBorderWidth: 3,
pointHoverRadius: 3,
pointHitRadius: 3,
lineTension: 0.3,
fill: '0', //fill until previous dataset
data: \[25, 30, 36, 39, 45, 49, 53, 56, 60, 68\]
}
\], lineAtIndex: 9
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets\[tooltipItem.datasetIndex\].label || '';
if (label) {
label += ': ';
}
if (label === "25th - 75th Percentile: ") {
label = "75th Percentile: "
}
label += tooltipItem.yLabel
return label;
}
}
},
title: {
display: true,
text: 'Frontend Engineer salaries (753 datapoints)',
fontSize: 20
},
maintainAspectRatio: false,
legend: {
onClick: (e) => e.stopPropagation(),
display: true,
labels: {
filter: function(item,
mychart2) {
return !item.text.includes("25th Percentile" & "10th Percentile")
}
}
},
spanGaps: false,
elements: {
line: {
tension: 0.1
}
},
plugins: {
filler: {
propagate: false
}
},
scales: {
yAxes: \[{
gridLines: {drawOnChartArea:false
},
scaleLabel: {
display: true,
labelString: 'Salary',
fontSize: 20
},
ticks: {
beginAtZero: true,
stepSize: 20,
callback: function(value, index, values) {
return '$' + value.toFixed(decimals)
}
}
}\],
xAxes: \[{
gridLines: {drawOnChartArea:false
},
ticks: {
beginAtZero: true,
stepSize: 20,
},
scaleLabel: {
display: true,
labelString: 'Years of relevant experience',
fontSize: 20
}
}\]
}
}
};
var chart = new Chart(ctx, config)
</script>][1]
how should the vertical line look like?
do you mean the median line?
it would be helpful, if you can show us what kind of vertical line you mean, or at least tell us a function, so we know how the line should look like
EDIT:
You can add a 2nd yAxis to the right side.
Replace this for yAxes:
yAxes: [{
id: 'a',
type: 'linear',
position: 'left',
gridLines: {
drawOnChartArea:false
},
scaleLabel: {
display: true,
labelString: 'Salary',
fontSize: 20
},
ticks: {
beginAtZero: true,
stepSize: 20,
callback: function(value, index, values) {
return '$' + value.toFixed(decimals)
}
}
}, {
id: 'b',
type: 'linear',
position: 'right',
gridLines: {
drawOnChartArea:false
},
scaleLabel: {
display: false
},
ticks: {
display: false,
beginAtZero: true,
stepSize: 1
}
}]

Chart JS custom tooltip not showing

I have a line graph and I want to alter it's tooltip. I want it, on hover, to show the follow (as an example):
Question: This is question 1
Your answers: 3
Average answers: 7
Your average: 5
Average: 7
The data in the tooltip is fine and works. See this fiddle here
What I'm trying to do is to add to the tooltip so that it can display the question in it too.
What I've tried:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset=data.datasets[tooltipItem.datasetIndex];
return data.datasets[tooltipItem.datasetIndex].label+ ' : ' +dataset.data[tooltipItem.index]+questions[i];
}
}
}
var q1 = "This is question 1";
var q2 = "This is question 2";
var q3 = "This is question 3";
var q4 = "This is question 4";
var q5 = "This is question 5";
var questions = [q1, q2, q3, q4, q5];
var questionsArrayLength = questions.length;
for (var i = 0; i < questionsArrayLength; i++) {
console.log(questions[i]);
}
var canvas = document.getElementById('chart');
canvas.height = 500;
var data = {
labels: ["Q1", "Q2", "Q3", "Q4", "Q5"],
datasets: [{
label: "Your answers",
fill: false,
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "rgba(75,192,192,1)",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 5,
decimals: false,
pointHitRadius: 10,
data: [1,3,4,5,3],
stack: 4
},
{
label: "Average answers",
fill: false,
lineTension: 0.1,
borderColor: "rgba(79,104,241,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "rgba(79,104,241,1)",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(79,104,241,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 5,
decimals: false,
pointHitRadius: 10,
data: [2, 7, 5, 10, 3],
stack: 5
},
{
label: "Your average",
pointStyle: 'line',
fill: false,
borderColor: "#ffffff",
borderCapStyle: 'round',
borderDash: [0.5, 5],
borderDashOffset: 1,
lineTension: 0.1,
data: [5, 5, 5, 5, 5],
},
{
label: "Average",
pointStyle: 'line',
fill: false,
borderColor: "#ffffff",
borderCapStyle: 'round',
borderDash: [5, 8],
borderDashOffset: 0.6,
lineTension: 0.1,
data: [7, 7, 7, 7, 7],
},
]
};
var options = {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset=data.datasets[tooltipItem.datasetIndex];
return data.datasets[tooltipItem.datasetIndex].label+ ' : ' +dataset.data[tooltipItem.index]+questions[i];
}
}
},
plugins: {
filler: {
propagate: true
}
},
responsive: true,
maintainAspectRatio: false,
tooltips: {
mode: 'index'
},
showLines: true,
scales: {
yAxes: [{
gridLines: {
color: 'rgb(255, 255, 255)',
z: 2
},
scaleLabel: {
display: true,
labelString: 'Scores'
},
stacked: false,
ticks: {
beginAtZero: 0,
suggestedMin: 1,
suggestedMax: 10,
stepSize: 2,
userCallback: function(label, index, labels) {
// when the floored value is the same as the value we have a whole number
if (Math.floor(label) === label) {
return label;
}
},
}
}],
xAxes: [{
gridLines: {
color: 'rgb(255, 255, 255)',
z: 2
},
scaleLabel: {
display: true,
labelString: 'Questions'
},
}]
},
annotation: {
annotations: [
{
drawTime: "beforeDatasetsDraw",
type: "box",
id: "n",
xScaleID: "x-axis-0",
yScaleID: "y-axis-0",
xMin: "Q1",
xMax: "Q5",
yMin: 0,
yMax: 3.7,
backgroundColor: "rgba(26,26,26,0.6)",
borderColor: "rgba(26,26,26,0.6)",
borderWidth: 1,
},
{
drawTime: "beforeDatasetsDraw",
type: "box",
xScaleID: "x-axis-0",
yScaleID: "y-axis-0",
xMin: "Q1",
xMax: "Q5",
yMin: 3.7,
yMax: 7,
backgroundColor: 'rgba(88,88,88,0.6)',
borderColor: 'rgba(88,88,88,0.6)',
borderWidth: 1,
},
{
drawTime: "beforeDatasetsDraw",
type: "box",
xScaleID: "x-axis-0",
yScaleID: "y-axis-0",
xMin: "Q1",
xMax: "Q5",
yMin: 7,
yMax: 10,
backgroundColor: 'rgba(31,42,97,0.6)',
borderColor: 'rgba(88,88,88,0.6)',
borderWidth: 0
}
]
}
};
var myLineChart = Chart.Line(document.getElementById('chart'), {
data: data,
options: options
});
.wrap { background-color:#000; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.5/chartjs-plugin-annotation.js"></script>
<div class="wrap">
<canvas id="chart"></canvas>
</div>
You have to define a callback function to change the tooltip title as follows.
tooltips: {
mode: 'index',
callbacks: {
title: tooltipItem => 'Question: ' + questions[tooltipItem[0].index]
}
}
Please check the amended JSFiddle

Categories