chartjs show dot point on hover over line chart - javascript

I am using Chartjs v.1.0.2 and trying to set a point dot only to appear on hover over chart. After it it should be removed. I have managed to show it, by changing the object value, but it is not fluid motion and it doesn't show point always. This also doesn't hide it on hover out.
How can it be fluid and hide when mouse is not over?
window.onload = function(){
var ctx = $("#chart1").get(0).getContext("2d");
var chart1 = new Chart(ctx).Line(data1, options);
$("#chart1").hover(function(e) {
var activeBars = chart1.getPointsAtEvent(e);
activeBars[0].display = true;
// console.log(activeBars[0]);
chart1.update();
});
};
var data1 = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(95,186,88,0.7)",
strokeColor: "rgba(95,186,88,1)",
pointColor: "rgba(95,186,88,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
}
]
};
var options = {
responsive: true,
bezierCurve : false,
scaleShowLabels: false,
scaleFontSize: 0,
pointDot : false,
scaleBeginAtZero: true,
scaleShowHorizontalLines: false,
scaleShowVerticalLines: true,
scaleGridLineColor : "rgba(232,232,232)",
showTooltips: true,
customTooltips: function (tooltip) {
var tooltipEl = $('#chartjs-tooltip');
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// split out the label and value and make your own tooltip here
var parts = tooltip.text.split(":");
var innerHtml = '<span>' + parts[0].trim() + '</span> : <span><b>' + parts[1].trim() + '</b></span>';
tooltipEl.html(innerHtml);
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + tooltip.y + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
}
};
simplified fiddle

Tested with Chart.js v2.6.0
Global setting will do the trick:
Chart.defaults.global.hover.intersect = false;
Or directly in chart config:
options: {
hover: {
intersect: false;
}
}
And point settings for dataset.
initial color of the point should be transparent
hover color must be set to the desired color
e.g.
datasets: [{
label: 'My First dataset',
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgb(255, 99, 132)',
data: [10, 30, 46, 2, 8, 50, 0],
fill: false,
pointBorderColor: 'rgba(0, 0, 0, 0)',
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBackgroundColor: 'rgb(255, 99, 132)',
pointHoverBorderColor: 'rgb(255, 99, 132)'}],...
window.onload = function() {
const mode = 'index';
const intersect = false;
const config = {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'My First dataset',
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgb(255, 99, 132)',
data: [10, 30, 46, 2, 8, 50, 0],
fill: false,
pointBorderColor: 'rgba(0, 0, 0, 0)',
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBackgroundColor: 'rgb(255, 99, 132)',
pointHoverBorderColor: 'rgb(255, 99, 132)',
}, {
label: 'My Second dataset',
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgb(54, 162, 235)',
data: [7, 49, 46, 13, 25, 30, 22],
fill: false,
pointBorderColor: 'rgba(0, 0, 0, 0)',
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBackgroundColor: 'rgb(54, 162, 235)',
pointHoverBorderColor: 'rgb(54, 162, 235)',
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Mode: index, intersect = false'
},
tooltips: {
mode: 'index',
intersect: intersect,
},
hover: {
mode: mode,
intersect: intersect
},
}
};
const ctx = document.getElementById('canvas').getContext('2d');
const chart = new Chart(ctx, config);
}
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>

Edit: The following solution is for Chart.js v1.0.2 (the latest version at the time this solution was proposed). Please refer to this answer which provides a solution for Chart.js v2.x.x.
I ran into a similar situation a while back and resolved this by making the default point dot "invisible" as follows:
setting pointDotRadius to 1
setting pointStrokeColor to white with the alpha set to 0
The two steps above make the default point dot very small, this, in combination with the transparent point stroke, makes the default point dot invisible. Now if we make the pointDotStrokeWidth large enough, we can achieve the desired hover effect. i.e.
set pointDotStrokeWidth to a larger value (I used 8)
set the desired values for pointColor, pointHighlightFill, pointHighlightStroke
[Note: the same effect can be achieved by making pointColor
transparent but if you are plotting multiple datasets, then the
tooltip wouldn't show the corresponding line color next to the data
value.]
Example below (or you can checkout this Fiddle: ChartJS - Show Points on Hover):
var data = {
labels: ["Point0", "Point1", "Point2", "Point3", "Point4"],
datasets: [
{
label: "My Chart",
fillColor: "rgba(87, 167, 134, 0.2)",
strokeColor: "rgba(87, 167, 134, 1)",
pointColor: "rgba(87, 167, 134, 1)",
pointStrokeColor: "rgba(255, 255, 255, 0)",
pointHighlightFill: "rgba(87, 167, 134, 0.7)",
pointHighlightStroke: "rgba(87, 167, 134, 1)",
data: [5, 39, 109, 19, 149]
}
]
};
var ctx = document.getElementById("my_chart").getContext("2d");
myChart = new Chart(ctx).Line(data, {
responsive : true,
bezierCurve: false,
datasetFill: true,
pointDotRadius: 1,
pointDotStrokeWidth: 8,
pointHitDetectionRadius: 20,
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<canvas id="my_chart"></canvas>

$("#chart1").mouseover(function(e) {
chart1.datasets[0].points[0].display = true;
chart1.update();
});
$("#chart1").mouseout(function(e) {
chart1.datasets[0].points[0].display = false;
chart1.update();
});

Try using mouseover and mouseout as shown below. Similarly you can also use mouseenter and mouseleave methods to handle events.
$("#chart1").mouseover(function(e) {
var activeBars = chart1.getPointsAtEvent(e);
activeBars[0].display = true;
chart1.update();
});
$("#chart1").mouseout(function(e) {
var activeBars = chart1.getPointsAtEvent(e);
activeBars[0].display = false;
chart1.update();
});

This is a six years old question but I think in 2022 we can use ChartJS version 4.0.1.
ChartJS supports interactions behavior, and they can be configured via interaction, hover or tooltips settings on the chart configuration.
For this we will use the hover setting and select the index mode. This mode finds an item at the same index. If the intersect setting is false the nearest item, in the x direction, is used to determine the index.
Here is a working snippet
const data = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
}
const options = {
maintainAspectRatio: false,
elements: {
point: {
hoverRadius: 6,
},
},
hover: {
mode: 'index',
intersect: false,
},
}
const config = {
type: 'line',
data,
options,
}
const $chart = document.getElementById('chart')
const chart = new Chart($chart, config)
<div class="wrapper" style="width: 98vw; height: 180px">
<canvas id="chart"></canvas>
</div>
<script src="https://unpkg.com/chart.js#4.0.1/dist/chart.umd.js"></script>

Related

Horizontal bar with two yaxes chart js

I want to do an horizontal bar with 2 yaxes, Where a bar can have a positive or negative value and positive side has a yaxis and the negative side has other yaxis like the image
This is my code JSFiddle.
I can't change the names of the second yaxes
I add arrays with the same values because i would want two yaxes, It is not necessary to use "chart.js" if you knows other library where i can it use, please tell me
var canvas = document.getElementById('myChart');
var extremo1=[-5, 3, 9, -11];
var extremo2=[-5, 3, 9, -11];
var data = {
labels: ["Visua_Verbal", "Secuencial_Global", "Sensitivo_Intuitivo", "Reflexivo_Activo"],
datasets: [
{
backgroundColor: 'rgba(63, 191, 191, 0.75)',
borderColor: 'rgba(63, 191, 191, 0.75)',
hoverBackgroundColor: 'rgba(191, 63, 63, 1)',
hoverBorderColor: 'rgba(191, 63, 63, 1)',
data: extremo1
},
{
backgroundColor: 'rgba(63, 191, 191, 0.75)',
borderColor: 'rgba(63, 191, 191, 0.75)',
hoverBackgroundColor: 'rgba(191, 63, 63, 1)',
hoverBorderColor: 'rgba(191, 63, 63, 1)',
data: extremo1
}
]
};
var option = {
maintainAspectRatio: false,
responsive: true,
scales: {
xAxes: [{
display: true,
ticks: {
maxTicksLimit: 12
}
}],
yAxes: [{
position: "left",
display: true,
ticks: {
callback:(label,index,labels)=>{
label = label.match(/_(\w*)/)[1];
return label;
}}
},
{
position: "right",
display: true,
ticks: {
callback:(label,index,labels)=>{
return label ;
}
}
}]
},
legend: {
display: false
}
};
var myLineChart = new Chart(canvas,{
type: 'horizontalBar',
data:data,
options:option
});
In the snippet below I've set the options labels, type, offset on the y-axes to achieve the result you want. I've also removed unnecessary properties.
var canvas = document.getElementById('myChart');
var extremo = [-5, 3, 9, -11];
var data = {
datasets: [{
backgroundColor: 'rgba(63, 191, 191, 0.75)',
borderColor: 'rgba(63, 191, 191, 0.75)',
hoverBackgroundColor: 'rgba(191, 63, 63, 1)',
hoverBorderColor: 'rgba(191, 63, 63, 1)',
data: extremo
}]
};
var option = {
maintainAspectRatio: false,
responsive: true,
scales: {
xAxes: [{
ticks: {
maxTicksLimit: 12
}
}],
yAxes: [{
labels: ['Verbal', 'Global', 'Reflexivo', 'Sensitivo']
},
{
position: 'right',
labels: ['Visual', 'Secuencial', 'Activo', 'Intuitivo'],
gridLines: {
display: false
},
type: 'category',
offset: true
}
]
},
legend: {
display: false
}
};
var myLineChart = new Chart(canvas, {
type: 'horizontalBar',
data: data,
options: option
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="myChart">

How to Reset a Chart of Chart.Js?

I have a problem when I try to reload the graphic on the canvas with ChartJs again. At the time of making a new search, I left the previous graphic data when moving the mouse over the graphic. I would like to know how to restart the graph.
Function
function cargar_datos(datasL,dataP,dataR){
var ctx = $("#myChart")
var chart = new Chart(ctx, {
type: 'line',
data:
{
labels: datasL,
datasets:
[{
label: "Rendimiento",
borderColor: 'rgb(255, 99, 132)',
backgroundColor: ['rgba(255,200,200,0)'],
borderWidth: 2,
pointBackgroundColor: "red",
pointBorderColor: "rgba(250,10,10,0.1)",
pointBorderWidth: "10",
pointStyle: "rectRounded",
data:dataP,
},
{
label: "Aplicado",
borderColor: 'rgb(0, 143, 255)',
backgroundColor: ['rgba(112, 171, 219, 0.2)'],
borderWidth: 2,
pointBackgroundColor: "blue",
pointBorderColor: "rgba(144, 140, 174, 0.3)",
pointBorderWidth: "10",
pointStyle: "rectRounded",
data: dataR
}]
},
options: {
tooltips: {
position: 'average',
mode: 'index',
intersect: false,
},
}
});
chart.destroy();
}
Js
$(document).on('click','#Mostrarb',function(){
cargar_datos(labels,rend,porc);
});
the html
<div class="box-body">
<canvas id="myChart" width="200" height="35"></canvas>
</div>
That is because you are creating a new instance of chart.js every time you call the function, create a outiside var chart:
var chart;
function cargar_datos(datasL,dataP,dataR){
var ctx = $("#myChart")
chart = new Chart(ctx, {
type: 'line',
data:
{
labels: datasL,
datasets:
[{
label: "Rendimiento",
borderColor: 'rgb(255, 99, 132)',
backgroundColor: ['rgba(255,200,200,0)'],
borderWidth: 2,
pointBackgroundColor: "red",
pointBorderColor: "rgba(250,10,10,0.1)",
pointBorderWidth: "10",
pointStyle: "rectRounded",
data:dataP,
},
{
label: "Aplicado",
borderColor: 'rgb(0, 143, 255)',
backgroundColor: ['rgba(112, 171, 219, 0.2)'],
borderWidth: 2,
pointBackgroundColor: "blue",
pointBorderColor: "rgba(144, 140, 174, 0.3)",
pointBorderWidth: "10",
pointStyle: "rectRounded",
data: dataR
}]
},
options: {
tooltips: {
position: 'average',
mode: 'index',
intersect: false,
},
}
});
chart.destroy();
}
This works fine only when chart.destroy() is used before new Chart(), not after after it.

Chartjs Line Color Between Two Points

Is there any way to set line color of specific sections in between two points in chart.js?
I would like to color the section 00-07 gray, 07-15 red, and 15-23 blue.
Here is what I am passing as the data attribute in the options object to initialize the chart:
var chartData = {
labels: [/* a single dimensional array of strings */],
datasets: [
{
label: '',
data: [/* a single dimensional array of totals */],
fill: false,
backgroundColor: '#e7eaeb',
borderColor: red
}
]
};
I think this is where I need to add the graph section points and colors, but I do not know how.
HI Michael Hurley I think you should use:
interpolation:
https://www.chartjs.org/docs/latest/samples/line/interpolation.html
or
Multi-axis: https://www.chartjs.org/docs/latest/samples/line/multi-axis.html
My idea is we have 3 datasets with multi-color,
End of dataset1 is first of dataset2.
Here my Example:
window.chartColors = { red: 'rgb(255, 99, 132)', orange: 'rgb(255, 159, 64)', yellow: 'rgb(255, 205, 86)', green: 'rgb(75, 192, 192)', blue: 'rgb(54, 162, 235)', purple: 'rgb(153, 102, 255)', grey: 'rgb(201, 203, 207)' };
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var config = {
type: 'line',
data: {
labels: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
datasets: [{
label: 'Cubic interpolation (monotone)',
data: [0, 20, 20, 60, 60, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN],
borderColor: window.chartColors.red,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
cubicInterpolationMode: 'monotone'
}, {
label: 'Cubic interpolation (default)',
data: [NaN, NaN, NaN, NaN, 60, 120, 140, 180, 120, NaN, NaN, NaN, NaN],
borderColor: window.chartColors.blue,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
}, {
label: 'Linear interpolation',
data: [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 120, 125, 105, 110, 170],
borderColor: window.chartColors.green,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
lineTension: 0
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Line Chart - Cubic interpolation mode'
},
tooltips: {
mode: 'index'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
ticks: {
suggestedMin: -10,
suggestedMax: 200,
}
}]
}
}
};
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
Latest versions of ChartJS allow you to customize line segments individually, which can be used to change the color and also the style (dashed etc) of a specific segment.
const config = {
type: 'line',
data: {
labels: Utils.months({count: 7}),
datasets: [{
label: 'My First Dataset',
data: [65, 59, NaN, 48, 56, 57, 40],
borderColor: 'rgb(75, 192, 192)',
segment: {
borderColor: ctx => skipped(ctx, 'rgb(0,0,0,0.2)') || down(ctx, 'rgb(192,75,75)'),
borderDash: ctx => skipped(ctx, [6, 6]),
}
}]
},
options: genericOptions
};
See https://www.chartjs.org/docs/master/samples/line/segments.html for more info.
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterLayout hook to create a linear gradient through CanvasRenderingContext2D.createLinearGradient().
In the following example, the linear gradient is created from the colors defined in data.dataset.colors.
new Chart('myChart', {
type: 'line',
plugins: [{
afterLayout: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var gradientStroke = ctx.createLinearGradient(xAxis.left, 0, xAxis.right, 0);
var dataset = chart.data.datasets[0];
dataset.colors.forEach((c, i) => {
var stop = 1 / (dataset.colors.length - 1) * i;
gradientStroke.addColorStop(stop, dataset.colors[i]);
});
dataset.backgroundColor = gradientStroke;
dataset.borderColor = gradientStroke;
dataset.pointBorderColor = gradientStroke;
dataset.pointBackgroundColor = gradientStroke;
dataset.pointHoverBorderColor = gradientStroke;
dataset.pointHoverBackgroundColor = gradientStroke;
}
}],
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
datasets: [{
label: 'My Dataset',
data: [101, 122, 103, 115, 95, 94, 100, 108, 112, 115, 119, 120, 109, 108, 105, 116, 117, 108, 109, 114],
fill: false,
colors: ['gray', 'gray', 'gray', 'gray','gray', 'gray', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue']
}]
},
options: {
scales: {
yAxes: [{
ticks: {
min: 0
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="70"></canvas>
In V3 you can make use of the segment option in the dataset to style specific line parts:
new Chart('myChart', {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
datasets: [{
label: 'My Dataset',
data: [101, 122, 103, 115, 95, 94, 100, 108, 112, 115, 119, 120, 109, 108, 105, 116, 117, 108, 109, 114],
segment: {
borderColor: (ctx) => {
const xVal = ctx.p1.parsed.x;
if (xVal <= 7) {
return 'gray';
} else if (xVal <= 15) {
return 'red'
} else {
return 'blue'
}
},
},
}]
},
options: {}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
<canvas id="myChart" height="70"></canvas>
I've been wanting to let everyone know a way for react chart.
import React from "react";
import { LineController } from 'chart.js';
import Chart from 'chart.js/auto';
class MultiLineController extends LineController {
draw() {
const ctx = this.chart.ctx;
const meta = this.getMeta();
const points = meta.data || [];
const colors = this.getDataset().colors || [];
const area = this.chart.chartArea;
colors.forEach((color, idx) => {
meta.dataset.options.borderColor = color;
meta.dataset.draw(ctx, area, idx, 2);
});
meta.dataset.draw(ctx, area, colors.length, points.length - colors.length);
}
}
MultiLineController.id = "multicolorLine";
MultiLineController.defaults = LineController.defaults;
Chart.register(MultiLineController);
export default function App() {
React.useEffect(() => {
const ctx = document.getElementById("line-chart").getContext("2d");
window.lineChart = new Chart(ctx, {
type: 'multicolorLine',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45],
colors: ['red', 'green', 'blue', 'yellow']
}]
},
options: {}
});
return () => window.lineChart.destroy();
}, []);
return (
<div style={{width: '100%', height: 300}}>
<canvas id="line-chart" />
</div>
);
}
Here is screenshot of this chart.
React Chart Component implemented by chart.js

How to position line data points to middle of bar in bar/line graph using ChartJS

I'm making a combination bar/line chart using Chart.js v2. I want the line data to match up exactly with the bar data when being displayed given that there are two sets of bar chart data. Here is what I have now:
But I really want each blue data point on the line graph to match up to the top-middle of each blue bar, and each green data point to match up to the top-middle of each green bar, instead of them being placed in the center of the "x value". I can't seem to figure out how to do this given the Chart.js documentation.
Here is my code:
var monthlyDownloadsData = {
labels: ["3 Months","2 Months","Last Month","This Month","Next Month"],
datasets: [{
label: "App Store",
data: [150, 175, 135, 120, 115],
backgroundColor: "rgba(102, 179, 255, 1)",
borderColor: "rgba(255, 255, 255, 1)"
}, {
label: "Google Play",
data: [130, 105, 115, 95, 75],
backgroundColor: "rgba(140, 255, 102, 1)",
borderColor: "rgba(255, 255, 255, 1)"
}, {
type: "line",
label: "App Store",
data: [150, 175, 135, 120, 115],
backgroundColor: "rgba(102, 179, 255, 0.5)"
}, {
type: "line",
label: "Google Play",
data: [130, 105, 115, 95, 75],
backgroundColor: "rgba(140, 255, 102, 0.5)"
}]
};
var monthlyDownloadsOptions = {
title: {
display: false
},
scales: {
xAxes: [{
gridlines: {
display: false
}
}]
},
responsive: true,
maintainAspectRatio: false
};
var monthlyDownloads = document.getElementById('monthlydownloads').getContext('2d');
new Chart(monthlyDownloads, {
type: 'bar',
data: monthlyDownloadsData,
options: monthlyDownloadsOptions
});
Any help would be greatly appreciated!

Move tooltip further from data point for Chart.js?

I started messing with Chart.js today, and I'm really impressed so far by how easy it is to understand, even for a javascript beginner like myself.
I'm wanting to add some spacing horizontally between the tooltip and the data point on the graph. By default, the caret point touches the data point. I can't figure it out. I know there's a position option, but I don't quite get how it's used. I also tried using the tooltips: { x } option but no luck either. Guessing I'm misunderstanding what that is for.
Below is what I have so far for one chart...
Thanks, appreciate it!
//Global Chart.js options
Chart.defaults.global.defaultFontFamily = 'Lato';
Chart.defaults.global.elements.responsive = true;
Chart.defaults.global.tooltips.xPadding = 10;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.global.tooltips.titleMarginBottom = 10;
Chart.defaults.global.tooltips.position = 'average';
//Individual chart config
var ctx = "myChart";
var myChart = new Chart(ctx, {
type: 'line',
options: {
title: {
display: true,
text: 'Precision-Recall Curve',
},
layout: {
padding: 32
},
tooltips: {
x: 20
},
},
data: {
labels: ['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'],
datasets: [{
label: 'Precision',
data: [2, 42, 55, 50, 42, 38, 32, 24, 20, 18, 18],
borderColor: '#1abc9c',
backgroundColor: 'RGBA(26, 188, 156, .4)',
pointBorderColor: "#4BC0C0",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}, {
label: 'Recall',
data: [2, 12, 24, 30, 39, 58, 70, 82, 86, 89, 93],
borderColor: '#34495e',
backgroundColor: 'RGBA(52, 73, 94, .3)',
pointBorderColor: "#34495e",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}]
}
});
<div class="container">
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
I have something close, tooltips can accept a position which is an alias for a function stored in Chart.Tooltip.positioners. This function returns the x and y position for the tooltip.
You can add a custom one to adjust the x at an offset.
The only issue is that by adjust the x the layout (left/right direction) of the tooltip can change meaning that even after working out if the tool tip is below half way or above half way bu adjusting the x it then switches its layout meaning on tooltip in the middle will look odd as it is offset in the wrong direction.
This could be fixed by knowing the width of the tooltip and taking this into account but looking through the data provided to the function this is not given.
Anyway leaving this as an answer it gets you most of the way there and you/someone might be able to figure out how to get rid of that annoying last part
//Global Chart.js options
Chart.defaults.global.defaultFontFamily = 'Lato';
Chart.defaults.global.elements.responsive = true;
Chart.defaults.global.tooltips.xPadding = 10;
Chart.defaults.global.tooltips.yPadding = 10;
Chart.defaults.global.tooltips.titleMarginBottom = 10;
Chart.defaults.global.tooltips.position = 'average';
//register custome positioner
Chart.Tooltip.positioners.custom = function(elements, position) {
if (!elements.length) {
return false;
}
var offset = 0;
//adjust the offset left or right depending on the event position
if (elements[0]._chart.width / 2 > position.x) {
offset = 20;
} else {
offset = -20;
}
return {
x: position.x + offset,
y: position.y
}
}
//Individual chart config
var ctx = "myChart";
var myChart = new Chart(ctx, {
type: 'line',
options: {
title: {
display: true,
text: 'Precision-Recall Curve',
},
layout: {
padding: 32
},
tooltips: {
//use our new custom position
position: 'custom'
},
},
data: {
labels: ['0%', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'],
datasets: [{
label: 'Precision',
data: [2, 42, 55, 50, 42, 38, 32, 24, 20, 18, 18],
borderColor: '#1abc9c',
backgroundColor: 'RGBA(26, 188, 156, .4)',
pointBorderColor: "#4BC0C0",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}, {
label: 'Recall',
data: [2, 12, 24, 30, 39, 58, 70, 82, 86, 89, 93],
borderColor: '#34495e',
backgroundColor: 'RGBA(52, 73, 94, .3)',
pointBorderColor: "#34495e",
pointBackgroundColor: "#fff",
pointHitRadius: 10
}]
}
});
<div class="container">
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script>
I think it's simpler by change the number of caretPadding. We can increase the distance from tooltip to data point by caretPadding
option: {
tooltip: {
caretPadding: 20,
}
}
caretPadding-image

Categories

Resources