我的目标是创建自定义工具提示,并始终显示它们。稍后会有一些更奇特的东西,但是现在我正在努力实现这两件事。
要创建自定义工具提示,请使用charts.js docs的教程;在stackoverflow上我找到了solution for always showing the tooltips。
所以现在我有两个工具提示:标准工具提示,显示在绘制后并保持可见状态,以及自定义工具提示,它们目前正在工作但只出现在悬停点/数据点上。
jsFiddle https://jsfiddle.net/2c4261wj/1/以下图片显示问题。红色容器显示自定义工具提示,仅在悬停点时出现。
而不是标准的工具提示,我想在AfterDraw之后总是显示自定义的工具提示,但我无法做到这一点。
原始码位
工具提示选项中的自定义工具提示:
custom: function(tooltipModel) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Create element on first render
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = "<table></table>";
document.body.appendChild(tooltipEl);
}
// Hide if no tooltip
if (tooltipModel.opacity === 0) {
tooltipEl.style.opacity = 1;
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltipModel.yAlign) {
tooltipEl.classList.add(tooltipModel.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if (tooltipModel.body) {
var titleLines = tooltipModel.title || [];
var bodyLines = tooltipModel.body.map(getBody);
var innerHtml = '<div>';
titleLines.forEach(function(title) {
innerHtml += '<span>' + title + '</span>';
});
innerHtml += '</div>';
bodyLines.forEach(function(body, i) {
var colors = tooltipModel.labelColors[i];
var style = 'background:' + colors.backgroundColor;
style += '; border-color:' + colors.borderColor;
style += '; border-width: 2px';
var span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
innerHtml += '<div class="inner">' + span + body + '</div>';
});
innerHtml += 'last';
var tableRoot = tooltipEl;
tableRoot.innerHTML = innerHtml;
}
// `this` will be the overall tooltip
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = position.left + tooltipModel.caretX - 100 + 'px';
tooltipEl.style.top = position.top + tooltipModel.caretY - 100 + 'px';
tooltipEl.style.fontFamily = tooltipModel._fontFamily;
tooltipEl.style.fontSize = tooltipModel.fontSize;
tooltipEl.style.fontStyle = tooltipModel._fontStyle;
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
}
始终显示工具提示:
Chart.pluginService.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
我试图在第一个插件中使用自定义工具提示,但没有结果,也许我在插件中引用了错误。 有什么想法吗?
答案 0 :(得分:1)
所以,我找到了解决方案。之前,我尝试使用自定义工具提示并创建了一个插件,这样可以使自定义工具提示在加载时显示并保持可见。
我现在做的是:
首先:working fiddle of the current state
实际上它非常简单;插件获取所有数据集,循环遍历它们并在画布上绘制内容。感谢插件,您可以通过将其保存到数组来访问所有数据,然后是...抓住它们并做任何你想做的事。
魔法发生在这里:
Chart.plugins.register({
afterDraw: function(chart, easing) {
// To only draw at the end of animation, check for easing === 1
var debug = false;
var ctx = chart.chart.ctx;
var numbers = [],
position = [],
dataString = [],
safetyCounter = 0;
var datasetAmount = chart.data.datasets.length;
var datasetLength = chart.getDatasetMeta(0).data.length;
var amountLength = (datasetAmount * datasetLength);
chart.data.datasets.forEach(function(dataset, i) {
var meta = chart.getDatasetMeta(i);
if (!meta.hidden) {
meta.data.forEach(function(element, index) {
if (numbers.indexOf(dataset.data[index]) < 0) {
numbers.push(dataset.data[index]);
}
position.push(element.tooltipPosition());
var fontSize = 20;
var fontStyle = 'bold';
var fontFamily = 'Helvetica Neue';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.lineWidth = 2;
dataString.push(dataset.data[index].toString() + '%');
var padding = 5;
if (numbers.length === amountLength) {
if (safetyCounter === 0) {
safetyCounter++
}
for (var k = 0; k < numbers.length; k++) {
if (k < datasetLength) {
ctx.strokeStyle = "#c7d85e";
ctx.fillStyle = "#c7d85e";
if (numbers[k] >= numbers[k + datasetLength]) {
ctx.beginPath();
ctx.moveTo(position[k].x, position[k].y - 50);
ctx.lineTo(position[k].x, position[k].y);
ctx.stroke();
ctx.fillText(dataString[k], position[k].x, position[k].y - 50 - (fontSize / 2) - padding);
} else {
ctx.beginPath();
ctx.moveTo(position[k].x, position[k].y + 50);
ctx.lineTo(position[k].x, position[k].y);
ctx.stroke();
ctx.fillText(dataString[k], position[k].x, position[k].y + 80 - (fontSize / 2) - padding);
}
} else {
ctx.strokeStyle = "#4f708b";
ctx.fillStyle = "#4f708b";
if (numbers[k] >= numbers[k - datasetLength]) {
ctx.beginPath();
ctx.moveTo(position[k].x, position[k].y - 50);
ctx.lineTo(position[k].x, position[k].y);
ctx.stroke();
ctx.fillText(dataString[k], position[k].x, position[k].y - 50 - (fontSize / 2) - padding);
} else {
ctx.beginPath();
ctx.moveTo(position[k].x, position[k].y + 50);
ctx.lineTo(position[k].x, position[k].y);
ctx.stroke();
ctx.fillText(dataString[k], position[k].x, position[k].y + 80 - (fontSize / 2) - padding);
}
}
}
} else {
// nothing yet here
}
});
}
});
si++;
// necessary for prevent standard tooltips from showing
// but I also use css pointer events for preventing canvas to respond to mouseevents
if (chart.config.options.showAllTooltips) {
if (!chart.allTooltipsOnce) {
if (easing !== 1) return;
chart.allTooltipsOnce = true;
}
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function(tooltip) {
tooltip.initialize();
tooltip.update();
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});