最近项目中在用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;
}
}
);
}