将工具提示放置在栏的中心 [英] Position tooltip in center of bar
本文介绍了将工具提示放置在栏的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
找不到像这样将工具提示放置在栏中心的方法(是的,我知道它不完全在此屏幕截图的中心,但仍然):
如果我使用custom
工具提示选项,我只能获得插入符号在栏顶部的x
和y
位置。但无法获取条的高度/宽度。
下面是我传递给图表构造函数的Options对象的一部分:
const options = {
tooltips: {
enabled: false,
custom: (tooltip) => {
// Retrieving valuable props from tooltip (caretX, caretY)
// and creating custom tooltip that is positioned
// on top of a bar
}
}
// other options
}
const chart = new Chart(ctx, {
type: 'bar',
data,
options
})
推荐答案
您可能已经知道,要将自定义工具提示放置在栏的中心,您可能需要它的一些的(栏)属性,例如-宽度、高度、顶部和左侧位置。但不幸的是,没有直接的方法来获取这些属性,而是需要您自己计算它们。
若要获取/计算这些属性,您可以使用以下函数(可以任意命名),该函数将返回一个对象,该对象包含特定条形图的所有这些(宽度、高度、顶部、左侧)属性。
function getBAR(chart) {
const dataPoints = tooltipModel.dataPoints,
datasetIndex = chart.data.datasets.length - 1,
datasetMeta = chart.getDatasetMeta(datasetIndex),
scaleBottom = chart.scales['y-axis-0'].bottom,
bar = datasetMeta.data[dataPoints[0].index]._model,
canvasPosition = chart.canvas.getBoundingClientRect(),
paddingLeft = parseFloat(getComputedStyle(chart.canvas).paddingLeft),
paddingTop = parseFloat(getComputedStyle(chart.canvas).paddingTop),
scrollLeft = document.body.scrollLeft,
scrollTop = document.body.scrollTop;
return {
top: bar.y + canvasPosition.top + paddingTop + scrollTop,
left: bar.x - (bar.width / 2) + canvasPosition.left + paddingLeft + scrollLeft,
width: bar.width,
height: scaleBottom - bar.y
}
}
计算居中位置
检索所需属性后,您可以计算条形的中心位置,如下所示:
𝚌𝚎𝚗𝚝𝚎𝚛𝚇 = 𝚋𝚊𝚛-𝚕𝚎𝚏𝚝+(𝚋𝚊𝚛-𝚠𝚒𝚍𝚝𝚑/𝟸)
𝚌𝚎𝚗𝚝𝚎𝚛𝚈 = 𝚋𝚊𝚛-𝚝𝚘𝚙+(𝚋𝚊𝚛-𝚑𝚎𝚒𝚐𝚑𝚝/𝟸)
然后,创建自定义工具提示元素并相应地放置它。
ᴘʀᴇᴠɪᴇᴡ
ʟɪᴠᴇ ᴇxᴀᴍᴘʟᴇ⧩
数据-lang="js"数据-隐藏="真"数据-控制台="假"数据-巴贝尔="假">const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
datasets: [{
label: 'Revenue',
data: [4, 2, 3, 3],
backgroundColor: '#2d4e6d'
}, {
label: 'Expenses',
data: [3, 3.5, 4, 1],
backgroundColor: '#c06526'
}, {
label: 'Profit',
data: [3, 2.5, 4, 2],
backgroundColor: '#e0ecf0'
}]
},
options: {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}]
},
tooltips: {
enabled: false,
custom: function(tooltipModel) {
/*** jQuery IS USED FOR SIMPLICITY ***/
/* TOOLTIP & CARET ELEMENT */
let tooltip = $('#tooltip');
let tooltipCaret = $('#tooltip-caret');
/* CREATE TOOLTIP & CARET ELEMENT AT FIRST RENDER */
if (!tooltip.length && !tooltipCaret.length) {
tooltip = $('<div></div>').attr('id', 'tooltip');
tooltipCaret = $('<div></div>').attr('id', 'tooltip-caret');
$('body').append(tooltip, tooltipCaret);
}
/* HIDE IF NO TOOLTIP */
if (!tooltipModel.opacity) {
tooltip.hide();
tooltipCaret.hide();
return;
}
/* GET BAR PROPS (width, height, top, left) */
const barWidth = getBAR(this._chart).width,
barHeight = getBAR(this._chart).height,
barTop = getBAR(this._chart).top,
barLeft = getBAR(this._chart).left;
/* SET STYLE FOR TOOLTIP
(these can also be set in separate css file) */
tooltip.css({
"display": "inline-block",
"position": "absolute",
"color": "rgba(255, 255, 255, 1)",
"background": "rgba(0, 0, 0, 0.7)",
"padding": "5px",
"font": "12px Arial",
"border-radius": "3px",
"white-space": "nowrap",
"pointerEvents": "none"
});
/* SET STYLE FOR TOOLTIP CARET
(these can also be set in separate css file) */
tooltipCaret.css({
"display": "block",
"position": "absolute",
"width": 0,
"pointerEvents": "none",
"border-style": "solid",
"border-width": "8px 10px 8px 0",
"border-color": "transparent rgba(0, 0, 0, 0.7) transparent transparent"
});
/* ADD CONTENT IN TOOLTIP */
tooltip.text('ChartJS');
tooltip.append('<br><div class="color-box"></div><label style="display: block; margin: -16px 0 0 16px;"> Custom Tooltip<label>');
/* POSITION TOOLTIP & CARET
(position should be set after tooltip & caret is rendered) */
const centerX = barLeft + (barWidth / 2),
centerY = barTop + (barHeight / 2)
tooltip.css({
"top": centerY - (tooltip.outerHeight() / 2) + 'px',
"left": centerX + tooltipCaret.outerWidth() + 'px'
});
tooltipCaret.css({
"top": centerY - (tooltipCaret.outerHeight() / 2) + 'px',
"left": centerX + 'px'
});
/* FUNCTION TO GET BAR PROPS */
function getBAR(chart) {
const dataPoints = tooltipModel.dataPoints,
datasetIndex = chart.data.datasets.length - 1,
datasetMeta = chart.getDatasetMeta(datasetIndex),
scaleBottom = chart.scales['y-axis-0'].bottom,
bar = datasetMeta.data[dataPoints[0].index]._model,
canvasPosition = chart.canvas.getBoundingClientRect(),
paddingLeft = parseFloat(getComputedStyle(chart.canvas).paddingLeft),
paddingTop = parseFloat(getComputedStyle(chart.canvas).paddingTop),
scrollLeft = document.body.scrollLeft,
scrollTop = document.body.scrollTop;
return {
top: bar.y + canvasPosition.top + paddingTop + scrollTop,
left: bar.x - (bar.width / 2) + canvasPosition.left + paddingLeft + scrollLeft,
width: bar.width,
height: scaleBottom - bar.y
}
}
}
}
}
});
.color-box{width:12px;height:12px;background:#c06526;display:inline-block;margin-top:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
更新
如果您希望将工具提示放置在每个条形线段的中心,请使用以下函数:
function getBARSegment(chart) {
const dataPoints = tooltipModel.dataPoints,
bar = chart.active[dataPoints[0].datasetIndex]._model,
canvasPosition = chart.canvas.getBoundingClientRect(),
paddingLeft = parseFloat(getComputedStyle(chart.canvas).paddingLeft),
paddingTop = parseFloat(getComputedStyle(chart.canvas).paddingTop),
scrollLeft = document.body.scrollLeft,
scrollTop = document.body.scrollTop;
return {
top: bar.y + canvasPosition.top + paddingTop + scrollTop,
left: bar.x - (bar.width / 2) + canvasPosition.left + paddingLeft + scrollLeft,
width: bar.width,
height: bar.base - bar.y
}
}
ᴘʀᴇᴠɪᴇᴡ
ʟɪᴠᴇ ᴇxᴀᴍᴘʟᴇ⧩
数据-lang="js"数据-隐藏="真"数据-控制台="假"数据-巴贝尔="假">const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
datasets: [{
label: 'Revenue',
data: [4, 2, 3, 3],
backgroundColor: '#2d4e6d'
}, {
label: 'Expenses',
data: [3, 3.5, 4, 1],
backgroundColor: '#c06526'
}, {
label: 'Profit',
data: [3, 2.5, 4, 2],
backgroundColor: '#e0ecf0'
}]
},
options: {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
}]
},
tooltips: {
enabled: false,
custom: function(tooltipModel) {
/*** jQuery IS USED FOR SIMPLICITY ***/
/* TOOLTIP & CARET ELEMENT */
let tooltip = $('#tooltip');
let tooltipCaret = $('#tooltip-caret');
/* CREATE TOOLTIP & CARET ELEMENT AT FIRST RENDER */
if (!tooltip.length && !tooltipCaret.length) {
tooltip = $('<div></div>').attr('id', 'tooltip');
tooltipCaret = $('<div></div>').attr('id', 'tooltip-caret');
$('body').append(tooltip, tooltipCaret);
}
/* HIDE IF NO TOOLTIP */
if (!tooltipModel.opacity) {
tooltip.hide();
tooltipCaret.hide();
return;
}
/* GET BAR PROPS (width, height, top, left) */
const barWidth = getBARSegment(this._chart).width,
barHeight = getBARSegment(this._chart).height,
barTop = getBARSegment(this._chart).top,
barLeft = getBARSegment(this._chart).left;
/* SET STYLE FOR TOOLTIP
(these can also be set in separate css file) */
tooltip.css({
"display": "inline-block",
"position": "absolute",
"color": "rgba(255, 255, 255, 1)",
"background": "rgba(0, 0, 0, 0.7)",
"padding": "5px",
"font": "12px Arial",
"border-radius": "3px",
"white-space": "nowrap",
"pointerEvents": "none"
});
/* SET STYLE FOR TOOLTIP CARET
(these can also be set in separate css file) */
tooltipCaret.css({
"display": "block",
"position": "absolute",
"width": 0,
"pointerEvents": "none",
"border-style": "solid",
"border-width": "8px 10px 8px 0",
"border-color": "transparent rgba(0, 0, 0, 0.7) transparent transparent"
});
/* ADD CONTENT IN TOOLTIP */
tooltip.text('ChartJS');
tooltip.append('<br><div class="color-box"></div><label style="display: block; margin: -16px 0 0 16px;"> Custom Tooltip<label>');
/* POSITION TOOLTIP & CARET
(position should be set after tooltip & caret is rendered) */
const centerX = barLeft + (barWidth / 2),
centerY = barTop + (barHeight / 2)
tooltip.css({
"top": centerY - (tooltip.outerHeight() / 2) + 'px',
"left": centerX + tooltipCaret.outerWidth() + 'px'
});
tooltipCaret.css({
"top": centerY - (tooltipCaret.outerHeight() / 2) + 'px',
"left": centerX + 'px'
});
/* FUNCTION TO GET BAR PROPS */
function getBARSegment(chart) {
const dataPoints = tooltipModel.dataPoints,
bar = chart.active[dataPoints[0].datasetIndex]._model,
canvasPosition = chart.canvas.getBoundingClientRect(),
paddingLeft = parseFloat(getComputedStyle(chart.canvas).paddingLeft),
paddingTop = parseFloat(getComputedStyle(chart.canvas).paddingTop),
scrollLeft = document.body.scrollLeft,
scrollTop = document.body.scrollTop;
return {
top: bar.y + canvasPosition.top + paddingTop + scrollTop,
left: bar.x - (bar.width / 2) + canvasPosition.left + paddingLeft + scrollLeft,
width: bar.width,
height: bar.base - bar.y
}
}
}
}
}
});
.color-box{width:12px;height:12px;background:#c06526;display:inline-block;margin-top:5px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="ctx"></canvas>
这篇关于将工具提示放置在栏的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文