将鼠标悬停在相应的图例项目上时突出显示图表元素

时间:2017-03-02 20:44:39

标签: javascript jquery chart.js

当我将鼠标悬停在相应的图例项目上时,我试图在Charts.js(版本2.5)中使用我的饼图突出显示相应的切片。

我有以下代码绑定mouseover / mouseout事件并调用我的函数,但我无法弄清楚如何突出显示相应的切片。

// Function to bind mouseover/mouseout events
Chart.helpers.each(document.getElementById('legendID').firstChild.childNodes, function(legendNode, index) {
    Chart.helpers.addEvent(legendNode, 'mouseover', function() {
        highlightActiveSegment(myChart,index,true);
    });
    Chart.helpers.addEvent(legendNode, 'mouseleave', function() {
        highlightActiveSegment(myChart,index,false);
    });
});


// And the corresponding function highlightActiveSegment
function highlightActiveSegment(oChart,segmentIndex,highlight) {
    var activeSegment = oChart.data.datasets[0]._meta[1].controller._data[segmentIndex];
    window.chartAccidentsByRoadConditions.data.datasets[0]._meta[1].controller.setHoverStyle(activeSegment);
    /*
    if (highlight) {
        oChart.data.datasets[0].controller.setHoverStyle(segmentIndex);
    } else {
        oChart.data.datasets[0].controller.removeHoverStyle(segmentIndex);
    }
    */
}

有人可以告诉我如何根据ChartsJS 2.5上方悬停的图例项触发setHoverStyle和removeHoverStyle方法

我创建了一个显示问题的JSFiddle。正如您将在示例中看到的,由于未定义showHoverStyle和removeHoverStyle,将鼠标悬停在图例项上时控制台中存在错误。看来当前在线的ChartJS文档不是最新的。

完整示例



var chartAccidentsByRoadConditionsClasses =  new Array();
chartAccidentsByRoadConditionsClasses[0] = "Dry";
chartAccidentsByRoadConditionsClasses[1] = "Not Available";
chartAccidentsByRoadConditionsClasses[2] = "Wet";
chartAccidentsByRoadConditionsClasses[3] = "Icy";
var chartAccidentsByRoadConditionsLabels =  new Array();
chartAccidentsByRoadConditionsLabels[0] = "Dry";
chartAccidentsByRoadConditionsLabels[1] = "Not Available";
chartAccidentsByRoadConditionsLabels[2] = "Wet";
chartAccidentsByRoadConditionsLabels[3] = "Icy";
var chartAccidentsByRoadConditionsData =  new Array();
chartAccidentsByRoadConditionsData[0] = 31;
chartAccidentsByRoadConditionsData[1] = 3;
chartAccidentsByRoadConditionsData[2] = 3;
chartAccidentsByRoadConditionsData[3] = 1;

var dataAccidentsByRoadConditions = {
	labels: chartAccidentsByRoadConditionsLabels,
	datasets: [{
		data: chartAccidentsByRoadConditionsData,
		backgroundColor: [ "#82a8c3","#b24339","#053454","#77954b" ],
		hoverBackgroundColor: [ "#7597AF","#A03C33","#042E4B","#6B8643" ]
	}]
};

$(document).ready(function() {
	var canvasAccidentsByRoadConditions = document.getElementById("chart-AccidentsByRoadConditions").getContext("2d");
	var chartAccidentsByRoadConditions = new Chart(canvasAccidentsByRoadConditions, {
		type: 'pie',
		data: dataAccidentsByRoadConditions,
		options: {	
			tooltips: {
				enabled: false
			},
			legend: {						
				display:false
			},
			legendCallback: function(chart) {	
				var text = [];
				text.push('<ul>');
				for (var i=0; i<chart.data.datasets[0].data.length; i++) {
					text.push('<li>');
					text.push('<div class="legendValue"><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
					text.push(chart.data.datasets[0].data[i] + '</span></div>');
					text.push('<div class="legendLabel">');
					if (chart.data.labels[i]) { text.push('<p class="label">' + chart.data.labels[i] + '</p>'); }
					if (chart.data.datasets[0].data[i]) { 
						text.push('<p class="percentage">' + chartValueToPercentage(chart.data.datasets[0].data[i],chartAccidentsByRoadConditions.getDatasetMeta(0).total) + '</p>'); 
					}
					text.push('</li>');
				}
				text.push('</ul>');
				return text.join("");
			}
		}
	});

	// Create our legend
	$('#legend-AccidentsByRoadConditions').prepend(chartAccidentsByRoadConditions.generateLegend());

	// Bind our "Break-Out" Chart function
	$('#chart-AccidentsByRoadConditions').on('mousemove mouseout',function(e){
		var activeSegment = chartAccidentsByRoadConditions.getElementAtEvent(e);
		pieChartHoverBreakout(this,activeSegment,e);
	});

	// Tie the legend to the chart tooltips				
	Chart.helpers.each(document.getElementById('legend-AccidentsByRoadConditions').firstChild.childNodes, function(legendNode, index) {
		Chart.helpers.addEvent(legendNode, 'mouseover', function() {
			highlightActiveSegment(chartAccidentsByRoadConditions,index,true);
		});
		Chart.helpers.addEvent(legendNode, 'mouseleave', function() {
			highlightActiveSegment(chartAccidentsByRoadConditions,index,false);
		});
	});					
});

function chartValueToPercentage(value,total) {
	return Math.floor(((value/total)*100)+0.5) + '%';
}

// Function breakout the active "legend item" PieCharts
currentBreakoutIndex = null;
function pieChartHoverBreakout(oChart, activeSegment, eventType) {		
	try {	
		// First, remove any existing classes with "breakout" from the legend
		var legend = ($(oChart).parent('.chartContainer').find('.legend'));	
		var segmentIndex = (activeSegment.length && (typeof activeSegment[0]._index != 'undefined' && activeSegment[0]._index !== null)) ? activeSegment[0]._index : -1;
		var breakout = (eventType.type === 'mousemove') ? true : false;
		if (currentBreakoutIndex != segmentIndex) {
			$.each(legend.find('li'), function(index,value) {
				$(this).removeClass('breakout');
			});
			// Second, if we have a valid segment index and breakout is true
			// we add the breakout class to the corresponding li in the legend
			if (breakout && segmentIndex >= 0) {
				currentBreakoutIndex = segmentIndex;
				var targetSegment = legend.find('li').get(segmentIndex);//
				$(targetSegment).addClass('breakout');			
			} else {
				currentBreakoutIndex = null;
			}
		}
	} catch(e) {
		// Nothing - just prevent errors in console
		console.log(e);
	}
}

function highlightActiveSegment(oChart,segmentIndex,highlight) {
  var activeSegment = oChart.data.datasets[0]._meta[0].controller._data[segmentIndex];

  if (highlight) {
    oChart.data.datasets[0].controller.setHoverStyle(activeSegment);
  } else {
    oChart.data.datasets[0].controller.removeHoverStyle(activeSegment);
  }
}
&#13;
#dashboardWrapper h2 { 
	display:block; 
	text-align:left; 
	margin-bottom:0px; 
	margin-left: 20px; 
	margin: 5px 0px 20px 0px; 
	line-height: 1.2;
}
#dashboardWrapper .chart {
  float:left;
	width:50%;
	vertical-align:middle;
	display:inline-block;
  width:50% !important;
  height:100% !important;	
}
#dashboardWrapper .legend {
	float:left;
	width:50%;
	margin-bottom: 25px;
}
#dashboardWrapper .legendInfo {
  background-color: #EBEBEB;
  display: inline-block;
  padding: 0px 10px 5px 10px;
  border-radius: 10px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;	
  box-shadow: 0px 0px 5px #888;
}
#dashboardWrapper .legendInfo span {
  display: block;
  font-size: 12px;    
  margin-top: 5px;	
}
#dashboardWrapper .chart
{
	margin-bottom: 25px;	
}
#dashboardWrapper .chartContainer { padding: 20px 0px; }
#dashboardWrapper .chartContainer ul {
	background:none;	
}				
#dashboardWrapper .chartContainer li {
	background:none;
	margin:0;
	padding:0;
	border:none;
	color: #666666;
	font-size: 16px;
	font-family: 'Source Sans Pro', sans-serif;
	font-weight: 400;
	list-style-type: none;				
}
#dashboardWrapper .chartContainer li span {
  background-color: #791b15;
  height: 20px;
  min-width: 20px;
  padding: 2px 3px;
  display: inline-block;
  vertical-align: middle;
  border-radius: 5px;
  margin-right: 10px;
  color:#FFF;
  text-align:center;
  font-size: 12px;
  line-height: 18px;
  text-shadow: 1px 1px 2px #000;
}
#dashboardWrapper div.legendValue { float:left; width:20%; }
#dashboardWrapper div.legendLabel { float:left; width:80%; }
#dashboardWrapper p.label {
	display:inline-block;
	margin:0;
	margin-right:10px;
	padding:0;
	vertical-align:middle;
}
#dashboardWrapper p.percentage {
	display:inline-block;
	margin:0;
	padding:0;
	vertical-align:middle;	
}
#dashboardWrapper .dashboardElement
{
  display:inline-block; 
  min-height: 350px;
  float: left; 
  padding: 0px 20px 0px 2%;
  margin: 0px;
  -webkit-transform-origin: 0 0;
  -moz-transform-origin: 0 0;
  -o-transform-origin: 0 0;
  -ms-transform-origin: 0 0;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  -ms-transition: all 0.3s;
  -o-transition: all 0.3s;
  transition: all 0.3s;
}

#dashboardWrapper .chartContainer li 
{
    background: none;
    margin: 0 0 0 0;
  	padding:  0px 0px 5px 0px;
    border: none;
    font-family: 'News Cycle', sans-serif;
    font-size: 12px;
	  white-space: nowrap;    
	  cursor:pointer;
    float: right;
    display: inline;
    width: 94%;  
}

.chartContainer .legend ul li { 
  position:relative; 
  -webkit-transform-origin: 0 0;
  -moz-transform-origin: 0 0;
  -o-transform-origin: 0 0;
  -ms-transform-origin: 0 0;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  -ms-transition: all 0.3s;
  -o-transition: all 0.3s;
  transition: all 0.3s;	
  left:0px;
}
.chartContainer .legend ul li.breakout { 
	left:-10px; 
}
&#13;
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.5.0/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dashboardWrapper">
  <div class="dashboardElement right">
      <h2>Accidents by Road Conditions</h2>		
      <div class="chartContainer" style="position:relative;">
        <canvas id="chart-AccidentsByRoadConditions" class="chart" width="200" height="150"></canvas>
        <div id="legend-AccidentsByRoadConditions" class="legend"></div>            
      </div>                                                           
  </div>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

看起来你的// Stop *all* buffering while (ob_get_level()) { ob_end_clean(); } // Set headers using PHP functions instead of Response header('Content-Type: application/x-download'); header('X-Content-Type-Options: nosniff'); header('Content-Length: ' . filesize($filename)); header('Content-Disposition: attachment; filename="whatever.zip"'); die(readfile($filename)); 函数和图例事件处理程序中只有一些问题。这是一个带有解释的更正版本。

已修改的图例事件处理程序

您需要使用highlightActiveSegment代替mousemove,以便在用户移动鼠标时该部分保持突出显示。

mouseover

修改后的Chart.helpers.each(document.getElementById('legend-AccidentsByRoadConditions').firstChild.childNodes, function(legendNode, index) { Chart.helpers.addEvent(legendNode, 'mousemove', function() { highlightActiveSegment(chartAccidentsByRoadConditions, index, true); }); Chart.helpers.addEvent(legendNode, 'mouseleave', function() { highlightActiveSegment(chartAccidentsByRoadConditions, index, false); }); }); 功能

基本上,关键是要确保你获得了被模拟的传奇项目所代表的图形的实际部分,相应地设置悬停样式并重新渲染图表。

highlightActiveSegment

此外,这里有一个显示工作解决方案的codepen

答案 1 :(得分:0)

color: [
  {
    backgroundColor: ['#92d06f', '#73c8b8', '#3bb9ab'],
    borderColor: 'rgba(255, 255, 255, 0)',
    hoverBackgroundColor: ['#92d06f', '#73c8b8', '#3bb9ab'],
    hoverBorderColor: ['#92d06f', '#73c8b8', '#3bb9ab'],
    hoverBorderWidth: 10,
    hoverRadius: 0

}     ],

鼠标悬停上的

突出显示角度2(ng-2图表)中的活动段,用于圆环图