更改饼图标题取决于可见系列



我有 2 个系列的饼图。当两者都可见时,标题在图表内显示"总计"值。悬停时 - "详细"值。

现在,当系列中的一个不可见时,我需要显示"详细"标题而不是"总计"。

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

我不知道如何在禁用一个系列或同时启用两个系列后显示"详细"值,因为在图例项目单击我在单击之前收到状态...


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

这里有一个可能的策略:

  • Highcharts.chart()对象保存在全局变量中
  • 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>

这是我的工作示例:

谢谢@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上返回隐藏序列的函数

最新更新