如何让几个交点的数据标签很好地显示?

问题描述 投票:0回答:1

不,我有一个折线图,上面有几条线。这些线在某些点相交。我还使用 Chartjs-plugin-datalabels 来标记图形上的点。

问题是:如果我在一个地方有来自不同行的几个点,它们的标签也会显示在一个地方,这很糟糕。我怎样才能让它们看起来漂亮且可读?

您可以在第二张图表中看到该问题(带有“2 (...)”的点):

在文档中没有找到任何内容,而且我是 JS 新手。所以,我希望能得到你们的帮助:)

javascript html chart.js
1个回答
0
投票

好吧,在没有看到你的代码的情况下,我必须推断出它会是什么样子以及我将如何解决它。

我愿意:

  1. 迭代数据并寻找交叉点
  2. 为具有所需标签的交叉点创建一个“字典”
  3. 使用插件中的
    formatter
    功能来设置交叉点的标签

这里有一个演示,我将如何做到这一点:
代码中有一些注释标记了重要部分。

const data = {
    labels: ['1', '2', '3', '4', '5'], 
    datasets: [{
        label: 'DS1',
        data: [{x:1, y: 1, v:'d1'}, {x:2, y: 2, v:'d1'}, {x:3, y: 4, v:'d1'}, {x:4, y: 3, v:'d1'}], 
     }, {
        label: 'DS2',
        data: [
            {x:1, y: 1, v:'d2'}, {x:2, y: 2, v:'d3'}, {x:3, y: 2, v:'d2'}, {x:4, y: 2, v:'d2'}], 
     }, {
        label: 'DS3',
        data: [{x:1, y: 1, v:'d3'}, {x:2, y: 2, v:'d3'}, {x:3, y: 5, v:'d3'}, {x:4, y: 5, v:'d3'}], 
     }],
};

// Helper to get all values into on array
let flatDatalist = data.datasets.map( entry => entry.data).flat();

// find all overlapping points
let overlappingEntries = flatDatalist.filter( (entry, index )=>{
    return flatDatalist.some((entryInner, indexInner) => index != indexInner && entry.x == entryInner.x && entry.y == entryInner.y)
})

// create an Array with new formated label for overlapping labels
let labelsForOverlappingEntries = overlappingEntries.reduce((prev, curr) => {
    let key = `${curr.x}__${curr.y}`;
    
    if(!prev[key]){
        prev[key] = `${data.labels[curr.x]}:${curr.v}`;
    } else {
          prev[key] = `${prev[key]}\n${data.labels[curr.x]}:${curr.v}`;
    }
    
    return prev;
 }, {});

const config = {
    type: 'line',
    data: data,
    plugins:[ChartDataLabels],
    options: {
        scales: {
          y: {
            min: 0,
            max: 6,
          }
        },
        maintainAspectRatio: false,
        plugins: {
          datalabels: {
            align: 'end',
            anchor: 'end',
            offset: -1,
            formatter: function(v, ctx){
              // get a multiline label when needed
              let key = `${v.x}__${v.y}`;
              if(labelsForOverlappingEntries[key]){
                return labelsForOverlappingEntries[key];
              }
              return ctx.chart.data.labels[ctx.dataIndex] + ': '+ v.v;
            },
          }
        }
    }
};

new Chart(
    document.getElementById('chart'),
    config
);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>  
<script src="
https://cdn.jsdelivr.net/npm/[email protected]/dist/chartjs-plugin-datalabels.min.js
"></script>
<div class="chart" style="height:184px; width:350px;">
    <canvas  id="chart" ></canvas>
</div>

免责声明我不确定这是否是最好的方法,而且它可能有点过度设计。尽管如此,它还是有效的,我希望你能使用它,或者至少它有助于找到你的方法。

© www.soinside.com 2019 - 2024. All rights reserved.