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

8
我正在开发一个使用chart.js(www.chartjs.org)的网站。
我必须制作一条线图,显示多个系列的数据,并通过单击相应的图例符号来隐藏或显示它们(类似于此http://js.syncfusion.com/demos/web/#!/azure/chart/linechart)。
有没有办法在chartjs中实现这个功能?

只需重新绘制图表,不包括该系列数据即可吗? - Pointy
@Pointy,我在想是否有更简单、自包含和更自动化的方法来做到这一点。这样,我必须动态地将事件附加到图例项,排除或包含系列并重新绘制。对于许多图表来说,这很快就会变得混乱,但无论如何还是谢谢你。 - pomarc
就我所知,特别是Chart.js在支持交互方面并没有太多的复杂性。 - Pointy
6个回答

14

你可以尝试这个
为隐藏的数据集创建存储库

window.chartName = new Chart(...

window.chartName.store = new Array();

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

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();
    }

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

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>"

简而言之,我为 li 组件添加了此 onclick 处理程序

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

我不知道为什么这个不太受欢迎。它帮了我很多,谢谢!如果可以的话,我会给它加1个赞和更多的。 - SirDerpington
Igor,非常好的解决方案!我有多个按特定顺序排列的数据集。使用您在jsfiddle(http://jsfiddle.net/1qjco9Ls/)中的代码,一旦隐藏某些内容,然后再次单击以显示它,该数据集就会被推到末尾。是否有任何方法可以在隐藏和取消隐藏后记住其原始位置? - rocky

4

这个功能现在可以在 Charts.js 中使用。

从文档 http://www.chartjs.org/docs/#chart-configuration-legend-configuration 中可以了解更多信息。

图例配置

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

onClick function(event, legendItem) {} 当在标签项目上注册 'click' 事件时调用的回调函数

onHover function(event, legendItem) {} 当在标签项目上注册 'mousemove' 事件时调用的回调函数


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

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

我的示例代码版本,当单击数据集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
        },
    }
...
};

1
我的版本是v2.8.0 我发现了一种可行的方法,请尝试。
添加
legend : {

                }

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

                }

            };


使用此代码。

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

donutChart.update();

0

我没找到解决方法。在图例模板上加入一些onclick行为很容易,你可以轻松地将系列描边和颜色alpha通道更改为0,使区域和描边消失,但我没找到对点这样做的方法。

我决定在这个特殊的图表中使用Google Charts,并在不需要该行为时使用chart.js,希望chart.js的优秀创建者们能在未来添加它。


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

dxcharts有一个名为onLegendClick的函数,还有一些其他的函数如onSeriesClick和onPointClick。希望这可以帮到你。


2
原始问题涉及使用ChartJS,而不是dxCharts,因此这并没有帮助。 - jschrab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接