Chart JS V3 Tooltip styling location changed? - javascript

I'm using Chart JS v.3.4 and I'm trying to style my charts tooltip with no luck so far. I added the options to options.tooltips but for some reason, they have no effect.
My full code is below. Is there maybe a configuration that blocks my options from working? Or did it changed at some point where the options go?
async function init_line_chart()
{
var ctx = document.getElementById('chart').getContext("2d");
var data = [100, 140, 150, 130, 160, 120, 130];
var suggestedMin = Math.max.apply(Math,data);
var suggestedMax = Math.min.apply(Math,data);
var gradientStroke = ctx.createLinearGradient(500, 0, 100, 0);
gradientStroke.addColorStop(0, '#4e62ff');
gradientStroke.addColorStop(1, '#4e62ff');
var gradientFill = ctx.createLinearGradient(0, 0, 0, 200);
gradientFill.addColorStop(0, 'rgba(78, 98,255, 0.25)');
gradientFill.addColorStop(0.2, 'rgba(78, 98, 255, 0.12)');
gradientFill.addColorStop(0.8, 'rgba(78, 98, 255, 0)');
gradientFill.addColorStop(1, 'rgba(78, 98, 255, 0)');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
label: "",
borderColor: gradientStroke,
pointBorderColor: 'rgba(0, 0, 0, 0)',
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointBorderWidth: 5,
pointRadius: 5,
fill: true,
backgroundColor: gradientFill,
borderWidth: 4,
lineTension: 0.3,
pointHitRadius: 1000,
data: data
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
animation: {
easing: "easeInOutQuint"
},
tooltips: {
backgroundColor: '#FFFFFF',
bodyFontColor: '#d4d4d4',
bodyFontSize: 14,
},
scales: {
x: {
grid:{
display:false,
drawBorder: false,
},
ticks: {
font: {
family: 'Comfortaa', // Your font family
size: 13.6,
},
color: "#d4d4d4"
},
},
y: {
grid:{
display:false,
drawBorder: false,
},
ticks: {
display: false, //this will remove only the label
},
}
},
plugins: {
legend: {
display: false
},
}
}
});
}
Is there maybe a configuration that blocks my options from working? Or did it changed at some point where the options go?

As stated in the Migration guide the namespace has been changed to options.plugins.tooltip.
If you want to know where to put options for configuration of specific things you can go to that part of the docs and look for the namespace part, that will tell you where to put the options

Related

chart.js remove lower grid from mixed chart

I have a mixed chart (scatter and line), hence I need 2 xAxis.
There's an extra grid that appears on the bottom of the chart, because that's where the other x axis normally has its labels (I removed them because I don't need them)
I'm trying to get rid of that extra grid, but I can't find how to do it. I've tried to specify the ticks color as white but the grid's still there.
Look at the image, it's that solitary extra grid at the bottom (marked with an horizontal bracket):
This is my code:
const ctx = document.getElementById('myChart');
const labels1 = ['A','R','Fyo','A-MAC','HR','Do','Rs','Dpr','GM','GF','EPK','EPS','Is1','Is2','Is3','FP','INVAR','INVER'];
const lasIs = (ctx, value) => ctx.p0DataIndex > 11 ? value: undefined;
const markedIdxs = [0,5,10,15,20,25,30,35,44, //... and many more];
const markedVals = [0,5,10,15,20,25,30,35,10,// ... and many more];
const data1 = {
labels: labels1,
datasets: [
{
type: 'line',
label: 'Line Dataset',
data: [65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65],
pointRadius: 0,
borderWidth: 1,
borderColor: '#0070C5',
xAxisID: 'x2'
},
{
type: 'line',
label: 'Line Dataset',
data: [50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50],
pointRadius: 0,
borderWidth: 1,
borderColor: '#0070C5',
xAxisID: 'x2'
},
{
type: 'line',
label: 'Line Dataset',
data: [102, 38, 54, 56, 102, 38, 54, 56, 102, 38, 54, 56, 102, 38, 54, 87, 62, 91],
pointStyle: 'circle',
pointRadius: 5,
borderWidth: 2,
borderColor: 'rgba(0, 120, 161,0.5)',
backgroundColor: 'rgba(0, 120, 161,0.5)',
fill: true,
segment: {
borderColor: ctx => lasIs (ctx, 'rgba(0, 168, 172, 0.5'),
backgroundColor: ctx => lasIs (ctx, 'rgba(0, 168, 172, 0.5'),
},
xAxisID: 'x2'
},
{
type: 'scatter',
pointStyle: 'dash',
pointRadius: 6,
borderColor: 'rgba(0, 0, 255,0.2)',
xAxisID: 'x',
data: [{x:1, y:36}, {x:1, y:37}, {x:1, y:39}, {x:1, y:40}, {x:1, y:42}... //and many more]
},
],
};
const multiplos5 = {
id: 'multiplos5',
afterDatasetsDraw(chart, args, options) {
const {ctx} = chart;
ctx.save();
ctx.font = "8px Verdana";
ctx.fillStyle = "#0070C5";
yaSeDibujo=84;
paddLeft = 0;
for (i=0; i < markedIdxs.length; i++) {
if (markedVals[i] < 10)
paddLeft=8;
else
paddLeft=12;
ctx.fillText(markedVals[i], chart.getDatasetMeta(3).data[markedIdxs[i]].x - paddLeft, chart.getDatasetMeta(3).data[markedIdxs[i]].y + 3);
}
}
};
Chart.register(multiplos5);
const myChart = new Chart(ctx, {
data: data1,
options: {
scales: {
x2: { // add extra axes
min: 0,
max: 18,
position: 'bottom',
type: 'category',
ticks: {color: '#0070C5'},
offset: true
},
x: {
min: 1,
max: 18,
ticks: {stepSize: 1, display: false},
offset: true
},
y: {
min: 20,
max: 120,
ticks: {stepSize: 10, color: '#555555', crossAlign: 'start'},
grid:{color:'#f1f1f1', display:true},
},
y2: {
position: 'right',
min: 20,
max: 120,
ticks: {stepSize: 10, color: '#555555'},
grid:{display:false}
},
},
plugins: {
multiplos5,
legend: false,
tooltip: {
displayColors: false,
filter: function (tooltipItem) {
return tooltipItem.datasetIndex == 2;
},
callbacks: {
//title: "el título",
label: function(context) {
let label = labels2[context.dataIndex] + ': ' + context.parsed.y;
return label;
}
}
}
},
},
});
Chart.js version is 3.6.2
Any help/workaround will be really appreciated.
Regards!!
Forgot to mention that the axis I'm talking about is 'x' (xAxisID: 'x')
In your config for the X axis where you set the ticks to display false, if you instead do this in the root of the X scale config it will hide that line so you will get:
scales:{
x: {
display: false,
min: 1,
max: 18,
offset: true
}
}

Chartjs bar min, max and avarage value

Hi I have a chart with chartjs, which inserts between min, max, average values, with a bar type chart.
So far, everything is fine, the values are entered, what I want to do is that the bars of the graph are positioned starting from their min on the y axis up to the maximum on the y axis, I do not want the bar to start from the value 0.
dataset = {
labels: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
datasets: [{
label: 'min',
borderWidth: 4,
borderColor: "#ef4931",
backgroundColor: "#ef4931",
borderJoinStyle: 'miter',
pointHitRadius: 10,
data: data[1],
fill: false,
},
{
label: 'avg',
borderWidth: 4,
borderColor: "#ef4931",
backgroundColor: "#ef4931",
borderJoinStyle: 'miter',
pointHitRadius: 10,
data: data[0],
fill: "-1",
},
{
label: 'max',
borderWidth: 4,
borderColor: "#ef4931",
backgroundColor: "#ef4931",
borderJoinStyle: 'miter',
pointHitRadius: 10,
data: data[2],
fill: "-1",
}
]
};
options = {
legend: {
display: false,
},
title: {
display: true,
position: 'bottom',
fontSize: 14
},
tooltips: {
mode: 'index',
intersect: false,
titleFontStyle: "bold",
titleFontColor: "rgba(255, 255, 255, 1)",
bodyFontStyle: "normal",
bodyFontColor: "rgba(255, 255, 255, 1)",
backgroundColor: "rgba(102, 102, 102, 1)",
borderWidth: 1,
bodySpacing: 5,
xPadding: 15,
yPadding: 15,
displayColors: false,
callbacks: {
title: function(item, data) {
var title = "";
title += item[0].xLabel;
return title;
}
}
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [{
stacked: true,
barThickness: 10,
}],
yAxes: [{
stacked: true,
display: true,
scaleLabel: {
display: true,
fontSize: 14,
fontStyle: "bold",
},
ticks: {
callback: function(value, index, values) {
return parseInt(value) + " bpm";
},
}
}]
},
animation: {
duration: 1000,
easing: "easeInOutQuad"
}
};
myChart.config.data = dataset;
myChart.options = options;
myChart.config.type = "bar";
myChart.update();
in your y axes config you can add the prop suggestedMin or min between the stacked and display prop. With this the scale will start at that number, here you can put in the value of the lowest bar.
SuggestedMin will go lower if there is a bar with a lower value, if you use min if will use that as a final so if you have a bar with a lower value it wont get shown.
You can combine "floating bars" and "stacked bar chart". See https://codepen.io/fantasyzer/pen/KKaqgoM for an example. Note that the data of each bar is given as an array [Ybegin,Yend]. If you set stackable to false for the y scale the values are to be given as absolute:
datasets: [
{
data: [
[10,12],
[20,25],
[15,25],
[25,28],
...
Ref:
https://www.chartjs.org/docs/latest/samples/bar/floating.html, https://www.chartjs.org/docs/latest/samples/bar/stacked.html

ChartJs. How to stretch up line graph to the edges?

I use ChartJs library for building graphs. For now my graphs have "side gaps". I want stretch line graphics to the full width and height like this:
I tried to change canvas width and it works if canvas has not a full width, but I need to make it works also on full width:
My configurations:
data: {
datasets: [
{
data: bids,
fill: true,
pointHitRadius: 10,
pointBorderWidth: 0,
pointHoverRadius: 4,
pointHoverBorderColor: 'white',
pointHoverBorderWidth: 2,
pointRadius: 0,
backgroundColor: 'rgba(58, 196, 174, 0.4)',
borderColor: '#3ac4ae',
lineTension: 0.7,
borderJoinStyle: 'miter',
},
{
data: asks,
pointRadius: 0,
fill: true,
pointHitRadius: 10,
pointBorderWidth: 0,
pointHoverRadius: 4,
pointHoverBorderColor: 'white',
pointHoverBorderWidth: 2,
backgroundColor: 'rgba(255, 107, 66, 0.4)',
borderColor: '#ff6b42',
lineTension: 0.7,
cubicInterpolationMode: 'default',
borderJoinStyle: 'miter',
}
]
},
options: {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [
{
display: true,
type: 'linear',
gridLines: {
borderDashOffset: 0,
display: true,
color: 'rgba(255, 255, 255, .1)'
},
ticks: {
autoSkip: false,
callback: (value, index, values) => {
console.log('valueskol', values)
return value
},
beginAtZero: true,
padding: 20,
},
}
],
yAxes: [
{
display: true,
type: 'linear',
position: 'left',
gridLines: {
display: true,
color: 'rgba(255, 255, 255, .1)',
drawBorder: false,
offsetGridLines: true,
tickMarkLength: 0,
drawOnChartArea: true
},
ticks: {
min: 0.02,
padding: 20,
stepSize: 0.1,
}
}
Would be very grateful, if someone can help me.
Set xAxes.ticks.min to the minimum X value and .max to the maximum value, and set yAxes.ticks.padding to 0.
Here's an example. I had to make up some numbers because the data is missing from your post:
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
data: [{
x: 1,
y: 12
}, {
x: 2,
y: 11
}, {
x: 3,
y: 10
}, {
x: 4,
y: 1
}, ],
fill: true,
pointHitRadius: 10,
pointBorderWidth: 0,
pointHoverRadius: 4,
pointHoverBorderColor: 'white',
pointHoverBorderWidth: 2,
pointRadius: 0,
backgroundColor: 'rgba(58, 196, 174, 0.4)',
borderColor: '#3ac4ae',
lineTension: 0.7,
borderJoinStyle: 'miter',
},
{
data: [{
x: 6,
y: 1
}, {
x: 7,
y: 3
}, {
x: 8,
y: 5
}, {
x: 9,
y: 11
}, ],
pointRadius: 0,
fill: true,
pointHitRadius: 10,
pointBorderWidth: 0,
pointHoverRadius: 4,
pointHoverBorderColor: 'white',
pointHoverBorderWidth: 2,
backgroundColor: 'rgba(255, 107, 66, 0.4)',
borderColor: '#ff6b42',
lineTension: 0.7,
cubicInterpolationMode: 'default',
borderJoinStyle: 'miter',
}
]
},
options: {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
display: true,
type: 'linear',
gridLines: {
borderDashOffset: 0,
display: true,
color: 'rgba(255, 255, 255, .1)'
},
ticks: {
autoSkip: false,
callback: (value, index, values) => {
console.log('valueskol', values)
return value
},
beginAtZero: true,
padding: 20,
min: 1,
},
}],
yAxes: [{
display: true,
type: 'linear',
position: 'left',
gridLines: {
display: true,
color: 'rgba(255, 255, 255, .1)',
drawBorder: false,
offsetGridLines: true,
tickMarkLength: 0,
drawOnChartArea: true
},
ticks: {
padding: 0,
}
}]
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>

remove data display in middle of the bar's and every graph from graphs in chart js

I'm using Chart.js v2.9.3 in sails js
my question is how should I remove the values display in the middle of the bars
config for chat is below
var ChartConfig = {
type: "line",
data: {
labels: [],
datasets: [{
label: "Earnings",
lineTension: 0.3,
backgroundColor: "rgba(0, 97, 242, 0.05)",
borderColor: "rgba(0, 97, 242, 1)",
pointRadius: 3,
pointBackgroundColor: "rgba(0, 97, 242, 1)",
pointBorderColor: "rgba(0, 97, 242, 1)",
pointHoverRadius: 3,
pointHoverBackgroundColor: "rgba(0, 97, 242, 1)",
pointHoverBorderColor: "rgba(0, 97, 242, 1)",
pointHitRadius: 10,
pointBorderWidth: 2,
data: []
}]
},
options: {
maintainAspectRatio: false,
barValueSpacing: 20,
layout: {
padding: {
left: 10,
right: 25,
top: 25,
bottom: 0
}
},
scales: {
xAxes: [{
barThickness: barThickness,
gridLines: {
display: false,
drawBorder: false
},
ticks: {
padding: 10,
// maxTicksLimit: 10
},
stacked: true,
}],
yAxes: [{
ticks: {
maxTicksLimit: 10,
padding: 10,
},
gridLines: {
color: "rgb(234, 236, 244)",
zeroLineColor: "rgb(234, 236, 244)",
drawBorder: false,
borderDash: [2],
zeroLineBorderDash: [2]
},
stacked: true,
}]
},
legend: {
display: true,
labels: {
filter: function (item, chart) {
// Logic to remove a particular legend item goes here
return !item.text.includes('Emp_Id') && !item.text.includes('Rel_Id')
}
}
},
tooltips: {
backgroundColor: "rgb(255,255,255)",
bodyFontColor: "#858796",
titleMarginBottom: 10,
titleFontColor: "#6e707e",
titleFontSize: 14,
borderColor: "#dddfeb",
borderWidth: 1,
xPadding: 15,
yPadding: 15,
displayColors: false,
intersect: false,
mode: "index",
caretPadding: 10,
},
plugins: {
colorschemes: {
scheme: ThemeVariable
},
},
}
}
also dous not add anything other then this in any place.
the value with a simple bar graph is ok but with stacked bars and pie and doughnut its looks dirty.
I've attached the screenshot of the graph.graph's spanshot
can anyone help me with this
thank you

ChartJS Tooltip Customization

I'm running ChartJS 2.7.something, and have https://codepen.io/anon/pen/YBJWKX this graph. Code below:
var ctx = document.getElementById("chart");
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
draw: function(ease) { Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
let activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.scales['y-axis-a'].top,
bottomY = this.chart.scales['y-axis-a'].bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(52,58,64,1)';
ctx.stroke();
ctx.restore();
}
}
});
var dashboard = new Chart(ctx, {
type: 'bar',
data: {
responsive: true,
labels: ["1", "2", "3", "4", "5", "6", "7"],
datasets: [{
label: 'No Data',
yAxisID: 'y-axis-a',
data: [null,null,4000, null, null, 4000, null],
backgroundColor: 'rgba(229,229,229,1)',
borderWidth: '0',
borderSkipped: 'bottom',
hoverBackgroundColor: 'rgba(229,229,229,1)',
hoverBorderWidth: '0',
showTooltip: false,
},
{
type: 'LineWithLine',
label: 'Dummy 1',
fill: false,
yAxisID: 'y-axis-a',
data: [2586, 2343, 2380, 2439, 3316, 1570, 3439],
borderColor: 'rgba(220,53,69,1)',
backgroundColor: 'rgba(220,53,69,1)',
borderWidth: 3,
borderCapStyle: 'butt',
pointRadius: 2,
pointBorderWidth: 0,
pointHoverRadius: 1,
pointHitRadius: 10,
lineTension: 0.1, // Removes Bezier on Line
},
{
type: 'LineWithLine',
label: 'Dummy 2',
fill: false,
yAxisID: 'y-axis-a',
data: [3466, 1295, 3015, 2351, 3305, 1167, 1350],
borderColor: 'rgba(40, 167, 69,1)',
backgroundColor: 'rgba(40, 167, 69,1)',
borderWidth: 3,
borderCapStyle: 'butt',
pointRadius: 2,
pointBorderWidth: 0,
pointHoverRadius: 1,
pointHitRadius: 10,
lineTension: 0.1, // Removes Bezier on Line
},
{
type: 'LineWithLine',
label: 'Dummy 3',
fill: false,
yAxisID: 'y-axis-b',
data: [1, 8, 17, 6, 12, 4, 7],
borderColor: 'rgba(0, 123, 255,1)',
backgroundColor: 'rgba(0, 123, 255,1)',
borderWidth: 3,
borderCapStyle: 'butt',
pointRadius: 2,
pointBorderWidth: 0,
pointHoverRadius: 1,
pointHitRadius: 10,
lineTension: 0.1, // Removes Bezier on Line
},
]
},
options: {
bezierCurve: false,
maintainAspectRatio:false,
legend: {
labels: {
filter: function(item, dashboard) {
// Logic to remove a particular legend item goes here
return !item.text.includes('No Data');
}
}
},
tooltips: {
mode: 'index',
intersect: false,
//enabled: false,
},
scales: {
yAxes: [{
position: "left",
id: "y-axis-a",
ticks: {
suggestedMax: 3600,
}
},
{
position: "left",
id: "y-axis-b",
max: 25,
display: false,
gridLines: {
display:false
}
}],
},
xAxes: [{ }]
}
});
It's almost perfect for what i need it for, however:
In this particular case I would like to remove the "No Data" grey bars from the tooltip where it's values are NULL.
At the same time, i would also like to remove the tooltip entirely where it's value is not NULL, ie disabled.
I'm using the tooltip in index mode with intersect turned to false so that the black line that is on the graph works, the black line came from this question.
I've tried a range of things from stackoverflow, but I have a feeling that none of the things i've tried have worked because of how the tooltip is set up.
Is it at all possible to do what I need here?
Just change your options parameter a little bit.
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
//returns a empty string if the label is "No Data"
label: function(items, data){
let dataset = data.datasets[items.datasetIndex];
if(dataset.label !== "No Data") {
return `${dataset.label}: ${items.yLabel}`
} else {
return ""
}
},
//only returns something when at least one dataset yLabel is a valid number.
title: function(t, e) {
let shouldDisplay = false;
t.forEach((it) => {
if(!isNaN(it.yLabel)) shouldDisplay = true;
});
if(shouldDisplay) {
return t[0].xLabel;
}
}
}
},
There is probably a better way to optimize this, but I hope it helps

Categories