単純に、チャートエリアの良さげな位置に固定の画像を貼るのであれば、こんな感じでしょうか。
<div>
<canvas id="chart" style="border: solid 1px; width: 800px; height: 600px"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
<script>
let tooltipImg = new Image();
tooltipImg.src = '画像パス';
const drawImagePlugin = {
afterDraw: chart => {
// bar stackの一番最後の要素の描画領域を取得
const dataset = chart.config.data.datasets.slice(-1)[0];
const i = chart.config.data.datasets.length - 1;
const meta = chart.controller.getDatasetMeta(i);
const bar = meta.data.slice(-1)[0];
const index = meta.data.length - 1;
const data = dataset.data[index];
const xPos = bar._model.x;
const yPos = bar._model.y;
// 貼り付ける画像のサイズを棒グラフに合わせて調整する。
const b_w = bar._model.width;
const b_h = tooltipImg.height * b_w / tooltipImg.width;
const context = document.getElementById('chart').getContext('2d');
context.drawImage(tooltipImg, xPos - b_w / 2, yPos - b_h - 10, b_w, b_h);
}
}
Chart.pluginService.register(drawImagePlugin);
const config = {
type: "bar",
data: {
labels: [0, 1, 2, 3],
datasets: [
{
label: "AAA",
data: [100, 200, 221, 350],
backgroundColor: "green",
},
{
label: "BBB",
data: [100, 200, 221, 350],
backgroundColor: "skyblue",
},
{
label: "CCC",
data: [100, 200, 221, 350],
backgroundColor: "red",
},
],
},
options: {
scales: {
xAxes: [
{
stacked: true,
scaleLabel: {
display: true,
},
},
],
yAxes: [
{
stacked: true,
scaleLabel: {
display: true,
},
},
],
},
responsive: true,
tooltips: {
enabled: false,
},
hover: { mode: null },
animation: false,
}
};
tooltipImg.addEventListener("load", () => {
const ctx = document.getElementById('chart').getContext('2d');
tooltipImg.width = tooltipImg.naturalWidth;
tooltipImg.height = tooltipImg.naturalHeight;
new Chart(ctx, config);
}, false);
</script>
ツールチップを固定表示するのであれば、よくみかける下記の手法で対応できます。(ツールチップの形を質問記載の画像に似せるところまでは回答範囲外と考えるので対応していません)
<body>
<canvas id="chart"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js"></script>
<script>
"use strict";
const type = "bar";
const data = {
labels: [0, 1, 2, 3],
datasets: [
{
label: "AAA",
data: [100, 200, 221, 350],
backgroundColor: "green",
},
{
label: "BBB",
data: [100, 200, 221, 350],
backgroundColor: "skyblue",
},
{
label: "CCC",
data: [100, 200, 221, 350],
backgroundColor: "red",
},
],
};
Chart.pluginService.register({
beforeRender: chart => {
if (chart.config.options.showAllTooltips) {
chart.pluginTooltips = [];
chart.config.data.datasets.forEach((dataset, i) => {
chart.getDatasetMeta(i).data.forEach(sector => {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
chart.options.tooltips.enabled = false;
}
},
afterDraw: (chart, easing) => {
if (chart.config.options.showAllTooltips) {
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
let cnt = 1;
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, tooltip => {
if (cnt == chart.pluginTooltips.length) { // 最後のスタック描画時だけツールチップを描く
tooltip.initialize();
tooltip.update();
tooltip.pivot();
tooltip.transition(easing).draw();
}
cnt = cnt + 1;
});
chart.options.tooltips.enabled = false;
}
}
})
const options = {
scales: {
xAxes: [
{
stacked: true,
scaleLabel: {
display: true,
},
},
],
yAxes: [
{
stacked: true,
scaleLabel: {
display: true,
},
},
],
},
tooltips: {
mode: 'index',
caretSize: 10,
titleFontSize: 24,
xAlign: "center",
yAlign: "bottom",
bodySpacing: 100,
backgroundColor: "yellowgreen",
position: "customMode",
cornerRadius: 20,
callbacks: {
label: (tooltipItems, data) => {
return;
},
title: (tooltipItems, data) => {
return ' 最新 ';
}
}
},
showAllTooltips: true,
responsive: true,
hover: { mode: null },
};
Chart.Tooltip.positioners.customMode = (elements, eventPosition) => {
let x = 0;
let y = 0;
let count = 0;
for (let el of elements) {
if (el && el.hasValue()) {
let pos = el.tooltipPosition();
x += pos.x;
y = pos.y;
++count;
}
}
return {
x: Math.round(x / count),
y: Math.round(y / count) - 20
};
}
const ctx = document.getElementById("chart").getContext("2d");
const myChart = new Chart(ctx, {
type: type,
data: data,
options: options,
});
</script>
</body>
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/11 10:06
退会済みユーザー
2021/05/12 04:16 編集
2021/06/05 13:25