I have implemented the react-chartjs2 https://www.npmjs.com/package/react-chartjs-2
in my react app. I have implemented it successfully but i need to change the direction of the tooltip when hovering the chart. Currently it looks like this
But i want my tooltip to look like this
How can i achieve this
My code for chart and chart options
const barChartOptions = {
tooltips: {
custom: function(tooltip) {
if (!tooltip) return;
// disable displaying the color box;
tooltip.displayColors = false;
},
callbacks: {
// use label callback to return the desired label
label: function(tooltipItem, data) {
return tooltipItem.yLabel + " kWh";
},
// remove title
title: function(tooltipItem, data) {
return;
}
}
},
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [
{
barPercentage: 1,
barThickness: 10,
gridLines: {
display: false,
color: "rgba(0, 0, 0, 0.1)"
}
}
],
yAxes: [
{
gridLines: {
display: true,
categorySpacing: 90,
drawBorder: false,
color: "rgba(0, 0, 0, 0.1)"
},
ticks: {
beginAtZero: true,
min: 0,
max: 100,
stepSize: 20,
padding: 20
}
}
]
}
};
inside render
<Bar
data={data}
width={100}
height={400}
options={barChartOptions}
/>
options: {
tooltips: {
yAlign: "bottom"
}
}
The problem is I don't know a way that the caret is in the middle of your box.
I think you need to add more configuration for your tooltip
Check what you can use for position and alignment of your Tooltip
Related
I would like to use mirror option in order to show y-axis value "inside" the graph:
now the problem is the x-axis should start after those values but I can't move them.
The chart is build with following code:
this.chart = new Chart(this.canvas.nativeElement, {
type: 'bar',
data: data,
options: {
scales: {
x: {
stacked: true,
grid: {
display: false,
drawBorder: false
},
ticks: {
color: '#333',
font: {
weight: 'bold'
},
maxRotation: 0,
maxTicksLimit: this.loadLabels()?.length / 2
},
bounds: 'ticks'
},
y: {
type: 'linear',
beginAtZero: true,
stacked: true,
title: {
display: false,
},
display: true,
grid: {
display: true,
drawBorder: false,
lineWidth: 1,
borderColor: 'rgb(244, 244, 244, 0.7)',
color: 'rgb(244, 244, 244, 0.7)'
},
ticks: {
display: true,
maxTicksLimit: 5,
mirror: true,
callback: (val) => formatCurrency(+val, 'it', getCurrencySymbol(this.currency, 'narrow'), this.currency)
}
}
}
},
});
I tried both padding and grace options without success.. Anyone knows how to do it?
You can define y.ticks.padding as follows:
y: {
ticks: {
...
padding: -50
}
}
Together with this, you also need to define layout.padding.left to make sure, the tick labels still appear on the canvas.
options: {
layout: {
padding: {
left: 100
}
}
...
Obviously you need to adapt the numbers to your needs.
For further information, please consult Tick Configuration and Padding from the Chart.js documentation.
I would like to exclude the dates on the x-axis that has no values. Below is the image of my chart.
What my chart currently looks like
Here is also my current code for the options in chart js
var options = {
responsive: true,
maintainAspectRatio: false,
elements: {
line: {
fill: false
}
},
style: {
strokewidth: 10
},
title: {
display: true,
position: 'top',
fontSize: 18,
padding: 20
},
scales: {
xAxes:[{
ticks: {
z: 0,
autoskip: false,
callback: function(value, index, values){
return new moment(value).format('L');
}
},
type: 'time',
time: {
unit: 'week'
},
scaleLabel: { display: true,
labelString: 'Date'}
}],
yAxes: [{
ticks: { beginAtZero:true ,
min: 0,
max: 5 } ,
scaleLabel: { display: true,
labelString: 'Skill Rating'}
}]
}
};
I hope you guys can help me. Thanks!
When you pass your series/data to your chart, filter it
let data = [...];
data = data.filter(v => v[0] && v[1]);
I'm trying to create a linear gradient under plugins for my chartJs chart.Unfortunately I get an error called :
Failed to execute 'createLinearGradient' on 'CanvasRenderingContext2D': The provided double value is non-finite.
I'm trying to add my linearGradient inside plugins because I want that gradient to be aligned on each scale.
Here what I tried below
barChart = new Chart(elem, {
plugins: [
{
id: "responsiveGradient",
afterLayout: function(chart, options) {
var scales = chart.scales;
var color = chart.ctx.createLinearGradient(
scales["x-axis-0"].left,
scales["y-axis-0"].bottom,
scales["x-axis-0"].right,
scales["y-axis-0"].top
);
// add gradients stops
color.addColorStop(0, "black");
color.addColorStop(0.25, "red");
color.addColorStop(0.5, "orange");
color.addColorStop(0.75, "yellow");
color.addColorStop(1, "green");
// changes the background color option
chart.data.datasets[0].backgroundColor = color;
}
}
],
type: 'horizontalBar',
data: datasets,
options: {
maintainAspectRatio: false,
tooltips: { enabled: false },
title: {
display: false,
},
responsive: true,
legend: {
display: false,
position: "top"
},
scales: {
xAxes: [{
ticks: {
beginAtZero: false,
min:0.5,
max:0.8,
maxTicksLimit: 6,
},
scaleLabel: {
display: false
},
barThickness: 5,
gridLines: {
display: false,
zeroLineColor: "transparent",
}
}],
yAxes: [{
barThickness: 5,
ticks: {
maxTicksLimit: 6,
padding: 15,
},
gridLines: {
drawTicks: false,
display: false
}
}]
}
},
});
The problem is in the last line of your plugins.afterLayout function. There is no object such as chart.data, use chart.config.data instead.
// chart.data.datasets[0].backgroundColor = color; // replace this line
chart.config.data.datasets[0].backgroundColor = color;
Please have a look at your amended code below (I had to make an assumptions about your data).
const datasets = {
labels: ['A', 'B', 'C'],
datasets: [{
label: 'data',
data: [0.6, 0.7, 0.8],
barThickness: 5
}]
};
new Chart("myChart", {
plugins: [{
id: "responsiveGradient",
afterLayout: (chart, options) => {
var scales = chart.scales;
var color = chart.chart.ctx.createLinearGradient(
scales["x-axis-0"].left,
scales["y-axis-0"].bottom,
scales["x-axis-0"].right,
scales["y-axis-0"].top
);
// add gradients stops
color.addColorStop(0, "black");
color.addColorStop(0.25, "red");
color.addColorStop(0.5, "orange");
color.addColorStop(0.75, "yellow");
color.addColorStop(1, "green");
// changes the background color option
chart.config.data.datasets[0].backgroundColor = color;
}
}],
type: 'horizontalBar',
data: datasets,
options: {
maintainAspectRatio: false,
tooltips: {
enabled: false
},
title: {
display: false,
},
responsive: true,
legend: {
display: false,
position: "top"
},
scales: {
xAxes: [{
ticks: {
beginAtZero: false,
min: 0.5,
max: 0.8,
maxTicksLimit: 6,
},
scaleLabel: {
display: false
},
gridLines: {
display: false,
zeroLineColor: "transparent",
}
}],
yAxes: [{
ticks: {
maxTicksLimit: 6,
padding: 15,
},
gridLines: {
drawTicks: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>
I have a chart using chart.js, it's a simple line, and if I hover over the line everything is correct, a circle shows on the point and the tool tip appears.
Now I also wanted that when the user hovers on the X-axis, it would select the circle and show the tooltip for the value at that X-axis point.
So I added this:
tooltips: {
intersect: false,
mode: "index"
}
and it works correctly, now if I hover on the X-axis I'll get the tooltip on my line, but one thing that doesn't work is, I dont get the "circle" on my line, only the tooltip!
I get the circle only if I hover directly on the line, here 2 images so you can see the difference:
in the above image I'm hovering directly on the line, and it shows the Circle and the tooltip
in this image instead I'm hovering on the X-axis and as you can see, it will display only the tooltip on my line, but not the circle!
How can I display the circle even when not hovering directly?
thank you
EDIT: added more code:
ngOnInit(): void {
this.ctx = this.myChartRef.nativeElement.getContext("2d");
this.canvas = new Chart(this.ctx, {
type: "scatter",
data: {
labels: [],
datasets: [
{
label: "Grade",
data: [],
borderColor: "#3cba9f",
fill: false,
pointHitRadius: 10,
showLine: true
}
]
},
options: {
responsive: true,
maintainAspectRatio: true,
elements: {
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 8
}
},
tooltips: {
displayColors: false,
intersect: false,
enabled: true,
mode: "index",
callbacks: {
afterBody: function([tooltipItem], data): any {
const multistringText = ["Points: " + tooltipItem.xLabel];
multistringText.push("Grade: " + tooltipItem.yLabel);
return multistringText;
},
label: function(tooltipItem, data): any {
return;
}
}
},
layout: {
padding: {
top: 12
}
},
legend: {
display: false
},
scales: {
gridLines: {
drawBorder: false
},
xAxes: [
{
ticks: {
beginAtZero: false,
maxTicksLimit: 8,
stepSize: 5,
callback: function(value, index, values): any {
if (Math.floor(value) === value) {
return value;
}
if (value % 5 === 0) {
return value;
}
}
},
scaleLabel: {
display: false
}
}
],
yAxes: [
{
ticks: {
beginAtZero: false,
min: 1,
max: 6
},
scaleLabel: {
display: false
}
}
]
}
}
});
}
As you can see below with the canvas element highlighted, there is considerable whitespace below the x axis label. If I resize the canvas, the whitespace stays proportional to the height of it. Are there any settings that control this whitespace? I've ruled out padding and do not see any settings for margins.
Thanks!
Here is the JavaScript that renders the chart:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
options: {
legend: {
display: false
},
elements: {
point: {
radius: 0
}
},
scales: {
xAxes: [{
gridLines: {
display: false,
drawBorder: true
},
ticks: {
autoSkip: true,
maxTicksLimit: 1
}
}],
yAxes: [{
gridLines: {
display: true,
drawBorder: false
},
ticks: {
callback: function(value, index, values) {
return '$' + addCommas(value);
}
}
}]
},
layout: {
padding: 5
}
},
type: 'line',
data: {
labels: labels,
datasets: [
{
data: values,
fill: false,
borderColor: "blue"
}
]
}
});
And the complete jsfiddle: https://jsfiddle.net/rsn288fh/2/
I know you said you ruled out padding, but this is the only option I can see working:
options: {
layout: {
padding: {
bottom: -20
}
}
}
Obviously you can play with the -20 to what works for you.
Here is the reference for padding for chartjs, if you wanted to see more
EDIT:
I've updated your jsfiddle, with a colored div below the chart. As you resize it seems to stay at the same spot below the chart.
Changing the tickMarkLength to 0 results in no padding on the left or bottom of the chart (or wherever your axis happens to be).
https://www.chartjs.org/docs/latest/axes/styling.html#grid-line-configuration
tickMarkLength
Length in pixels that the grid lines will draw into the axis area.
const options = {
scales: {
xAxes: [
{
ticks: {
display: false,
},
gridLines: {
display: false,
tickMarkLength: 0,
},
},
],
yAxes: [
{
ticks: {
display: false,
},
gridLines: {
display: false,
tickMarkLength: 0,
},
},
],
},
};