2016-10-18 4 views
0

Я работаю с парой диаграмм PIE. Каждый из них охватывает одну и ту же тему данных и может иметь одинаковые элементы среза. Однако не все предметы легенды появляются в обоих PIE все время. Я рассмотрел несколько решений этого (это one является самым близким). Однако он ломается, когда один из PIE не имеет всех срезов, которые есть у другого.Как слить легенды высоких карт со всеми уникальными записями

Испытательный кейс jsFiddle показывает, что первый PIE не имеет среза 'Engineering', а второй PIE. Но это означает, что элемент не отображается в легенде. Как я могу получить все уникальные записи в каждой легенде PIE в одной легенде?

Это текущая функция обратного вызова (обратите внимание, он основан на серии [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

Вы должны получить массив, содержащий имена уникальных точек (это будет легенда), то перебирать элементы в легенде и устанавливать соответствующие события.

Мое предложение ниже для вашего тестового примера (например, оно не принимает во внимание связанную серию).

Вот обертка метода 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/

Цвета ломтики не будут соответствовать для таких пирогов - но это может быть достигнуто путем установления тех же цветов для точек , Также, когда элемент в легенде завис, отображается только точка в одной серии - это может быть достигнуто путем установки состояния точки a в событии mouseouver/mouseout (аналогично тому, как это делается при обратном вызове нагрузки).

+0

Хорошо, это работает. Я устанавливаю цвета вручную, поэтому не нужно беспокоиться о разъединении в серии. Я могу справиться с зависанием. Большое спасибо. – wergeld

Смежные вопросы