切换资料序列

我们都知道当你在绘图时, 通常会有不只一种的资料序列. 就像下方的世界人口图一样, 这张图用了六个数据序列来绘制图表.

如果一次只显示一个数据序列在图表上, 用户可以很容易的判读图表, 但如果同时间一次把六个数据序列放在同一个图表上时, 用户就会很难去区别各数据序列的数值, 尤其时当图表的线条交错重迭在一起的时候.

虽然Flot并没有内建的函式可供开发者能够自由地显示或隐藏数据序列, 但还是有其它方法可以达到相同的效果.

制作切换数据序列图表的步骤

  1. 建立数据源
  2. 建立开关项
  3. 决定哪些数据序列需要被绘制出来

建立数据源

在这里我们使用之前出现在别的范例里的分区图作为此篇范例. 首先, 你必须先建立数据源, 不论是写死在程序里, 或是更进阶的你可以使用 Ajax取得数据源都可以. 在此范例里我们会使用前者的方法, 数据源格式如下...

   
//Asia population data source
var rawData6 = [
    [year(1800), 63500], [year(1850), 80900], [year(1900), 94700], [year(1950), 139849], [year(1955), 154195],
    [year(1960), 167434], [year(1965), 189942], [year(1970), 214312], [year(1975), 239751], [year(1980), 263234],
    [year(1985), 288755], [year(1990), 316781], [year(1995), 343005], [year(2000), 367974], [year(2005), 391751],
    [year(2010), 411963]
];
                    

全部一共有六个数据源, 但因为格式都相同, 所以在这里我们省略列出其它五个数据源.

在建立好了所有的数据源后, 我们必须把它们全部放进一个叫做dataCollection的数组里, 之后我们再另外建立一个叫做labelCollection的数组, 并且把相对应的label名称也同时放进此数组.

我们建立这2个数组的原因是, 我们会一一检查所有的checkbox控件, 去判断checkbox是否有被选取, 如果当属于Asia的checkbox被选取时, 我们就会把对应到Asia的数据源加入到另一个叫做dataSet的数组里去, 这个数组的数据最后会被用来当作绘制图表的数据用.

   
var dataCollection = [
    rawData1, rawData2, rawData3, rawData4, rawData5, rawData6
];

var labelCollection = [
    "Oceania", "North America", "Latin America", "Europe", "Africa", "Asia"
]
                    

建立开关项

我们在此范例使用的开关项是checkbox, 在你把它们加入到窗体里之后, 必须先把每一个的checked属性设为true, 然后给予每一个checkbox的id一个流水号, 这个流水号会用来判断要把数组中的哪一组资料抓出来用. 举例来说, 如果使用者选取了Oceania的checkbox, 那你就要把数据源rawData1和label名称"Oceania"加入dataSet数组里, 最后只要一直重复此相同的程序, 你就可以得到你所需要绘制图表的数据了.

   
<ul id="ToggleController">
    <li><input id="Checkbox1" type="checkbox" checked="checked" />Oceania</li>
    <li><input id="Checkbox2" type="checkbox" checked="checked" />North America</li>
    <li><input id="Checkbox3" type="checkbox" checked="checked" />Latin America</li>
    <li><input id="Checkbox4" type="checkbox" checked="checked" />Europe</li>
    <li><input id="Checkbox5" type="checkbox" checked="checked" />Africa</li>
    <li><input id="Checkbox6" type="checkbox" checked="checked" />Asia</li>
</ul>
                    

决定哪些数据序列需要被绘制出来

现在数据源和控件都已经完成了, 接下来就是处理切换程序, 整个流程会像如下...

  • 一一的检查每一个checkbox去判断是否有被选取
  • 从被选取的checkbox里取得当初设定在ID里的流水号
  • 加入跟流水号相对应的数据到dataSet数组里
  • 重新绘制图表

我们需要先建立一个空的数组dataSet, 这个数组变量会在最后用来绘制图表之用. 接着我们检查所有的开关项, 利用jQuery selector去抓取所有属性type设定为checkbox的input元素, $("input[type='checkbox']");

因为之前我们在UL元素中加了个ID属性进去, 主要是为了要能够与页面中其它的checkbox能够区别, 所以在这里我们必须先抓取UL元素, 然后再用$.find去抓取在其下的所有checkbox. 最后我们再用$.each去遍历所有抓出来的checkbox.

接下来我们需要去判断各个checkbox是否有被选取, 我们可以用is(":checked")来判断. 如果checkbox有被选取的话, 将会回传true值. 之后再从checkbox的ID属性中抓流水号出来. 因为checkbox元素的程序代码是这样的...
<input id="Checkbox6" type="checkbox" checked="checked" />

你可以先把整个ID属性的值抓出来, 然后再移除字符串'Checkbox', 剩下来的部份就会是流水号了. 而最后的步骤就只要把相对应的数据源和label名称从之前默认定好的数组里, 利用流水号抓出来, 再放进dataSet数组中即可.

现在你就可以呼叫$.plot($("#flot-placeholder"), dataSet, options);来绘制图表. 我们在这范例中并没有对于options变量多做解释是只想专注在切换资料序列上, 如果你想多了解分区图的options变量的话你可以到如何绘制分区图查看.

   
var dataSet = [];

$("#ToggleController").find("input[type='checkbox']").each(function () {
    if ($(this).is(":checked")) {
        var position = $(this).attr("id").replace("chkData", "");
        position = parseInt(position) - 1;

        dataSet.push(
            {
                label: labelCollection[position],
                data: dataCollection[position]
            }
        );   
    }
});

$.plot($("#flot-placeholder"), dataSet, options);
                    

要让整个程序看起来更干净, 你可以把上面的公式给包进叫做DoToggling()的函式里. 当网页完全载入后, 先呼叫一次此函式让图表先显示出来, 接着注册click事件到所有的checkbox上, 这样一来当使用者选取或取消选取checkbox时, 整个图表也会跟着重绘一次.

   
function DoToggling() {
    //formula mentioned above goes here..
}                

$(document).ready(function () {
    DoToggling();

    $("#ToggleController").find("input[type='checkbox']").click(function () {
        DoToggling();
    });
});
                    

整个切换数据序列完成图如下

切换资料序列分区图(世界人口)

利用下方checkbox切换显示的数据序列

  • Oceania
  • North America
  • Latin America
  • Europe
  • Africa
  • Asia

练习

本章的完整范例程序代码可以在这里找到并做在线练习 Go to Example Tester