Flot plothover事件绑定后,获取item一直为null、数据混乱的问题

最近项目中在用Flot制作折线图和柱状图,Ajax获取数据,图表能够正常显示,但是在实现鼠标移动后进行提示的功能时,始终无法正常显示提示信息。google里各种查阅相关资料,还是未能解决问题。最后不得已,只能照着一个Flot官方最简单的sin和cos的折线图进行排查,终于发现问题,故总结如下,以免忘记。

最终的效果:


由于开发阶段,数据没有准备齐全,故看起来比较单调。

这里仅以折线图为例,说明我在解决问题的步骤:

1、检查数据:

打印ajax获取到的数据格式,确认没有问题:

获取数据的方法:

function getTestPercent() {
	var url = Util.getContentPath() + "/tt/getPercent.do";
	var tmp = [];
	getPercent(url, tmp);
	return tmp;
}

function getPercent(url, percent) { 
	$.ajax({
		type : "post",
		dataType : "json",
		async : false,
		url : url,
		success : function (data) {
			json = eval(data);
			for (var i = 0; i < 12; i++) { // 一共12个月
				if (!json[i])
					percent.push([i, 0]);
				else 
					percent.push([i, json[i]]);
			}
		}, error : function () {
//			Error("获取数据失败!");
		}
	});
}

function getStudyPlanPercent(percent) {
	var url = Util.getContentPath() + "/spt/getPercent.do";
	var tmp = [];
	getPercent(url, tmp);
	return tmp;
}

准备数据到datasource:

var test = getTestPercent();
	var studyplan = getStudyPlanPercent();
	
	var ds = [ 
		{ data : test, label : "Test"},
		{ data : studyplan, label : "Study Plan"}
	];
用console.debug打印出test和studyplan,确认没有问题。

2、检查参数设置:

var options = {	
		series: {
	        lines: {show: true},
	        points: {show: true}
	    },
		grid: {hoverable: true, clickable: true},
		yaxis : {
			axisLabel: "Percent",
	                axisLabelUseCanvas: true,
	                axisLabelFontSizePixels: 12,
         	        axisLabelFontFamily: 'Verdana, Arial',
	                axisLabelPadding: 3,
			ticks : [[0, "0"], [0.2, "20%"], [0.4, "40%"], [0.6, "60%"], [0.8, "80%"], [1, "100%"]]
		},
		xaxis : {
			axisLabel: "Month",
	                axisLabelUseCanvas: true,
	                axisLabelFontSizePixels: 12,
	                axisLabelFontFamily: 'Verdana, Arial',
	                axisLabelPadding: 10,
			ticks : [[0, "Jan"], [1, "Feb"], [2, "Mar"],
					[3, "Apr"], [4, "May"], [5, "Jun"],
					[6, "Jul"], [7, "Aug"], [8, "Sep"],
					[9, "Oct"], [10, "Nov"], [11, "Dec"]]
		},
	//	legend: {
	//        noColumns: 0,
	//        labelBoxBorderColor: "#000000",
	//        position: "nw"
	//    },
		colors : ["#F90", "#3C4049", "#666", "#BBB"]
	};

具体画折线图的方法及相信参数请参看:http://www.jqueryflottutorial.com/cn/how-to-make-jquery-flot-line-chart.html

确认没有问题。

以上都没有问题,此时已经束手无策了……

今天早上一来,找了一个正常的折线图,跟我的代码进行了一一比较,发现也没有任何问题。在比较css的时候,突然想起可以去看看生成图表的css样式,看看是否是CSS引起的问题,由于本人对CSS不是很熟悉,故一时半会真没想到这个点,此时感觉告诉我,问题很有可能出在css问题上,于是查看生成的折线图的html:

<canvas class="base" width="623" height="350"></canvas>
<canvas class="overlay" width="623" height="350" style="position: absolute; left: 0px; top: 0px;"></canvas>
可以看到,该图标的css为overlay,是不是由于这个css有冲突呢?于是查找整个项目的css文件,果然在loading加载动画的css里边找到了这个问题的罪魁祸首:

.overlay {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 998;
	width: 100%;
	height: 100%;
	_padding: 0 20px 0 0;
	background: #f6f4f5;
	display: none;
}
于是修改这个css的名字,在重新查看问题,问题得到解决……


ps:身为Java程序员,不光是能够了解Java的相关技术,javascript、Css、数据都需要全面去了解掌握,由于本人对CSS非常不熟悉,才导致半天没找到问题所在,饶了很大弯路,悲哀啊……

完整js代码:

折线图:

function getTestPercent() {
	var url = Util.getContentPath() + "/tt/getPercent.do";
	var tmp = [];
	getPercent(url, tmp);
	return tmp;
}

function getPercent(url, percent) { 
	$.ajax({
		type : "post",
		dataType : "json",
		async : false,
		url : url,
		success : function (data) {
			json = eval(data);
			for (var i = 0; i < 12; i++) { // 一共12个月
				if (!json[i])
					percent.push([i, 0]);
				else 
					percent.push([i, json[i]]);
			}
		}, error : function () {
//			Error("获取数据失败!");
		}
	});
}

function getStudyPlanPercent(percent) {
	var url = Util.getContentPath() + "/spt/getPercent.do";
	var tmp = [];
	getPercent(url, tmp);
	return tmp;
}

$(function () {
	var test = getTestPercent();
	var studyplan = getStudyPlanPercent();
	
	var ds = [ 
		{ data : test, label : "Test"},
		{ data : studyplan, label : "Study Plan"}
	];
    
	var options = {	
		series: {
	        lines: {show: true},
	        points: {show: true}
	    },
		grid: {hoverable: true, clickable: true},
		yaxis : {
			axisLabel: "Percent",
	        axisLabelUseCanvas: true,
	        axisLabelFontSizePixels: 12,
	        axisLabelFontFamily: 'Verdana, Arial',
	        axisLabelPadding: 3,
			ticks : [[0, "0"], [0.2, "20%"], [0.4, "40%"], [0.6, "60%"], [0.8, "80%"], [1, "100%"]]
		},
		xaxis : {
			axisLabel: "Month",
	        axisLabelUseCanvas: true,
	        axisLabelFontSizePixels: 12,
	        axisLabelFontFamily: 'Verdana, Arial',
	        axisLabelPadding: 10,
			ticks : [[0, "Jan"], [1, "Feb"], [2, "Mar"],
					[3, "Apr"], [4, "May"], [5, "Jun"],
					[6, "Jul"], [7, "Aug"], [8, "Sep"],
					[9, "Oct"], [10, "Nov"], [11, "Dec"]]
		},
	//	legend: {
	//        noColumns: 0,
	//        labelBoxBorderColor: "#000000",
	//        position: "nw"
	//    },
		colors : ["#F90", "#3C4049", "#666", "#BBB"]
	};
	
	var plot = $.plot($("#line-chart"), ds, options);
	var previousPoint = null, previousLabel = null;
	var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    $("#line-chart").bind("plothover", function (event, pos, item) {
        if (item) {
            if ((previousLabel != item.series.label) || (previousPoint != item.dataIndex)) {
                previousPoint = item.dataIndex;
                previousLabel = item.series.label;
                $("#tooltip").remove();
                  
                var x = item.datapoint[0];
                var y = item.datapoint[1];

                var color = item.series.color;
                //console.log(item);
                showTooltip(item.pageX,
                    item.pageY,
                    color,
                    "<strong>" + item.series.label + "</strong><br>" + monthNames[x] + " : <strong>" + y + "</strong> (%)");
            }
        } else {
            $("#tooltip").remove();
            previousPoint = null;
        }
	});
});

function showTooltip(x, y, color, contents) {
    $('<div id="tooltip">' + contents + '</div>').css({
        position: 'absolute',
        display: 'none',
        top: y - 5,
        left: x + 5,
        border: '2px solid' + color,
        padding: '3px',
        'font-size': '9px',
        'border-radius': '5px',
        'background-color': '#fff',
        'font-family': 'Verdana, Arial, Helvetica, Tahoma, sans-serif',
        opacity: 0.8
    }).appendTo("body").fadeIn(200);
}

柱状图:

$(function () {
	count();
	$("#countTypeSel").change(function () {
		count();
	});
	$("#selectMonth").change(function () {
		count();
	});
});

function getShowData (url, data, month) {
	var json = null;
	$.ajax({
		type : "post",
		dataType : "json",
		async : false,
		url : url,
		data : data,
		success : function (data) {
			json = eval(data);
		}
	});
	return json;
}

function count() {
	// x轴标签,默认显示5个
	var ticks = [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]];
	// 需要呈现的数据
	var data = [];
	
    // 从后到获取显示的数据
    var isTest = false;
    var url = Util.getContentPath() + "/spt/getEachPercent.do";
    if ($("#countTypeSel").val() == "1") {
	    isTest = true;
	    url = Util.getContentPath() + "/tt/getEachPercent.do";
    }
    var month = $("#selectMonth").val();
    var p = {month : 1};
    var json = getShowData(url, p, month);
    
    // 解析获取到的数据
    var dataArray = [];
    var ticksTmp = [];
    for (var i = 0; i < json.length; i++) {
		var m = json[i]; // test : test , percent : percent
		dataArray.push(m);
		ticksTmp.push([i + 1, i + 1]);
	}
	
    for (var i = 0; i < dataArray.length; i++) {
    	data.push([i + 1, dataArray[i].percent]);
    }
    // 默认显示5个,不足补0
    if (dataArray.length < 5) {
    	for (var i = 1; i <= (5 - dataArray.length); i++) {
		    data.push([data.length + 1, 0]);
    	}	
    } else {
    	ticks.push(ticksTmp);
    }
    
 	var bars = {
		show : true,
		align: "left",
		barWidth : 0.2,
		order : 1,
		lineWidth : 0.2,
		fillColor : {
			colors : [{
					opacity : 0.65
				}, {
					opacity : 1
				}]
		}
 	};
 	var grid = {
 		hoverable : true
 	};
 	var ds = [{label : "Percent", data : data}];
 	var options = {
 		series: {
	        bars: {
	            show: true
	        }
	    },
	    bars : bars,
	    grid : grid,
 		colors: ["#F90", "#3C4049", "#666", "#BBB"],
        xaxis: {
        	axisLabel: "Test / Study Plan ",
            axisLabelUseCanvas: true,
            axisLabelFontSizePixels: 12,
            axisLabelFontFamily: 'Verdana, Arial',
            axisLabelPadding: 10,
 			ticks: ticks
        }, 
		yaxis: {
			axisLabel: "Percent",
            axisLabelUseCanvas: true,
            axisLabelFontSizePixels: 12,
            axisLabelFontFamily: 'Verdana, Arial',
            axisLabelPadding: 3,
	    	ticks: [[0, "0"],[0.2, "20%"],[0.4, "40%"],[0.6, "60%"],[0.8, "80%"],[1, "100%"]]}
//	    legend: {
//            noColumns: 0,
//            labelBoxBorderColor: "#000000",
//            position: "nw"
//       	}	
 	};
    
    var tips = "";
    for (var i = 0; i < dataArray.length; i++) {
		$("#s-bar-chart").find(".tickLabel").each(function (j,v){
			if(j == i) {
				if (isTest)
					tips = dataArray[i].test.name;
				else 
					tips = dataArray[i].sp.name;
				$(this).tooltip({title : "name : " + tips});
				return;
			}
		});
    }
    
    $.plot($("#s-bar-chart"), ds, options);
    
    var previousPoint = null, previousLabel = null;
	$("#s-bar-chart").bind("plothover", function (event, pos, item) {
			if (item) {
			    if ((previousLabel != item.series.label) || (previousPoint != item.dataIndex)) {
			        previousPoint = item.dataIndex;
			        previousLabel = item.series.label;
			        $("#tooltip").remove();
			
				    var x = item.datapoint[0];
				    var y = item.datapoint[1];
				    //console.log(item.series.xaxis.ticks[x].label);                
				    var color = item.series.color;
				    var name = "";
				    if (isTest)
				    	name = "Test : " + dataArray[previousPoint].test.name;
				    else 
				    	name = "Study Plan : " + dataArray[previousPoint].sp.name;
				    var tips = "<strong>" + name + "</strong><br>" + item.series.label + " : <strong>" + y + "</strong> (%)";
				    showTooltip(item.pageX, item.pageY, color, tips);                
			    }
			} else {
			    $("#tooltip").remove();
			    previousPoint = null;
			}
		}
	);
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值