如何将Highcharts Legends与所有唯一条目合并

时间:2016-10-18 18:00:09

标签: javascript jquery highcharts

我正在使用一对PIE图表。每个都涵盖相同的数据主题,并可以具有相同的切片项。但是,并非所有图例项都始终出现在两个PIE中。我已经看过几个解决方案(这个one是最接近的)。但是,当其中一个PIE没有另一个PIE时,它会中断。

测试用例jsFiddle显示第一个PIE没有'Engineering'切片而第二个PIE没有。但是,这意味着该项目不会显示在图例中。如何在一个单一图例中获取每个PIE图例中的所有唯一条目?

这是当前的回调函数(注意它基于series [0]):

  $(chart.series[0].data).each(function(i, e) {
    e.legendItem.on('click', function(event) {
      var legendItem = e.name;

      event.stopPropagation();

      $(chart.series).each(function(j, f) {
        $(this.data).each(function(k, z) {
          if (z.name == legendItem) {
            if (z.visible) {
              z.setVisible(false);
            } else {
              z.setVisible(true);
            }
          }
        });
      });

    });
  });

1 个答案:

答案 0 :(得分:1)

你需要得到一个包含唯一点的数组'名称(这将是一个图例),然后遍历图例中的项目并设置适当的事件。

以下我的命题对于您的测试用例就足够了(例如,它没有考虑到考虑链接系列)。

这里是getAllItems()方法的包装器,它为图例提供项目,我得到了独特的点数'这里的名称(寻找唯一名称的循环可能会被优化,但对于这种情况,差异可能会忽略不计):

Highcharts.wrap(Highcharts.Legend.prototype, 'getAllItems', function (p) {              
            if (!this.options.mergedPieItems) {
                return p.call(this);
            }

            var allItems = [],
                uniquePieNames = [];

            this.chart.series.forEach(function (series) {
                var i,
                    len,
                    point;

                if (series.type === 'pie') {
                    for (i = 0, len = series.data.length; i < len; i++) {
                        point = series.data[i];

                        if (uniquePieNames.indexOf(point.name) === -1) {
                            uniquePieNames.push(point.name);
                            allItems.push(point);
                        }
                    }
                } else {
                    allItems.push(series);
                }
            });

            return allItems;
        });

这里我设置了事件,这几乎就是您附加的代码的副本

load: function () {
                    if (this.options.legend.mergedPieItems) {
                        var series = this.series;

                        this.legend.allItems.forEach(function (item) {
                            if (item.series) {
                                item.legendItem.element.onclick = function (e) {
                                    e.stopPropagation();

                                    series.forEach(function (series) {
                                        series.data.forEach(function (point) {
                                            if (point.name === item.name) {
                                                point.setVisible(!point.visible);
                                            }
                                        });
                                    });
                                };
                            }
                        }); 
                    }
                }

启用包装器和回调,以防图例应该表现为未包装。

legend: {
            enabled: true,
            mergedPieItems: true
        },

您的示例:http://jsfiddle.net/fjLao4nr/2/

系列与饼图不同的示例:http://jsfiddle.net/fjLao4nr/

切片的颜色与这些馅饼不匹配 - 但这可以通过为点设置相同的颜色来实现。 此外,当图例中的项目悬停时,只突出显示一个系列中的点 - 这可以通过设置mouseouver / mouseout事件上的点的状态来实现(类似于在加载回调中完成的那样)。 / p>