如何畫Flot直條圖

直條圖常被用來比較各組資料的相互關係, 直條的高度越高, 所代表的值越大. 除了直條圖之外, 還有橫條圖, 直條圖和橫條圖的做法一樣, 差別只在一個屬性值"horizontal", 如果設為true, 就會以橫條圖呈現, 另外x軸與y軸的資料需要互相對調位置.

本章會提供直條圖以及橫條圖的範例. 製作直條圖的做法和製作折線圖做法大同小異, 只要你有看過上一章折線圖的做法, 相信在這一章也能輕易上手.

直條圖範例

直條圖做法

在這個範例裡, 我們用的是2012世界城市的年平均溫度做為繪圖資料, 為了讓範例簡單一點, 我們只抓了6個城市的資料.

一開始的做法和折線圖一樣, 先插入定位點到頁面中, 並指定其id以及長度和寬度
   
        <div id="flot-placeholder" style="width:400px;height:300px"></div>
        
接下來就是準備資料, 直條圖的資料和折線圖的資料不太一樣, 因為直條圖通常是用來比較各組資料的關係, 所以在這裡我們加入6個陣列資料, 分別代表6個城市的年均溫, 因為這範例沒有用到時間資料格式, 我們將x軸用序號編碼, y軸資料則是年平均溫度.  最後再把陣列資料加到dataset變數裡, 並指定標籤(label)為"2012 Average Temperature", 另外我們用color屬性指定了直條圖的顏色為#5482FF, 若你有多個資料組時, 將各資料組用不同的顏色來區分, 有助於使用者在看圖表時的便利性.
   
        var data = [    
            [0, 11], //London, UK
            [1, 15], //New York, USA
            [2, 25], //New Delhi, India
            [3, 24], //Taipei, Taiwan
            [4, 13], //Beijing, China
            [5, 18]  //Sydney, AU
        ];

        var dataset = [
            { label: "2012 Average Temperature", data: data, color: "#5482FF" }
        ];
        
因為此範例不是用時間資料格式做為x軸的資料, 如果沒有指定x軸的刻度資料, x軸就只會顯示0, 1, 2, ....所以我們要自行建立x軸的刻度資料, 建立方式和資料來源一樣是用陣列, 你也可以直接複製data變數來修改. x軸一樣是從0開始的序號, 而y軸就是要顯示的刻度資料, 這裡我們填上各城市的名稱.

刻度資料完成後就可以指定到options裡的xaxis.ticks裡去, x軸就會顯示你所設定的城市名稱. y軸也可以自訂刻度資料, 如果是用在y軸上, 就指定到yaxis.ticks去即可.
   
        var ticks = [
            [0, "London"], [1, "New York"], [2, "New Delhi"], [3, "Taipei"], [4, "Beijing"], [5, "Sydney"]
        ];

        xaxis: {           
          ticks: ticks
        }
        
畫條圖時需要將options裡的series.bars.show設為true, 條圖才會出現, 若沒有設定, 預設會出現折線圖. 另外bars.align控制直條圖對齊的方向, 可設定的值有"left", "right"和"center". 另外我們還可以設定bars.barWidth控制條圖的寬度, barWidth是指x軸或y軸的單位寬度, 而不是像素, 在這裡我們設定為0.5.
             series: {
                bars: {
                    show: true
                }
            },
            bars: {
                align: "center",
                barWidth: 0.5
            }
        
我們剛剛解釋了自訂刻度的方法,但如果你想在原有的刻度加上單位如°C或是金錢單位如$要如何辦到,Flot提供了一個函式tickFormatter, 這函式傳入了2個參數, tick value和axis object, 並且會傳回字串, 所以我們在這範例裡要將y軸的刻度都加上°C的單位寫法如下
   
        yaxis: {                
            tickFormatter: function (v, axis) {
                return v + "°C";
            }
        }        
        
此範例裡也用了軸標籤的外掛, 由於上一章已經介紹過了, 在這裡就不贅述, 有興趣的可以回到上一章如何畫Flot折線圖查看.
   
        xaxis: {
            axisLabel: "World Cities",
            axisLabelUseCanvas: true,
            axisLabelFontSizePixels: 12,
            axisLabelFontFamily: 'Verdana, Arial',
            axisLabelPadding: 10
        }

        yaxis: {
            axisLabel: "Average Temperature",
            axisLabelUseCanvas: true,
            axisLabelFontSizePixels: 12,
            axisLabelFontFamily: 'Verdana, Arial',
            axisLabelPadding: 3
        }
        
最後一樣呼叫$.plot函式, 並且指定定位點, 帶入dataset和options參數後繪圖即完成. 下一章我們將會介紹橫條圖的做法, 直條圖和橫條圖做法大同小異, 差別在建立資料時需要把x軸及y軸相互對調, 細節我們會再詳細說明.
   
        $(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.symbol.js"></script>
    <script type="text/javascript" src="/js/flot/jquery.flot.axislabels.js"></script>
    
    <script type="text/javascript">
        //******* 2012 Average Temperature - BAR CHART
        var data = [[0, 11],[1, 15],[2, 25],[3, 24],[4, 13],[5, 18]];
        var dataset = [{ label: "2012 Average Temperature", data: data, color: "#5482FF" }];
        var ticks = [[0, "London"], [1, "New York"], [2, "New Delhi"], [3, "Taipei"],[4, "Beijing"], [5, "Sydney"]];

        var options = {
            series: {
                bars: {
                    show: true
                }
            },
            bars: {
                align: "center",
                barWidth: 0.5
            },
            xaxis: {
                axisLabel: "World Cities",
                axisLabelUseCanvas: true,
                axisLabelFontSizePixels: 12,
                axisLabelFontFamily: 'Verdana, Arial',
                axisLabelPadding: 10,
                ticks: ticks
            },
            yaxis: {
                axisLabel: "Average Temperature",
                axisLabelUseCanvas: true,
                axisLabelFontSizePixels: 12,
                axisLabelFontFamily: 'Verdana, Arial',
                axisLabelPadding: 3,
                tickFormatter: function (v, axis) {
                    return v + "°C";
                }
            },
            legend: {
                noColumns: 0,
                labelBoxBorderColor: "#000000",
                position: "nw"
            },
            grid: {
                hoverable: true,
                borderWidth: 2,
                backgroundColor: { colors: ["#ffffff", "#EDF5FF"] }
            }
        };

        $(document).ready(function () {
            $.plot($("#flot-placeholder"), dataset, options);
            $("#flot-placeholder").UseTooltip();
        });

        function gd(year, month, day) {
            return new Date(year, month, day).getTime();
        }

        var previousPoint = null, previousLabel = null;

        $.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;

                        //console.log(item.series.xaxis.ticks[x].label);                

                        showTooltip(item.pageX,
                        item.pageY,
                        color,
                        "<strong>" + item.series.label + "</strong><br>" + item.series.xaxis.ticks[x].label + " : <strong>" + y + "</strong> °C");
                    }
                } 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-placeholder" style="width:100%;height:100%;"></div>        
    </div>
</body>
</html>
        


練習

本章的完整範例程式碼可以在這裡找到並做線上練習 Go to Example Tester