折线图是最常被使用的图形, 也是最容易绘制的图表, 它可以显示时间与趋势的走向, 将各项数据图表化, 让人可以对这些数字与时间的相对关系一目了然, 因为这是Flot教学里第一个图表, 我们会完整的呈现所有细节及过程. 本章里以2012年的黄金价格走势做为范例, 我们将会以每月黄金的价格以及变动率做为数据源
制作折线图流程
本章以下图折线图为范例
加入所需要的Flot档案
将绘制折线图所会用到的档案加到<head>里, 第一个最重要的就是jQuery.js需要放在第一位, 再来就是Flot主要的档案jquery.flot.js, 接下来因为我们绘制的是时间数据格式的图表, 所以也需要把jquery.flot.time.js加进来最后的2个档案和jquery.flot.axislabels.js皆是Flot的插件, Flot预设的数据点(data point)符号是圆型(circle), 因为我们有改变数据点符号, 所以需要加入jquery.flot.symbol.js, 另外, Flot本身并不支持轴标签的设置, 所以需要透过加入jquery.flot.axislabels.js插件来达成轴标签的设置.
以下程序代码就是此范例所会用到的全部档案
<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script> <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="/js/flot/excanvas.min.js"></script><![endif]--> <script type="text/javascript" src="/js/flot/jquery.flot.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.time.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.symbol.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.axislabels.js"></script>
HTML5 canvas支援
如果你是使用Internet Explorer, 且版本为8以下的, 浏览有用Flot绘制图表的网页可能无法正常观看, 因为这些浏览器不支持HTML5 canvas标签, 不过别担心, 只要加入ExplorerCanvas插件(excanvas.min.js)就可以让Internet Explorer也能正常显示Flot图表. 档案可以到此下载.加入定位点
准备好所需要的档案后, 接下来就是决定Flot要绘图的位置, 你可以自行决定Flot要在那里出现, 只要在<body>加上下面的<div>标签, 并给一个id, 后面要绘制时会用到此id. 另一个比较重要的是, 你必须设置定位点的长度和宽度, 如果没有设置就有可能发生Uncaught Invalid dimensions for plot, width = 0, height = 0的script错误.<div id="flot-placeholder" style="width:300px;height:150px"></div>
准备折线图所需资料
数据是绘图过程中最重要的部份, 数据不正确绘制出来的图就会不正确, 2012年的黄金价格及变动率数据如下//Gold Price var data1 = [ [gd(2012, 0, 1), 1652.21], [gd(2012, 1, 1), 1742.14], [gd(2012, 2, 1), 1673.77], [gd(2012, 3, 1), 1649.69], [gd(2012, 4, 1), 1591.19], [gd(2012, 5, 1), 1598.76], [gd(2012, 6, 1), 1589.90], [gd(2012, 7, 1), 1630.31], [gd(2012, 8, 1), 1744.81], [gd(2012, 9, 1), 1746.58], [gd(2012, 10, 1), 1721.64], [gd(2012, 11, 1), 1684.76] ]; //Change var data2 = [ [gd(2012, 0, 1), 0.63], [gd(2012, 1, 1), 5.44], [gd(2012, 2, 1), -3.92], [gd(2012, 3, 1), -1.44], [gd(2012, 4, 1), -3.55], [gd(2012, 5, 1), 0.48], [gd(2012, 6, 1), -0.55], [gd(2012, 7, 1), 2.54], [gd(2012, 8, 1), 7.02], [gd(2012, 9, 1), 0.10], [gd(2012, 10, 1), -1.43], [gd(2012, 11, 1), -2.14] ]; var dataset = [ { label: "Gold Price", data: data1, points: { symbol: "triangle"} }, { label: "Change", data: data2, yaxis: 2 } ];
data1格式如下
[gd(2012, 0, 1), 1652.21]
[1325347200000, 1652.21]
function gd(year, month, day) { return new Date(year, month, day).getTime(); }
最后我们再把这2组原始数据结合成一个数据组(dataset), 再分别设定标签(label)为"Gold Price"和"Change", 将data属性分别设为data1和data2, 在dataset里如果你不设定其它的属性也可以, 唯一不可缺少的就是data属性. 另外我们还设定了points属性, 把其中的symbol设为triangle, 表示数据点符号会以三角形呈现.
var dataset = [ { label: "Gold Price", data: data1, points: { symbol: "triangle"} }, //first data seires { label: "Change", data: data2, yaxis: 2 } //second data seires ];
自定义轴属性
到这里已经完成了80%的部份, 接下来这个部份就是美化你的图表, Flot提供了相当多的属性可以让你自定义图表的细节及外观, 在这我们先就轴的部份说明. 因为我们所绘制的图表是以x轴为时间格式, 当你用时间格式数据时, 就必须把轴属性里的mode设为"time", 设定之后Flot就会把该轴的数据当作时间来解读.另外还有刻度间隔大小(tickSize) tickSize能接受的值为数字或是数组, 当你设定为2时, 刻度会变成显示2, 4, 6, .., 设定为3时会变成显示3, 6, 9, ...依此类推, 当你设定成数组时, 如tickSize: [1, "month"], 刻度就会显示成月份如Jan, Feb, Mar, ..., 除了"month"外也可设定成"day"、"year"、"hour"等.
因为Flot本身不支持轴卷标功能, 所以在加入档案时也一并加入了jquery.flot.axislabels.js插件让Flot能支持,所谓的轴卷标就是在图表的四周显示的卷标文字,属性axisLabel用来设定卷标显示文字, axisLabelFontSizePixels可设定文字大小, axisLabelUseCanvas用来设定文字是否以Canvas方式绘制. 范例程序代码如下...
xaxis: { mode: "time", tickSize: [1, "month"], tickLength: 0, axisLabel: "2012", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 10 }, yaxes: [{ axisLabel: "Gold Price(USD)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3, tickFormatter: function (v, axis) { return $.formatNumber(v, { format: "#,###", locale: "us" }); } }, { position: "right", axisLabel: "Change(%)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3 } ]
xaxis: {}, yaxis: {}
xaxis: {}, yaxes: [ { //first yaxis },{ //second yaxis } ]
呼叫$.plot函式
当你完成了以上所有的工作, 来到这最后的部份是最简单的, 只需要呼叫$.plot并带入参数即可. 如果你不熟悉$.plot函式可到绘制你的第一个图表去回顾.绘制Flot图表其实没想象中的难, 只是需要时间去熟悉, 而绘制折线图是最好的开始, 后面的章节将会把其它的图表如柱形图、条形图、分区图等一一的介绍, 相信你会越来越驾轻就熟!
$(document).ready(function () { $.plot($("#flot-placeholder"), dataset, options); });
本章完整程序代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="/js/lib/jquery-1.8.3.min.js" type='text/javascript'></script> <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="/js/flot/excanvas.min.js"></script><![endif]--> <script type="text/javascript" src="/js/flot/jquery.flot.min.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.time.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.symbol.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.axislabels.js"></script> <script type="text/javascript" src="/js/flot/jshashtable-2.1.js"></script> <script type="text/javascript" src="/js/flot/jquery.numberformatter-1.2.3.min.js"></script> <script> //******* 2012 Gold Price Chart var data1 = [ [gd(2012, 0, 1), 1652.21], [gd(2012, 1, 1), 1742.14], [gd(2012, 2, 1), 1673.77], [gd(2012, 3, 1), 1649.69], [gd(2012, 4, 1), 1591.19], [gd(2012, 5, 1), 1598.76], [gd(2012, 6, 1), 1589.90], [gd(2012, 7, 1), 1630.31], [gd(2012, 8, 1), 1744.81], [gd(2012, 9, 1), 1746.58], [gd(2012, 10, 1), 1721.64], [gd(2012, 11, 2), 1684.76] ]; var data2 = [ [gd(2012, 0, 1), 0.63], [gd(2012, 1, 1), 5.44], [gd(2012, 2, 1), -3.92], [gd(2012, 3, 1), -1.44], [gd(2012, 4, 1), -3.55], [gd(2012, 5, 1), 0.48], [gd(2012, 6, 1), -0.55], [gd(2012, 7, 1), 2.54], [gd(2012, 8, 1), 7.02], [gd(2012, 9, 1), 0.10], [gd(2012, 10, 1), -1.43], [gd(2012, 11, 2), -2.14] ]; var dataset = [ { label: "Gold Price", data: data1, points: { symbol: "triangle"} }, { label: "Change", data: data2, yaxis: 2 } ]; var options = { series: { lines: { show: true }, points: { radius: 3, fill: true, show: true } }, xaxis: { mode: "time", tickSize: [1, "month"], tickLength: 0, axisLabel: "2012", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 10 }, yaxes: [{ axisLabel: "Gold Price(USD)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3, tickFormatter: function (v, axis) { return $.formatNumber(v, { format: "#,###", locale: "us" }); } }, { position: "right", axisLabel: "Change(%)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3 } ], legend: { noColumns: 0, labelBoxBorderColor: "#000000", position: "nw" }, grid: { hoverable: true, borderWidth: 2, borderColor: "#633200", backgroundColor: { colors: ["#ffffff", "#EDF5FF"] } }, colors: ["#FF0000", "#0022FF"] }; $(document).ready(function () { $.plot($("#flot-placeholder1"), dataset, options); $("#flot-placeholder1").UseTooltip(); }); function gd(year, month, day) { return new Date(year, month, day).getTime(); } var previousPoint = null, previousLabel = null; var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; $.fn.UseTooltip = function () { $(this).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; var month = new Date(x).getMonth(); //console.log(item); if (item.seriesIndex == 0) { showTooltip(item.pageX, item.pageY, color, "<strong>" + item.series.label + "</strong><br>" + monthNames[month] + " : <strong>" + y + "</strong>(USD)"); } else { showTooltip(item.pageX, item.pageY, color, "<strong>" + item.series.label + "</strong><br>" + monthNames[month] + " : <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 - 40, left: x - 120, 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.9 }).appendTo("body").fadeIn(200); } </script> </head> <body> <div style="width:450px;height:300px;text-align:center;margin:10px"> <div id="flot-placeholder1" style="width:100%;height:100%;"></div> </div> </body> </html>