最近项目中在用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; }
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"] };
确认没有问题。
以上都没有问题,此时已经束手无策了……
今天早上一来,找了一个正常的折线图,跟我的代码进行了一一比较,发现也没有任何问题。在比较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; } } ); }