如何使用JavaScript創(chuàng)建柱狀圖
譯文在數(shù)據(jù)無(wú)處不在的情況下,人們應(yīng)該知道如何以圖形方式表示這些數(shù)據(jù),以便更好、更快地理解數(shù)據(jù)展示的內(nèi)容。最常見(jiàn)的數(shù)據(jù)可視化技術(shù)之一是柱狀圖,本文將展示如何使用JavaScript輕松創(chuàng)建交互式圖表。
當(dāng)需要比較數(shù)值時(shí),柱狀圖是一種簡(jiǎn)單而強(qiáng)大的顯示數(shù)據(jù)的方法。本文將學(xué)習(xí)如何制作它的不同變體(單系列、多系列、數(shù)值堆疊和100%堆疊),并在幾行JS代碼中應(yīng)用有效的自定義。
本文作者表示,作為一名板球迷,她觀看了去年10月在澳大利亞舉辦的ICC男子T20板球世界杯比賽。她決定使用一些與這些比賽相關(guān)的數(shù)據(jù)來(lái)進(jìn)行可視化說(shuō)明。在本文教程中構(gòu)建的JavaScript柱狀圖將讓人們可以了解擊球統(tǒng)計(jì)數(shù)據(jù),更準(zhǔn)確地說(shuō),是T20板球世界杯比賽中排名前十的擊球手得分。
1.基本JS柱狀圖
只需四個(gè)步驟即可輕松構(gòu)建基本的JavaScript柱形圖。以下展示在每個(gè)步驟中要做什么,并解釋將編寫(xiě)的每一行代碼。
A.創(chuàng)建容器
首先,需要為圖表設(shè)置一個(gè)地方。
如果已經(jīng)有一個(gè)想要放置的網(wǎng)頁(yè),可以打開(kāi)HTML文件,如果沒(méi)有,可以從頭創(chuàng)建一個(gè)。然后添加一個(gè)塊級(jí)HTML元素并為它提供一個(gè)ID。另外,設(shè)置它的寬度、高度和其他樣式參數(shù)來(lái)滿足需求。
在創(chuàng)建了一個(gè)非?;镜腍TML頁(yè)面之后,添加一個(gè)<div>元素,其ID為“container”,并將其寬度和高度指定為100%,以便產(chǎn)生的基于JS的柱形圖填充整個(gè)頁(yè)面:
HTML
<html>
<head>
<title>JavaScript Column Chart</title>
<style type="text/css">
html, body, #container {
width: 100%; height: 100%; margin: 0; padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
B.包含腳本文件
快速創(chuàng)建Web交互式圖表的最簡(jiǎn)單方法是使用現(xiàn)有的JavaScript圖表庫(kù)之一。它們是一組預(yù)先編寫(xiě)的圖表代碼,這使得用最少的額外編碼工作就可以構(gòu)建數(shù)據(jù)可視化。
不管具體的庫(kù)是什么,創(chuàng)建柱狀圖的步驟基本上都是相同的。無(wú)論選擇哪種,通過(guò)在<head>部分的<script>標(biāo)簽中引用它的JavaScript文件,將它包含在網(wǎng)頁(yè)中。然后在<head>或<body>部分的任何地方添加另一個(gè)<script>標(biāo)記,這是將放置柱狀圖代碼的地方。
在本文的教程中,為了說(shuō)明這個(gè)過(guò)程,將使用AnyChart這個(gè)工具。它是一個(gè)輕量級(jí)的JS圖表庫(kù),有詳細(xì)的文檔和許多示例,免費(fèi)用于非商業(yè)用途。因此包含了它的基本模塊:
HTML
<html>
<head>
<title>JavaScript Column Chart</title>
<style type="text/css">
html, body, #container {
width: 100%; height: 100%; margin: 0; padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
C.準(zhǔn)備數(shù)據(jù)
接下來(lái),準(zhǔn)備要在柱狀圖中可視化的數(shù)據(jù)。
本文作者從ESPNcricinfo收集了ICC男子T20世界杯前10名得分手的總得分統(tǒng)計(jì)數(shù)據(jù),并將它們整理在一個(gè)簡(jiǎn)單的JavaScript多維數(shù)組中。(當(dāng)然,可以使用不同的數(shù)據(jù)格式,例如JSON、XML、CSV等)
JavaScript
[
["Virat Kohli", "296", "India"],
["Max O'Dowd", "242", "Netherlands"],
["Suryakumar Yadav", "239", "India"],
["JD Butler", "225", "England"],
["Kusal Mendis", "223", "Sri Lanka"],
["Sikandar Raza", "219", "Zimbabwe"],
["Pathum Nissanka", "214", "Sri Lanka"],
["AD Hales", "212", "England"],
["Lorkan Tucker", "204", "Ireland"],
["Glenn Phillips", "201", "New Zealand"]
]
D.編寫(xiě)可視化代碼
場(chǎng)地已經(jīng)準(zhǔn)備好了,球員們也準(zhǔn)備好了,現(xiàn)在是比賽開(kāi)始的時(shí)候了!用JS圖表庫(kù)創(chuàng)建柱狀圖就像在板球比賽中擊出六分球一樣——通過(guò)更少的努力獲得更多的回報(bào)。以下展示如何通過(guò)編寫(xiě)幾行JavaScript代碼來(lái)啟動(dòng)和運(yùn)行它。
做的第一件事是在<body>部分的<script>標(biāo)記中添加anychart.onDocumentReady()函數(shù)。所有其他的部分都會(huì)進(jìn)入這個(gè)函數(shù)。
HTML
<script>
anychart.onDocumentReady(function() {
// The following JS code to create a column chart.
});
</script>
然后,使用內(nèi)置函數(shù)創(chuàng)建一個(gè)JS柱狀圖實(shí)例,并使用準(zhǔn)備好的數(shù)據(jù)添加一個(gè)系列。
JavaScript
// create a column chart
var chart = anychart.column();
// create a data series
var series = chart.column([
["Virat Kohli", "296", "India"],
["Max O'Dowd", "242", "Netherlands"],
["Suryakumar Yadav", "239", "India"],
["JD Butler", "225", "England"],
["Kusal Mendis", "223", "Sri Lanka"],
["Sikandar Raza", "219", "Zimbabwe"],
["Pathum Nissanka", "214", "Sri Lanka"],
["AD Hales", "212", "England"],
["Lorkan Tucker", "204", "Ireland"],
["Glenn Phillips", "201", "New Zealand"]
]);
為坐標(biāo)軸和圖表本身添加標(biāo)題始終是一個(gè)很好的做法,以使所表示的內(nèi)容更加明顯。以下設(shè)置這些:
JavaScript
// add axis titles
chart.xAxis().title("Batsman");
chart.yAxis().title("Number of runs");
// add a chart title
chart.title("Top 10 Run Scorers at ICC Men's T20 World Cup 2022");
最后,設(shè)置容器元素(這里是需要它的ID的地方),并將生成的柱形圖可視化顯示出來(lái)。
JavaScript
// set the container element
chart.container("container");
// display the chart
chart.draw()
在這個(gè)案例中,下面是<script>標(biāo)記中的整個(gè)JS代碼當(dāng)前的樣子:
JavaScript
anychart.onDocumentReady(function () {
// create a column chart
var chart = anychart.column();
// create a data series
var series = chart.column([
["Virat Kohli", "296", "India"],
["Max O'Dowd", "242", "Netherlands"],
["Suryakumar Yadav", "239", "India"],
["JD Butler", "225", "England"],
["Kusal Mendis", "223", "Sri Lanka"],
["Sikandar Raza", "219", "Zimbabwe"],
["Pathum Nissanka", "214", "Sri Lanka"],
["AD Hales", "212", "England"],
["Lorkan Tucker", "204", "Ireland"],
["Glenn Phillips", "201", "New Zealand"]
]);
// add axis titles
chart.xAxis().title("Batsman");
chart.yAxis().title("Number of runs");
// add a chart title
chart.title("Top 10 Run Scorers at ICC Men's T20 World Cup 2022");
// set the container element
chart.container("container");
// display the chart
chart.draw();
});
結(jié)果1:柱狀圖
一個(gè)功能基本的JavaScript柱形圖完成了,可以在Playground上找到此圖的交互式版本以及完整的源代碼。
然后,使用內(nèi)置函數(shù)創(chuàng)建一個(gè)JS柱狀圖實(shí)例,并使用準(zhǔn)備好的數(shù)據(jù)添加一個(gè)系列。
柱狀圖是為了便于比較而設(shè)計(jì)的。在這里,可以看到Virat Kohli是如何領(lǐng)先于其他人的,而其他人彼此接近。
但這只是開(kāi)始,現(xiàn)在想知道這些球員是如何得分的。更準(zhǔn)確地說(shuō),想知道總共有多少分是通過(guò)擊球得出6分、4分或在三柱門(mén)之間跑動(dòng)得分的。多系列柱狀圖或堆疊柱狀圖可以很好地表示這一點(diǎn)。
所以,將在JS中更深入地研究柱狀圖,可以展示如何制作這兩個(gè)柱狀圖,然后進(jìn)行美化。
2.基本JS多系列柱狀圖
與單系列柱狀圖一樣,可以使用JavaScript快速輕松地創(chuàng)建多系列柱狀圖。實(shí)際上,基數(shù)保持不變,只需要改變數(shù)據(jù)。
添加多系列數(shù)據(jù)
在此不計(jì)算總分,而是計(jì)算前10名得分手(1)個(gè)6分、(2)4分 (3) 在三柱門(mén)之間跑動(dòng)的得分相加。從相同的數(shù)據(jù)源ESPNcricinfo獲取這些數(shù)據(jù),并創(chuàng)建一個(gè)數(shù)據(jù)集:
JavaScript
var dataSet = anychart.data.set([
["Virat Kohli", "India", "148", "100", "48"],
["Max O'Dowd", "Netherlands", "106", "88", "48"],
["Suryakumar Yadav", "India", "81", "104", "54"],
["JD Butler", "England", "87", "96", "42"],
["Kusal Mendis", "Sri Lanka", "95", "68", "60"],
["Sikandar Raza", "Zimbabwe", "89", "64", "66"],
["Pathum Nissanka", "Sri Lanka", "114", "52", "48"],
["AD Hales", "England", "76", "76", "60"],
["Lorkan Tucker", "Ireland", "104", "76", "24"],
["Glenn Phillips", "New Zealand", "77", "76", "48"]
]);
映射數(shù)據(jù)
接下來(lái),需要將這些數(shù)據(jù)映射到三個(gè)系列,每個(gè)系列表示一個(gè)類別。第一個(gè)系列表示在三柱門(mén)之間跑動(dòng)的得分。還有一個(gè)系列表示擊球得出4分的得分。第三個(gè)系列顯示的是擊球得出6分的得分。
JavaScript
var firstSeriesData = dataSet.mapAs({x: 0, value: 4});
var secondSeriesData = dataSet.mapAs({x: 0, value: 3});
var thirdSeriesData = dataSet.mapAs({x: 0, value: 2});
創(chuàng)建系列
現(xiàn)在是使用分別映射的數(shù)據(jù)創(chuàng)建三個(gè)系列的時(shí)候了。
JavaScript
var series;
series = chart.column(firstSeriesData);
series = chart.column(secondSeriesData);
series = chart.column(thirdSeriesData);
結(jié)果2:多系列柱狀圖
一個(gè)基本的JS多系列柱狀圖與分組系列已經(jīng)準(zhǔn)備好了,可以在Playground上查看其完整源代碼的交互式版本。
分組的多系列柱狀圖很大程度上代表了分?jǐn)?shù)類別的細(xì)分。但總數(shù)值也值得一看。那么,現(xiàn)在可以創(chuàng)建堆疊柱狀圖。
3.基本JS堆疊柱狀圖
要將分組列轉(zhuǎn)換為堆疊柱狀圖,只需一行JavaScript代碼就足夠了。
設(shè)置數(shù)值堆疊方式
開(kāi)啟Y-scale堆疊模式:
JavaScript
chart.yScale().stackMode("value");
結(jié)果3:堆疊柱狀圖
現(xiàn)在已經(jīng)有了一個(gè)基本的JS堆疊柱狀圖! 它的交互式可視化在Playground上提供了完整的源代碼。
然后可以對(duì)這個(gè)圖進(jìn)行美化。
4.自定義JS堆疊柱狀圖
根據(jù)需求如何定制基于JavaScrip的堆疊柱狀圖可視化,可能需要修改不同的內(nèi)容。將展示一些重要但仍然易于實(shí)施的調(diào)整。
調(diào)整系列
當(dāng)將鼠標(biāo)懸停在交互列上時(shí),工具提示將自動(dòng)顯示每個(gè)類別的值。但是哪一個(gè)在哪里呢?先命名這個(gè)系列,一切都將變得清晰。
與此同時(shí),為什么不稍微改變一下顏色呢?將用ICC T20 2022年板球世界杯官方標(biāo)志的顏色來(lái)繪制這個(gè)系列。這將使柱狀圖看起來(lái)更加個(gè)性化和美觀。
為此創(chuàng)建了一個(gè)函數(shù),該函數(shù)將接受每個(gè)系列、名稱以及與之相關(guān)的顏色。還將在函數(shù)中添加一個(gè)stroke屬性,該屬性將應(yīng)用于每個(gè)系列,以便在每個(gè)類別之間創(chuàng)建一種填充顏色。
JavaScript
var setupSeries = function (series, name, color) {
series.name(name).stroke("2 #fff 1").fill(color);
};
現(xiàn)在,用剛才創(chuàng)建的函數(shù)建立三個(gè)系列,并為每個(gè)系列分別賦予名稱和顏色。
JavaScript
// store the series
var series;
// create the first series with the function
series = chart.column(firstSeriesData);
setupSeries(series, "Runs scored with Sixes", "#eb2362");
// create the second series with the function
series = chart.column(secondSeriesData);
setupSeries(series, "Runs scored with Fours", "#00b1e5");
// create the third series with the function
series = chart.column(thirdSeriesData);
setupSeries(series, "Running between the wickets", "#0f0449");
添加圖例
為了進(jìn)一步提高柱狀圖的易讀性,最好添加一個(gè)圖例來(lái)顯示哪種顏色表示哪種類別。這可以通過(guò)啟用圖例輕松完成。還將添加一些字體大小和填充自定義。
JavaScript
1chart.legend().enabled(true).fontSize(14).padding([10, 0, 0, 0]);
可以通過(guò)單擊相應(yīng)的圖例項(xiàng)來(lái)隱藏/顯示特定的類別。
增強(qiáng)標(biāo)簽、工具提示和標(biāo)題
正如人們所看到的,一些擊球手的名字在X軸上是不可見(jiàn)的。為了糾正這一點(diǎn),可以旋轉(zhuǎn)標(biāo)簽,以便每個(gè)名稱都能看到。
JavaScript
chart.xAxis().labels().rotation(-90);
默認(rèn)的列圖工具提示顯示單個(gè)類別值,但不顯示總數(shù)。此外,總數(shù)不包括在數(shù)據(jù)集中。但是很容易讓它們自動(dòng)計(jì)算,然后把它們放在某個(gè)地方,例如,在工具提示標(biāo)題中。
JavaScript
chart.tooltip().titleFormat(function () {
return this.x + " — " + this.points[0].getStat("categoryYSum");
});
此外,還可以使用聯(lián)合模式在工具提示中一起顯示所有類別的值。
JavaScript
chart.tooltip().displayMode("union");
最后,將圖表標(biāo)題變大一點(diǎn),改變它的字體顏色,并添加一些填充。
JavaScript
chart.title().fontSize(20).fontColor("#2b2b2b").padding([5, 0, 0, 0]);
結(jié)果4:自定義堆疊柱圖
堆疊柱狀圖都是定制的,可以看看它已經(jīng)變得多么令人驚嘆和印象深刻!可以在Playground上隨意查看這個(gè)基于JS的交互式堆疊柱狀圖,還可以進(jìn)一步使用它的代碼、添加數(shù)據(jù)等等。
看起來(lái)很直觀,不是嗎?可以清楚地看到總得分,例如一些擊球手在三柱門(mén)之間的跑動(dòng)得分,而另一些擊球手則通過(guò)他們的擊球獲得更多的得分。
5.JS 100%堆疊柱狀圖
最后,將演示如何創(chuàng)建100%堆疊的柱狀圖表示,它可以幫助以更簡(jiǎn)單的方式比較所有數(shù)據(jù)點(diǎn)上的單個(gè)類別。
切換列堆疊模式
只需將堆疊模式從值改為百分比,堆疊柱狀圖將變成100%堆疊柱狀圖:
JavaScript
chart.yScale().stackMode("percent");
結(jié)果5:100%堆疊柱狀圖
這就是本教程的最后一個(gè)數(shù)據(jù)可視化示例,可以在Playground上查看這個(gè)基于Javascript的百分比堆疊柱狀圖變體的完整代碼。
結(jié)論
在本文中的教程中,展示了如何以不同的形式創(chuàng)建JavaScript(HTML5)柱狀圖,例如常規(guī)的單系列柱狀圖、多系列分組柱狀圖、數(shù)值堆疊柱狀圖和100%堆疊柱狀圖。還了解了如何自定義它們。
在這里使用的是AnyChartJavaScript圖表庫(kù),但還有其他多種圖表庫(kù)以供使用。從根本上來(lái)說(shuō),這個(gè)過(guò)程對(duì)于任何人都是相似的。所以可以使用任何適合自己需要的圖表庫(kù)。
正如板球比賽的擊球分?jǐn)?shù)所顯示的那樣,總體數(shù)字包括大量的邊界,但也包括相當(dāng)多的跑動(dòng)。所以,采用更多的柱狀圖和其他數(shù)據(jù)可視化將這些數(shù)據(jù)都展現(xiàn)出來(lái)。
文章標(biāo)題:How to Create Column Charts With JavaScript,作者:Shachee Swadia