javascript Chart.js:通过点击图例隐藏系列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28093010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 08:23:52  来源:igfitidea点击:

Chart.js: hiding series by clicking on legend

javascriptchartschart.js

提问by pomarc

I'm developing a site that uses chart.js (www.chartjs.org).

我正在开发一个使用 chart.js (www.chartjs.org) 的网站。

I have to make a line chart that shows multiple series of data, that users can hide or show by clicking on the respective legend symbol (similar to this http://js.syncfusion.com/demos/web/#!/azure/chart/linechart).

我必须制作一个折线图,显示多个系列的数据,用户可以通过单击相应的图例符号来隐藏或显示(类似于http://js.syncfusion.com/demos/web/#!/azure/图表/折线图)。

Is there any way to do it with chartjs?

有没有办法用chartjs做到这一点?

回答by Igor

You can try this
Create store for hidden datasets

你可以试试这个
Create store for hidden datasets

window.chartName = new Chart(...

window.chartName.store = new Array();

Then use this function to update chart, must be handled by click on legend item

然后使用此功能更新图表,必须通过单击图例项来处理

function updateDataset(legendLi, chart, label) {
      var store = chart.store;
      var exists = false;
      for (var i = 0; i < store.length; i++) {
        if (store[i][0] === label) {
          exists = true;
          chart.datasets.push(store.splice(i, 1)[0][1]);
          legendLi.fadeTo("slow", 1);
        }
      }
      if (!exists) {
        for (var i = 0; i < chart.datasets.length; i++) {
          if (chart.datasets[i].label === label) {
            chart.store.push([label, chart.datasets.splice(i, 1)[0]]);
            legendLi.fadeTo("slow", 0.33);
          }
        }
      }
      chart.update();
    }

Don't forget updated legend template in chart options

不要忘记更新图表选项中的图例模板

legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li class=\"legend-item\" onclick=\"updateDataset($(this), window.chartName, '<%=datasets[i].label%>')\"><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"

Shortly, i added this onclick handler for li component

不久,我为 li 组件添加了这个 onclick 处理程序

<li class=\"legend-item\" onclick=\"updateDataset($(this), window.chartName , '<%=datasets[i].label%>')\"><

For example fiddle

例如小提琴

回答by benallansmith

This is now available in Charts.js

这现在在 Charts.js 中可用

From the documentation http://www.chartjs.org/docs/#chart-configuration-legend-configuration

从文档http://www.chartjs.org/docs/#chart-configuration-legend-configuration

Legend Configuration

The legend configuration is passed into the options.legend namespace. The global options for the chart legend is defined in Chart.defaults.global.legend.

onClickfunction(event, legendItem) {} A callback that is called when a 'click' event is registered on top of a label item

onHoverfunction(event, legendItem) {} A callback that is called when a 'mousemove' event is registered on top of a label item

图例配置

图例配置被传递到 options.legend 命名空间。图表图例的全局选项在 Chart.defaults.global.legend 中定义。

onClickfunction(event, legendItem) {} 在标签项上注册“点击”事件时调用的回调

onHoverfunction(event, legendItem) {} 在标签项上注册“mousemove”事件时调用的回调

回答by Ailete619

An update to @benallansmith answer, the link to the documentation is now :

@benallansmith 答案的更新,文档链接现在是:

https://www.chartjs.org/docs/latest/configuration/legend.html

https://www.chartjs.org/docs/latest/configuration/legend.html

My version of the example code, to have datasets 2 and 3 hidden while clicking on legend for dataset 1 (datasets 2 and 3 have their legends hidden with the filter function):

我的示例代码版本,在单击数据集 1 的图例时隐藏数据集 2 和 3(数据集 2 和 3 的图例使用过滤器功能隐藏):

public static readonly myChart: Chart.ChartConfiguration = {
    type: 'line',
    data: {
        datasets: [
            {
                label: 'A',
                borderColor: 'red',
                fill: false,
                lineTension: 0
            },
            {
                label: 'B',
                borderColor: 'blue',
                fill: false,
                lineTension: 0,
                pointRadius: 0
            },
            {
                borderColor: 'blue',
                borderDash: [5, 10],
                borderWidth: 1,
                fill: false,
                lineTension: 0,
                pointRadius: 0
            },
            {
                borderColor: 'blue',
                borderDash: [5, 10],
                borderWidth: 1,
                fill: false,
                lineTension: 0,
                pointRadius: 0
            }
       ]
   },
   options: {
       legend: {
           labels: {
               filter: function(legendItem, chartData) {
                    if (legendItem.datasetIndex > 1) {
                        return false;
                    }
                    return true;
                }
            },
            onClick: function(e, legendItem) {
                const index = legendItem.datasetIndex;
                if (index === 1) {
                    const ci = this.chart;
                    [
                        ci.getDatasetMeta(1),
                        ci.getDatasetMeta(2),
                        ci.getDatasetMeta(3)
                    ].forEach(function(meta) {
                        meta.hidden = meta.hidden === null ? !ci.data.datasets[1].hidden : null;
                    });
                    ci.update();
                } else {
                    // Do the original logic
                    Chart.defaults.global.legend.onClick.call(this, e, legendItem);
                }
            }
        },
        responsive: false,
        animation: {
            duration: 0
        },
    }
...
};

回答by EZone Lai

my version is v2.8.0 I find a work way, try it.

我的版本是 v2.8.0 我找到了一个工作方式,试试吧。

add

添加

legend : {

                }

into option

进入选项

var donutOptions     = {
                maintainAspectRatio : false,
                responsive : true,
                animation: {
                    animateScale: true,
                    animateRotate: true
                },
                tooltips: {
                    intersect: false,
                    callbacks: {
                        label: function (tooltipItem, data) {
                            ...
                        }
                    },
                },
                plugins: {
                    datalabels: {
                        ...
                        },
                    },
                },
                legend : {

                }

            };

and use this

并使用这个


donutChart.chart.getDatasetMeta(0).data[index].hidden = true;

donutChart.update();

回答by pomarc

I've found no way to do this. It's easy to put some onclick behaviour on the legend template, and you can easily change the series stroke and colors alpha channel to 0 so that the area and stroke disappear but I've found no way to do this on points.

我发现没有办法做到这一点。很容易在图例模板上添加一些 onclick 行为,您可以轻松地将系列笔触和颜色 alpha 通道更改为 0,以便区域和笔触消失,但我发现无法在点上执行此操作。

I've decided to use google charts for this particular chart, and chart.js whenever I do not need that behavior, hoping that the good creators of chart.js will add it in the future.

我决定在这个特定图表中使用谷歌图表,并在我不需要这种行为时使用 chart.js,希望 chart.js 的优秀创建者将来会添加它。

回答by Alvin

onLegendClick: function (e) {
var series = e.target;
                series.isVisible() ? series.hide() : series.show();
            },

dxcharts have a function called onLegendClick, a few others are onSeriesClick and onPointClick. I hope this helps.

dxcharts 有一个名为 onLegendClick 的函数,还有一些是 onSeriesClick 和 onPointClick。我希望这有帮助。