ChartJs折线图-在某些数据点上方显示永久性图标,并在悬停时显示文本

时间:2020-05-14 17:13:20

标签: chart.js

我有一张图表需要绘制,除了数据点外,我还希望图标(永久地)在(某些)数据点上方带有自定义文本字符串。

我不需要默认值popover,因为我可以使用自定义图例,但是我需要在一个或两点上方添加一个图标,并在该图标上悬停时显示一个popover。我需要从与图表无关的数据构建弹出文本字符串。

自定义数据标签似乎不够灵活,无法在不同数据点上使用不同的图标/弹出框,但是我可能是错的。

另一种可能性是chartjs-plugin-datalabels,但我不确定。

line graph with custom icon

1 个答案:

答案 0 :(得分:3)

如果图表(画布)的大小是固定的,则可以通过添加一个附加的dataset来轻松解决此问题,该{ data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null), fill: false, pointStyle: icon, pointRadius: 22, pointHoverRadius: 22 } 除了在图表中显示的图标外,什么都没有指定。

data2

鉴于数据数组imageIndexes和数组data,可以使用Array.map构建图标dataset的{​​{1}}。请注意,这些值(如果有的话)是从data2中的相应值派生而来的,但要稍加增加以使图像显示在它们的顶部。

data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null)

此外,您需要在图表options内定义一个tooltips对象,以设置弹出窗口的样式,并确保仅当鼠标悬停在图标上时才显示工具提示。

tooltips: {
  filter: tooltipItem => tooltipItem.datasetIndex == 2,
  titleFontSize: 16,
  titleAlign: 'center',
  callbacks: {
    title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
    label: () => null
  }
},

请查看下面的可运行代码。

const labels = ['A', 'B', 'C', 'D', 'E', 'F'];
const alerts = ['B', 'D'];
const data1 = [0, 2, 1, 3, 2, 1];
const data2 = [1, 3, 3, 4, 3, 2];
const imageIndexes = [1, 3];
const tooltipText = 'Efficiency of Standard Curve\nnot opimal';

var icon = new Image();
icon.src = 'https://i.stack.imgur.com/YvlWY.png';

const chart = new Chart(document.getElementById("myChart"), {
  type: "line",
  data: {
    labels: labels,
    datasets: [{
        data: data1,
        fill: false,
        backgroundColor: 'blue',
        borderColor: 'blue',
        lineTension: 0,
        pointRadius: 5,
        pointHoverRadius: 5,
        pointBorderWidth: 3,
        pointHoverBorderWidth: 3,
        pointBorderColor: 'white',
        pointHoverBorderColor: 'white'
      },
      {
        data: data2,
        fill: false,
        showLine: false,
        backgroundColor: 'orange',
        pointRadius: 4,
        pointHoverRadius: 4
      },
      {
        data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
        fill: false,
        pointStyle: icon,
        pointRadius: 22,
        pointHoverRadius: 22
      }
    ]
  },
  options: {
    responsive: false,
    title: {
      display: false
    },
    legend: {
      display: false
    },
    tooltips: {
      filter: tooltipItem => tooltipItem.datasetIndex == 2,
      titleFontSize: 16,
      titleAlign: 'center',
      callbacks: {
        title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
        label: () => null
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
          max: 6,
          stepSize: 1
        }
      }],
      xAxes: [{
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" style="width: 500px; height: 200px"></canvas>