分享

如何画Flot条形图

 KyunraWang 2017-09-09
 
 

条形图和柱形图一样常被用来比较各组数据的相互关系, 差别在于条形图的长度越长, 所代表的值越大. 使用条形图的时机在于如果你有非常多组数据要放在一起比较, 这时用柱形图的话, 图表的宽度就有可能超出屏幕宽度, 所以改用条形图后会不断延伸的就是高度, 也方便使用者能够一眼就看到整张图表.

本章用贵金属价格, 黄金、白金、白银及钯金的现价当作数据, 另外还会介绍如何控条图的渐层色, 及控制图表图例的位置.


一开始不免俗的一样是放置定位点, 并且指定宽度和高度, 你可以直在用style设定, 或是指定一个CSS class给定位点.
1
2
3
4
5
6
7
<style type="text/css">
.mychart{
   width:300px;
   height:150px;
}
</style>
<div id="flot-placeholder" class="mychart"></div>
这次数据我们只有7笔, 先建立一个叫rawData的数组变量, 再把数据放进去. 还记得之前章节里的数据格式吗? 是像这样的 [x, y],  我们以x轴放入时间格式数据(1325347200000, 1328025600000, ...), 或是按序号编码(0, 1, 2, ....), 而y轴则放入数据的数值, 但这次我们做的是条形图, x轴和y轴数据位置必须对调如下面的rawData变量. 你可以看到数组里的第一组数字是1582.3, 这个是金价, 而第二组数字就是序号.
1
2
3
4
5
6
7
8
9
10
11
12
13
var rawData = [
    [1582.3, 0], //Gold
    [28.95, 1],  //Silver
    [1603, 2],   //Platinum
    [774, 3],    //Palladium
    [1245, 4],  //Rhodium
    [85, 5],      //Ruthenium
    [1025, 6]    //Iridium
];
 
var dataSet = [
    { label: "Precious Metal Price", data: rawData, color: "#AB5800" }
];
接着就是要建立刻度数据, 可能有人会认为因为我们做的是条形图, x轴和y轴数据对调了, 所以刻度数据也要跟着对调. 答案是错的, 刻度数据并不需要跟着对调.
1
2
3
var ticks = [
    [0, "Gold"], [1, "Silver"], [2, "Platinum"], [3, "Palldium"], [4, "Rhodium"], [5, "Ruthenium"], [6, "Iridium"]
];

条形图选项

当你绘制条形图时, bars.horizontal必须设定为true, 若没有设定, 就会变成柱形图. 在此范例里我们设定了bars.fillColor, 这属性可以接受的值可以是单一颜色(如rgba(255, 255, 255, 0.8))或是渐层色, 我们用的是后者. Flot里指定渐层色的方法可以是
1
{ colors: [ color1, color2, ... ] }
或是调整颜色的透明度如
1
{ colors: [ { opacity: 0.8 }, { opacity: 0.1 } ] }
另外我们还设定了bars.iineWidth, lineWidth是以像素为单位的线或轮廓的厚度, 在这范例里我们设成1, bars的完整选项程序代码如下
1
2
3
4
5
6
7
bars: {
    align: "center",
    barWidth: 0.5,
    horizontal: true,
    fillColor: { colors: [{ opacity: 0.5 }, { opacity: 1}] },
    lineWidth: 1
}
我们所用的数据中, 价格最贵的是白金为$1,603美金, 所以图表会以白金的条图做为宽度, 但如果我们想要让白金的条图不要占满整张图表的宽度的话, 就可以设定axis.max, 我们这在这设定2000, 如此一来白金的条图部份就不会占满整个宽度, 你也可以设定axis.min, 作用与max相反. axis.tickColor是设定网格线的颜色, 若不设定的话Flot会自动生成并且带一些透明度为基色, axis.color则是设定刻度标签的颜色.

在此我们为了美化刻度标签的格式, 我们用了jQuery Number Formatter外挂, 让x轴的值输出成货币格式, 要改变刻度标签可以复写axis.tickFormatter, 此函式传入了2个参数, tick value和axis object, 并且会传回字符串. 而Number Formatter可以到此下载.

而axis.axisLabel则是设定轴卷标, 此功能也是需要加入插件jquery.flot.axislabels.js才能使用.
以下是轴选项的程序代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
xaxis: {
    axisLabel: "Price (USD/oz)",
    axisLabelUseCanvas: true,
    axisLabelFontSizePixels: 12,
    axisLabelFontFamily: 'Verdana, Arial',
    axisLabelPadding: 10,
    max: 2000,
    tickColor: "#5E5E5E",                       
    tickFormatter: function (v, axis) {
        return $.formatNumber(v, { format: "#,###", locale: "us" });           
    },
    color:"black"
}
 
yaxis: {
    axisLabel: "Precious Metals",
    axisLabelUseCanvas: true,
    axisLabelFontSizePixels: 12,
    axisLabelFontFamily: 'Verdana, Arial',
    axisLabelPadding: 3,
    tickColor: "#5E5E5E",       
    ticks: ticks,
    color:"black"
}
Flot的图例是自动产生的,不过你也可以控制图例的细节,预设图例会出现在右上角,不过有时候会挡到图表,你可以设定legend.position让图例出现在4个角落的其中一个,可设定的值有"ne"、"nw"、"se"和"sw",分别代表右上角(north east)、左上角(north west)、右下角(south east)和左下角(south west). legend.noColumns代表图例的table会被分成多少行,若设为0则表示只会分成单一一行. legend.labelBoxBorderColor则是设定图例标签盒边框的颜色.
1
2
3
4
5
legend: {
    noColumns: 0,
    labelBoxBorderColor: "#858585",
    position: "ne"
}

呼叫$.plot完成绘图

最后把上面建立的dataSet以及options带入$.plot, 就完成了!
1
2
3
4
$(document).ready(function () {
    $.plot($("#flot-placeholder"), dataSet, options);   
    $("#flot-placeholder").UseTooltip();
});
在此范例里有用了提示框, 这部份在往后会有专属的一章讲解, 在此就不详细说明.

本范例完整程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www./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.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 type="text/javascript">
        //******* Precious Metal Price - HORIZONTAL BAR CHART
        var rawData = [[1582.3, 0], [28.95, 1],[1603, 2],[774, 3],[1245, 4], [85, 5],[1025, 6]];
        var dataSet = [{ label: "Precious Metal Price", data: rawData, color: "#E8E800" }];
        var ticks = [[0, "Gold"], [1, "Silver"], [2, "Platinum"], [3, "Palldium"], [4, "Rhodium"], [5, "Ruthenium"], [6, "Iridium"]];
 
        var options = {
            series: {
                bars: {
                    show: true
                }
            },
            bars: {
                align: "center",
                barWidth: 0.5,
                horizontal: true,
                fillColor: { colors: [{ opacity: 0.5 }, { opacity: 1}] },
                lineWidth: 1
            },
            xaxis: {
                axisLabel: "Price (USD/oz)",
                axisLabelUseCanvas: true,
                axisLabelFontSizePixels: 12,
                axisLabelFontFamily: 'Verdana, Arial',
                axisLabelPadding: 10,
                max: 2000,
                tickColor: "#5E5E5E",
                tickFormatter: function (v, axis) {
                    return $.formatNumber(v, { format: "#,###", locale: "us" });
                },
                color: "black"
            },
            yaxis: {
                axisLabel: "Precious Metals",
                axisLabelUseCanvas: true,
                axisLabelFontSizePixels: 12,
                axisLabelFontFamily: 'Verdana, Arial',
                axisLabelPadding: 3,
                tickColor: "#5E5E5E",
                ticks: ticks,
                color: "black"
            },
            legend: {
                noColumns: 0,
                labelBoxBorderColor: "#858585",
                position: "ne"
            },
            grid: {
                hoverable: true,
                borderWidth: 2,
                backgroundColor: { colors: ["#171717", "#4F4F4F"] }
            }
        };
 
        $(document).ready(function () {
            $.plot($("#flot-placeholder"), dataSet, options);
            $("#flot-placeholder").UseTooltip();
        });
 
        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;
                        //alert(color)
                        //console.log(item.series.xaxis.ticks[x].label);               
 
                        showTooltip(item.pageX,
                        item.pageY,
                        color,
                        "<strong>" + item.series.label + "</strong><br>" + item.series.yaxis.ticks[y].label +
                        " : <strong>" + $.formatNumber(x, { format: "#,###", locale: "us" }) + "</strong> USD/oz");
                    }
                } else {
                    $("#tooltip").remove();
                    previousPoint = null;
                }
            });
        };
 
        function showTooltip(x, y, color, contents) {
            $('<div id="tooltip">' + contents + '</div>').css({
                position: 'absolute',
                display: 'none',
                top: y - 10,
                left: x + 10,
                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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约