2017-09-05 48 views
1

我有餅圖2系列。當兩者都可見時,標題將在圖表內顯示「總計」值。懸停 - 「詳細」值。更改餅圖標題取決於可見的系列

現在,當系列中的一個不可見時,我需要顯示「詳細」標題而不是「總計」。

下面是一些演示:http://jsfiddle.net/jrvm4b6v/7/

我不知道如何禁用一個系列或legendItemClick同時啓用,因爲我前點擊接收狀態後,顯示「詳細」的價值...


$(document).ready(function() { 

    Highcharts.chart('container', { 
    chart: { 
     plotBackgroundColor: null, 
     plotBorderWidth: null, 
     plotShadow: false, 
     type: 'pie', 
     borderRadius: 0, 
     width: 1200, 
     height: 250, 
     backgroundColor: '#fff', 
     marginTop: 0, 
     marginRight: 950, 
     spacingTop: 0, 
     spacingBottom: 0, 
     spacingLeft: 0, 
     events: { 
     load: function(event) { 

      this.setTitle({ 
      text: generateChartText(true, this), 
      x: -468, 
      y: 124 
      }); 
     } 
     } 
    }, 
    legend: { 
     useHTML: true, 
     layout: 'vertical', 
     verticalAlign: 'top', 
     x: 0, 
     y: 40, 
     itemMarginBottom: 30, 
     labelFormatter: function() { 
     var description = this.name === 'Direct' ? 'Customers who use Chrome' : 'Customers who use Firefox'; 

     return '<div class="img"></div><div><span>' + this.name + '</span><br>' + '<p style="font-size: 13px; color: #666666;">' + description + '</p>' + '</div>'; 
     } 
    }, 
    title: { 
     text: 'Browser market shares January, 2015 to May, 2015' 
    }, 
    tooltip: { 
     pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' 
    }, 
    plotOptions: { 
     pie: { 
     allowPointSelect: true, 
     cursor: 'pointer', 
     dataLabels: { 
      enabled: false 
     }, 
     showInLegend: true, 
     borderWidth: 2, 
     startAngle: 0, 
     innerSize: '58%', 
     allowPointSelect: false, 
     dataLabels: false, 
     stickyTracking: false, 
     states: { 
      hover: { 
      enabled: false 
      } 
     }, 
     point: { 
      events: { 
      mouseOver: function(event) { 
       this.series.chart.setTitle({ 
       text: generateChartText(false, this), 
       x: -470, 
       y: 113 
       }); 
       $('.highcharts-title', $('#container')).addClass(this.name.toLowerCase()); 
      }, 
      mouseOut: function(event) { 

       var someSeriesAreHidden = this.series.data.some(function(dataItem) { 

        return dataItem.hasOwnProperty('visible') && !dataItem.visible; 
       }), 
       xVal = someSeriesAreHidden ? -470 : -468, 
       yVal = someSeriesAreHidden ? 113 : 124; 
       this.series.chart.setTitle({ 
       text: generateChartText(!someSeriesAreHidden, this.series.chart), 
       x: xVal, 
       y: yVal 
       }); 

       var highchartsTitle = $('.highcharts-title', $('#container')); 
       highchartsTitle.removeClass(); 
       highchartsTitle.addClass('highcharts-title'); 
      }, 
      legendItemClick: function() { 

       var $legend = $(this.legendGroup.div); 

       $legend.hasClass('disable') ? $legend.removeClass('disable') : $legend.addClass('disable'); 

       var someSeriesAreHidden = this.series.data.some(function(dataItem) { 
        return dataItem.hasOwnProperty('visible') && !dataItem.visible; 
       }), 
       xVal = someSeriesAreHidden ? -470 : -468, 
       yVal = someSeriesAreHidden ? 113 : 124; 

       this.series.chart.setTitle({ 
       text: generateChartText(!someSeriesAreHidden, this.series.chart), 
       x: xVal, 
       y: yVal 
       }); 
      } 
      } 
     } 
     } 
    }, 
    series: [{ 
     name: 'Brands', 
     colorByPoint: true, 
     data: [{ 
     name: 'Chrome', 
     y: 24.03, 
     searches: 1000 
     }, { 
     name: 'Firefox', 
     y: 10.38, 
     searches: 3000 
     }] 
    }] 
    }); 
}); 

function generateChartText(isTotal, chart) { 
    var series = chart.series[0], 
    totalSearches = isTotal ? series.data[0].searches + series.data[1].searches : chart.searches/chart.y * 100; 
    chart = Array.isArray(chart.series) ? (series.data[0].visible ? series.data[0] : series.data[1]) : chart; 
    var textForSerie = '<span style="font-size: 13px;font-weight:normal;">' + chart.name + '</span><br>' + '<span style="fill: #797979;">' + parseInt(chart.searches, 10) + '</span><br><span>' + chart.y + '%</span><br>'; 
    var textForTotal = '<span style="font-size: 13px;font-weight:normal;">Total Searches' + '</span>' + '<br>' + '<span style="fill: #797979;">' + parseInt(totalSearches, 10) + '</span>'; 

    return isTotal ? textForTotal : textForSerie; 
} 
+0

只需使用簡單的條件(線107-110)隱藏系列。例如:http://jsfiddle.net/6xkf57je/。 –

+0

如果兩者都關閉,那麼你打開一個錯誤的標題 – demo

回答

0

這是我的工作例如:JsFiddle

感謝@ rphv給了我一些新的想法。

主要問題是在legendItemClick點擊系列的狀態沒有改變這個事件。

所以我可以收到點擊的系列,它是以前的狀態(可見真或假),並依賴於此預測系列的下一個狀態。

function filterHiddenSeries(event) { 
    return function(dataItem, index) { 
    return (dataItem.hasOwnProperty('visible') && !dataItem.visible && event.target.index !== index) || (event.target.index === index && event.target.visible); 
    } 
} 

這是函數返回上legendItemClick

0

這裏是一個可能的策略:

  • 保存Highcharts.chart() OBJE CT在一個全局變量在legendItemClick()處理
  • ,使用點擊的目標來選擇數據系列是從全球chart變量
  • 傳遞未獲得點擊的generateChartText()函數的數據系列點擊。

這裏是你的代碼稍加修改,做這一點 - 有修改接近評論:

var chart; 
 
$(document).ready(function() { 
 

 
    // save the base chart object in a variable so any data series can be accessed on a click event 
 
    chart = Highcharts.chart('container', { 
 
    chart: { 
 
     plotBackgroundColor: null, 
 
     plotBorderWidth: null, 
 
     plotShadow: false, 
 
     type: 'pie', 
 
     borderRadius: 0, 
 
     width: 1200, 
 
     height: 250, 
 
     backgroundColor: '#fff', 
 
     marginTop: 0, 
 
     marginRight: 950, 
 
     spacingTop: 0, 
 
     spacingBottom: 0, 
 
     spacingLeft: 0, 
 
     events: { 
 
     load: function(event) { 
 

 
      this.setTitle({ 
 
      text: generateChartText(true, this), 
 
      x: -468, 
 
      y: 124 
 
      }); 
 
     } 
 
     } 
 
    }, 
 
    legend: { 
 
     useHTML: true, 
 
     layout: 'vertical', 
 
     verticalAlign: 'top', 
 
     x: 0, 
 
     y: 40, 
 
     itemMarginBottom: 30, 
 
     labelFormatter: function() { 
 
     var description = this.name === 'Direct' ? 'Customers who use Chrome' : 'Customers who use Firefox'; 
 

 
     return '<div class="img"></div><div><span>' + this.name + '</span><br>' + '<p style="font-size: 13px; color: #666666;">' + description + '</p>' + '</div>'; 
 
     } 
 
    }, 
 
    title: { 
 
     text: 'Browser market shares January, 2015 to May, 2015' 
 
    }, 
 
    tooltip: { 
 
     pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' 
 
    }, 
 
    plotOptions: { 
 
     pie: { 
 
     allowPointSelect: true, 
 
     cursor: 'pointer', 
 
     dataLabels: { 
 
      enabled: false 
 
     }, 
 
     showInLegend: true, 
 
     borderWidth: 2, 
 
     startAngle: 0, 
 
     innerSize: '58%', 
 
     allowPointSelect: false, 
 
     dataLabels: false, 
 
     stickyTracking: false, 
 
     states: { 
 
      hover: { 
 
      enabled: false 
 
      } 
 
     }, 
 
     point: { 
 
      events: { 
 
      mouseOver: function(event) { 
 
       console.log(this) 
 
       this.series.chart.setTitle({ 
 
       text: generateChartText(false, this), 
 
       x: -470, 
 
       y: 113 
 
       }); 
 
       $('.highcharts-title', $('#container')).addClass(this.name.toLowerCase()); 
 
      }, 
 
      mouseOut: function(event) { 
 

 
       var someSeriesAreHidden = this.series.data.some(function(dataItem) { 
 

 
        return dataItem.hasOwnProperty('visible') && !dataItem.visible; 
 
       }), 
 
       xVal = someSeriesAreHidden ? -470 : -468, 
 
       yVal = someSeriesAreHidden ? 113 : 124; 
 
       this.series.chart.setTitle({ 
 
       text: generateChartText(!someSeriesAreHidden, this.series.chart), 
 
       x: xVal, 
 
       y: yVal 
 
       }); 
 

 
       var highchartsTitle = $('.highcharts-title', $('#container')); 
 
       highchartsTitle.removeClass(); 
 
       highchartsTitle.addClass('highcharts-title'); 
 
      }, 
 
      legendItemClick: function(event) { 
 
       var $legend = $(this.legendGroup.div); 
 

 
       $legend.hasClass('disable') ? $legend.removeClass('disable') : $legend.addClass('disable'); 
 

 
       var someSeriesAreHidden = this.series.data.some(function(dataItem) { 
 
        return dataItem.hasOwnProperty('visible') && !dataItem.visible; 
 
       }), 
 
       xVal = someSeriesAreHidden ? -470 : -468, 
 
       yVal = someSeriesAreHidden ? 113 : 124; 
 

 
       // pass the series that was *not* clicked to generateChartText() 
 
       this.series.chart.setTitle({ 
 
       text: generateChartText(false, event.target.name == "Chrome" ? chart.series[0].data[1] : chart.series[0].data[0]), 
 
       x: -470, 
 
       y: 113 
 
       }); 
 
       // update the chart text 
 
       $('.highcharts-title', $('#container')).addClass(this.name.toLowerCase()); 
 
      } 
 
      } 
 
     } 
 
     } 
 
    }, 
 
    series: [{ 
 
     name: 'Brands', 
 
     colorByPoint: true, 
 
     data: [{ 
 
     name: 'Chrome', 
 
     y: 24.03, 
 
     searches: 1000 
 
     }, { 
 
     name: 'Firefox', 
 
     y: 10.38, 
 
     searches: 3000 
 
     }] 
 
    }] 
 
    }); 
 
}); 
 

 
function generateChartText(isTotal, chart) { 
 
    var series = chart.series[0], 
 
    totalSearches = isTotal ? series.data[0].searches + series.data[1].searches : chart.searches/chart.y * 100; 
 
    chart = Array.isArray(chart.series) ? (series.data[0].visible ? series.data[0] : series.data[1]) : chart; 
 
    var textForSerie = '<span style="font-size: 13px;font-weight:normal;">' + chart.name + '</span><br>' + '<span style="fill: #797979;">' + parseInt(chart.searches, 10) + '</span><br><span>' + chart.y + '%</span><br>'; 
 
    var textForTotal = '<span style="font-size: 13px;font-weight:normal;">Total Searches' + '</span>' + '<br>' + '<span style="fill: #797979;">' + parseInt(totalSearches, 10) + '</span>'; 
 

 
    return isTotal ? textForTotal : textForSerie; 
 
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> 
 
<script src="https://code.highcharts.com/highcharts.js"></script> 
 
<script src="https://code.highcharts.com/modules/exporting.js"></script> 
 

 
<div id="container" style="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div>