Chart.js 具有一个共同图例的多个图表多个、图表、图例、Chart

2023-09-08 08:58:36 作者:心跳的感觉

一页上有多个图表.每条图表线都很常见.我想显示一个对多个图表通用的图例,如该图.它使用 OnClick 显示和隐藏所有图表线,就像默认图例一样.这张照片是假的

这可能吗?怎么样?

向 Web 开发人员推荐35款 JavaScript 图形图表库

我试过 Chart.js 在多个图表上同步图例切换,一个图例,多个图表Chart JS等.但是,这些解决方案只有一个带有图例的图表,而该图例会影响其他图表.

我应该隐藏图表并只显示图例吗?我应该画一个没有数据的图表吗?

如果你能告诉我,我会毕业的

HTML

<script src="https://rawgit.com/nnnick/Chart.js/v1.0.2/Chart.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta/Chart.js"></script>

<canvas id="myChartA"></canvas></div>

<canvas id="myChartB"></canvas></div>

JS

var ctxA = document.getElementById("myChartA").getContext("2d");var ctxB = document.getElementById("myChartB").getContext("2d");让 data_A1 = [{x: "2019-01-01 00:01:38",y:13.0"},{x: "2019-01-01 01:01:39",y:11.0"},{x: "2019-01-01 02:01:40",y:16.0"},{x: "2019-01-01 03:01:41",y:15.0"},{x: "2019-01-01 04:01:42",y:14.0"}];var data_A2 = [{x: "2019-01-01 00:01:42",是:14.671}, {x: "2019-01-01 01:01:42",是:13.691}, {x: "2019-01-01 02:01:42",是:16.691}, {x: "2019-01-01 03:01:42",是:17.691}, {x: "2019-01-01 04:01:42",是:18.691}];让 data_B1 = [{x: "2019-01-02 00:01:38",y:12.0"},{x: "2019-01-02 01:01:39",y:11.0"},{x: "2019-01-02 02:01:40",y:13.0"},{x: "2019-01-02 03:01:41",y:14.0"},{x: "2019-01-02 04:01:42",y:16.0"}];var data_B2 = [{x: "2019-01-02 00:00:00",是:14.671}, {x: "2019-01-02 01:01:42",是:13.691}, {x: "2019-01-02 02:01:42",是:16.691}, {x: "2019-01-02 03:01:42",是:15.691}, {x: "2019-01-02 04:01:42",是:14.691}];var myChartA = new Chart(ctxA, {类型:'线',数据: {数据集:[{标签:'第一个数据',数据:data_A1,边框颜色:'#0f0',显示线:真}, {标签:'第二个数据',数据:data_A2,边框颜色:'#f00',显示线:真}]},选项: {秤:{x轴:[{类型:'时间',时间: {displayFormat: 'h:mm',}}]}}});var myChartB = new Chart(ctxB, {类型:'线',数据: {数据集:[{标签:'第一个数据',数据:data_B1,边框颜色:'#0f0',显示线:真}, {标签:'第二个数据',数据:data_B2,边框颜色:'#f00',显示线:真}]},选项: {秤:{x轴:[{类型:'时间',时间: {displayFormat: 'h:mm',}}]}}});

解决方案

如果两个数据集相似,您可以通过 generateLegend api 创建一个公共图例.

首先通过选项禁用默认图例

图例:{显示:假}

然后使用 generateLegend() api 获取数据标签并将其设置为公共元素.

<ul class="legend"></ul>

然后将事件监听器添加到生成的元素并定位所有图表

document.querySelector('.legend').innerHTML = myChartA.generateLegend();var legendItems = document.querySelector('.legend').getElementsByTagName('li');for (var i = 0; i < legendItems.length; i++) {legendItems[i].addEventListener("点击", legendClickCallback.bind(this,i), false);}函数 legendClickCallback(legendItemIndex){document.querySelectorAll('.myChart').forEach((chartItem,index)=>{var chart = Chart.instances[index];var dataItem = chart.data.datasets[legendItemIndex]if(dataItem.hidden == true || dataItem.hidden == null){dataItem.hidden = false;} 别的 {dataItem.hidden = true;}图表.更新();})}

这里有一支笔样https://codepen.io/srajagop/pen/yLBJOOo

注意我使用的是 chartjs 2.8

There are multiple charts on one page. Each chart line is common. I want to display a legend that is common to multiple charts like the figure.It shows and hides all chart lines with OnClick like the default legend. THIS PICT IS FAKE

Is that possible? how?

I had tried Chart.js sync legend toggle on multiple charts, One legend, multiple charts Chart JS and etc. But, those solutions have one chart with legend, and that legend affects other charts.

Should I hide the chart and show only the legend? Should I draw a chart with no data?

I would be grad if you could tell me

HTML

<script src="https://rawgit.com/nnnick/Chart.js/v1.0.2/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta/Chart.js"></script>
<div>
    <canvas id="myChartA"></canvas>
</div>

<div>
    <canvas id="myChartB"></canvas>
</div>

JS

var ctxA = document.getElementById("myChartA").getContext("2d");
var ctxB = document.getElementById("myChartB").getContext("2d");

let data_A1 = [{
        x: "2019-01-01 00:01:38",
        y: "13.0"
    },
    {
        x: "2019-01-01 01:01:39",
        y: "11.0"
    },
    {
        x: "2019-01-01 02:01:40",
        y: "16.0"
    },
    {
        x: "2019-01-01 03:01:41",
        y: "15.0"
    },
    {
        x: "2019-01-01 04:01:42",
        y: "14.0"
    }
];

var data_A2 = [{
    x: "2019-01-01 00:01:42",
    y: 14.671
}, {
    x: "2019-01-01 01:01:42",
    y: 13.691
}, {
    x: "2019-01-01 02:01:42",
    y: 16.691
}, {
    x: "2019-01-01 03:01:42",
    y: 17.691
}, {
    x: "2019-01-01 04:01:42",
    y: 18.691
}];

let data_B1 = [{
        x: "2019-01-02 00:01:38",
        y: "12.0"
    },
    {
        x: "2019-01-02 01:01:39",
        y: "11.0"
    },
    {
        x: "2019-01-02 02:01:40",
        y: "13.0"
    },
    {
        x: "2019-01-02 03:01:41",
        y: "14.0"
    },
    {
        x: "2019-01-02 04:01:42",
        y: "16.0"
    }
];

var data_B2 = [{
    x: "2019-01-02 00:00:00",
    y: 14.671
}, {
    x: "2019-01-02 01:01:42",
    y: 13.691
}, {
    x: "2019-01-02 02:01:42",
    y: 16.691
}, {
    x: "2019-01-02 03:01:42",
    y: 15.691
}, {
    x: "2019-01-02 04:01:42",
    y: 14.691
}];


var myChartA = new Chart(ctxA, {
    type: 'line',
    data: {
        datasets: [{
            label: '1st Data',
            data: data_A1,
            borderColor: '#0f0',
            showLine: true
        }, {
            label: '2nd Data',
            data: data_A2,
            borderColor: '#f00',
            showLine: true
        }]
    },
    options: {
        scales: {
            xAxes: [{
                type: 'time',
                time: {
                    displayFormat: 'h:mm',
                }
            }]
        }
    }
});

var myChartB = new Chart(ctxB, {
    type: 'line',
    data: {
        datasets: [{
            label: '1st Data',
            data: data_B1,
            borderColor: '#0f0',
            showLine: true
        }, {
            label: '2nd Data',
            data: data_B2,
            borderColor: '#f00',
            showLine: true
        }]
    },
    options: {
        scales: {
            xAxes: [{
                type: 'time',
                time: {
                    displayFormat: 'h:mm',
                }
            }]
        }
    }
});

解决方案

You can create a common legend and through generateLegend api, if both the datasets are similar.

First disable the default legends though the options

legend: {
        display: false
      }

Then use generateLegend() api to get the data labels and set it to a common element.

<ul class="legend">

</ul>

Then add event listeners to the generated elements and target all the charts

document.querySelector('.legend').innerHTML = myChartA.generateLegend();

var legendItems = document.querySelector('.legend').getElementsByTagName('li');
for (var i = 0; i < legendItems.length; i++) {
  legendItems[i].addEventListener("click", legendClickCallback.bind(this,i), false);
}

function legendClickCallback(legendItemIndex){
  document.querySelectorAll('.myChart').forEach((chartItem,index)=>{
    var chart = Chart.instances[index];
    var dataItem = chart.data.datasets[legendItemIndex]    
    if(dataItem.hidden == true || dataItem.hidden == null){
      dataItem.hidden = false;
    } else {
      dataItem.hidden = true;
    }
    chart.update();
  })  
}

A sample pen is present here https://codepen.io/srajagop/pen/yLBJOOo

Note I am using chartjs 2.8