形圖可視化廣泛用于分層數據分析。如果你沒有經驗還想創建一個,那將會有些復雜。下面是一個詳細教程,教你如何使用JavaScript創建交互式樹形圖。
宇宙中只有我們嗎?我們每個人都曾在某個時候問過自己這個問題。當我們在考慮地球是否是宇宙中唯一可居住的行星時,我們可能會思考宇宙究竟有多大。讓我們在樹形圖的幫助下看看吧!在本教程中,我們將使用樹形映射出宇宙中已知的10個最大的星系。
在進入教程之前,了解一下樹形圖的概念。樹形圖是一種流行的技術,用于將分層組織、樹狀結構的數據可視化。它可以一目了然地展示出層次結構以及各個數據點的值,它使用了大小與相應數量成比例的嵌套矩形。
樹的每個分支都是一個矩形,對于子分支,其中嵌套了較小的矩形。通過顏色和接近度顯示數據,樹形圖可以輕松表示大量數據,同時有效利用空間,非常適合比較層次結構中的比例。
樹形圖類型是由Ben Shneiderman教授發明的,他在信息設計和人機交互領域作出了重大貢獻。樹形圖被用于許多數據可視化領域,可用于分析股票市場、人口普查系統和選舉統計數據,以及數據新聞、硬盤探索工具等。
下面將使用JavaScript構建一個樹形圖來比較已知宇宙中排名前10的星系的大小。JS樹狀圖在本教程結束時的樣子:
創建基于JavaScript的樹狀圖通常需要以下四個基本步驟:
1. 創建一個HTML頁面
2. 參考JavaScript文件
3. 設置數據
4. 編寫一些JS樹代碼
如果你是 HTML、CSS 和JavaScript方面的新手,請不要擔心。本文將詳細介紹每一步,在學習完本教程之后,你可以嘗試去做自己的JS樹狀圖。
首先需要創建一個基本的HTML頁面。添加一個HTML塊元素 (<div>),并將樹形圖放置其中,為其分配一個ID屬性(讓它成為“容器”),以便稍后在代碼中引用它。
然后為 <div> 設置一些樣式。將寬度和高度屬性定義為 100%,邊距和填充為 0。當然,你可以根據自己的喜好進行更改。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Treemap 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>
接下來,需要引用所需腳本,用這些腳本創建樹形圖。
現在有多個JavaScript圖表庫可供選擇。創建交互式數據可視化的基本步驟與它們中的任何一個都是差不多的。在這里,為了說明問題,我將使用AnyChart,它支持樹形圖并有免費版本,其源代碼在GitHub上開放。
因此,要構建樹形圖,需要導入“核心”和“樹形圖”模塊。在第一步創建的HTML頁面的 head 部分中引用它們。從 CDN 獲取它們(或下載文件)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Treemap Chart</title>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-treemap.min.js"></script>
<style type="text/css">
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
設置數據后將把已知宇宙中最大的前10個星系的規模可視化。這些星系非常龐大,所以需要以它們的直徑來衡量它們是多少光年(光年是一束光在一個地球年中傳播的距離,相當于大約 6 萬億英里)。
我已經從 Largest.org 獲取了星系尺度的數據。
對于圖表,樹結構數據根基元素是“星系”,(按星系類型)分為“橢圓”和“螺旋”作為其子元素,它們又有個別星系對象的數組作為它們自己的子元素。
每個星系對象都具有<名稱 \ 尺度>鍵值屬性。例如,{name: "IC 1101", value: 4000000} 表示規模為 4,000,000 光年的 IC 1101 星系。說實話,很難理解它有多大。
var dataSet = [
{name: "Galaxies", children: [
{name: "Elliptical", children: [
{name: "IC 1101", value: 4000000},
{name: "Hercules A", value: 1500000},
{name: "A2261-BCG", value: 1000000},
{name: "ESO 306-17", value: 1000000},
{name: "ESO 444-46", value: 402200},
]},
{name: "Spiral", children: [
{name: "Rubin's Galaxy", value: 832000},
{name: "Comet Galaxy", value: 600000},
{name: "Condor Galaxy", value: 522000},
{name: "Tadpole Galaxy", value: 280000},
{name: "Andromeda Galaxy", value: 220000}
]}
]}
];
到此只需幾行JavaScript代碼就可以為樹形圖提供動力。
1.使用anychart.onDocumentReady() 函數,加載樹形圖的所有JavaScript代碼,確保它在網頁完全加載并準備執行。
<script>
anychart.onDocumentReady(function () {
// JS樹映射代碼會寫到這里
});
</script>
2.然后,從第3步開始在樹形圖中添加我們想要可視化的數據。
<script>
anychart.onDocumentReady(function () {
var dataSet = [
{name: "Galaxies", children: [
{name: "Elliptical", children: [
{name: "IC 1101", value: 4000000},
{name: "Hercules A", value: 1500000},
{name: "A2261-BCG", value: 1000000},
{name: "ESO 306-17", value: 1000000},
{name: "ESO 444-46", value: 402200},
]},
{name: "Spiral", children: [
{name: "Rubin's Galaxy", value: 832000},
{name: "Comet Galaxy", value: 600000},
{name: "Condor Galaxy", value: 522000},
{name: "Tadpole Galaxy", value: 280000},
{name: "Andromeda Galaxy", value: 220000}
]}
]}
];
});
</script>
3.添加以下代碼將數據轉換到圖上。
var chart = anychart.treeMap(dataSet, "as-tree");
4.添加一個標題,將圖表放入之前定義的 <div> 容器中,并使用 draw 命令顯示它。
chart.title("The 10 Largest Galaxies in the Known Universe");
chart.container("container");
chart.draw();
現在JS樹形圖基本上已經準備好了:
加載樹形圖時,只會顯示兩個圖塊,“橢圓”和“螺旋”。然后可以單擊它們,展開其各自的子星系,這就是所謂的下鉆操作。
為什么會只有兩塊?因為默認情況下,最大深度值設置為1。這意味著一次只能看到其父級的一個級別。較低的級別是隱藏的。在第一層,將“星系”分為“橢圓”和“螺旋”,所以只能看到這一層。
顯示所有星系圖塊只需要使用maxDepth()函數更改最大深度值。
chart.maxDepth(2);
效果如下:
在這張圖表中,可以看到星系是如何根據層次結構進行分組的,還可以單擊頂部的“橢圓”或“螺旋”標題來放大其子星系。
完整代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Treemap Chart</title>
<script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
<script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-treemap.min.js"></script>
<style type="text/css">
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
anychart.onDocumentReady(function () {
// 創建數據
var dataSet = [
{name: "Galaxies", children: [
{name: "Elliptical", children: [
{name: "IC 1101", value: 4000000},
{name: "Hercules A", value: 1500000},
{name: "A2261-BCG", value: 1000000},
{name: "ESO 306-17", value: 1000000},
{name: "ESO 444-46", value: 402200},
]},
{name: "Spiral", children: [
{name: "Rubin's Galaxy", value: 832000},
{name: "Comet Galaxy", value: 600000},
{name: "Condor Galaxy", value: 522000},
{name: "Tadpole Galaxy", value: 280000},
{name: "Andromeda Galaxy", value: 220000}
]}
]}
];
// 創建樹形圖并設置數據
var chart = anychart.treeMap(dataSet, "as-tree");
// 設置圖表標題
chart.title("The 10 Largest Galaxies in the Known Universe");
// 設置圖表的容器id
chart.container("container");
// 開始繪制圖表
chart.draw();
});
</script>
</body>
</html>
現在,你可以一目了然地看到10個最大星系的規模并進行比較。下面展示如何自定義JavaScript樹形圖。
改變任何圖表的外觀和感覺有一種簡單方法就是更改顏色。
chart.normal().fill('#B46FC2');
chart.hovered().fill('#44008B', 0.8);
chart.selected().fill('#0A0068', 0.8);
chart.selected().hatchFill("forward-diagonal", '#282147', 2, 20);
添加了fill()和hashFill()方法來更改樹形圖的顏色。
在樹形圖中,除了大小,圖塊的顏色也有助于突出顯示比例。可以借助線性色標根據相應的數據維度自動為圖塊著色。
創建一個線性色標,為其提供兩個值,一個為最低范圍值,另一個為最高值,最后啟用顏色范圍。
var customColorScale = anychart.scales.linearColor();
customColorScale.colors(['#37B8F7', '#ffcc00']);
chart.colorScale(customColorScale);
chart.colorRange().enabled(true);
chart.colorRange().length('90%');
實現這些需要修改上一節中的代碼。
可以使用HTML來格式化標簽。為此,需要為標簽啟用 HTML。然后,你就可以不受限制地使用HTML對它們進行格式化。
可以把標簽格式化為<span>HTML元素,并對其進行樣式設計,以增加字體大小和改變顏色。
chart.labels().useHtml(true);
chart.labels().format(
"<span style='font-size: 24px; color: #00076f'>{%name}</span><br>{%value}"
);
正如你在上面的代碼片段中看到的,還使用了{%name}和{%value}標記,用來更改樹形圖標簽和工具提示的文本。這樣,在創建可視化時將為每個星系輸出名稱和比例值。
此外,使用format()方法來定制工具提示的文本。一個內容豐富的工具提示有助于更好地理解數據。
chart.tooltip().format(
"Scale: {%value} light-years"
);
默認情況下,樹形圖圖塊按降序排列。可以看到星系是從高到低排列的,規模最大的IC 1101星系是左起第一個。
如果需要升序排列,那么添加:
chart.sort("asc");
下面是一個完整 樣例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Treemap Chart</title>
<script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
<script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-treemap.min.js"></script>
<style type="text/css">
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
anychart.onDocumentReady(function () {
// create the data
var dataSet = [
{name: "Galaxies", children: [
{name: "Elliptical", children: [
{name: "IC 1101", value: 4000000},
{name: "Hercules A", value: 1500000},
{name: "A2261-BCG", value: 1000000},
{name: "ESO 306-17", value: 1000000},
{name: "ESO 444-46", value: 402200},
]},
{name: "Spiral", children: [
{name: "Rubin's Galaxy", value: 832000},
{name: "Comet Galaxy", value: 600000},
{name: "Condor Galaxy", value: 522000},
{name: "Tadpole Galaxy", value: 280000},
{name: "Andromeda Galaxy", value: 220000}
]}
]}
];
// create the treemap chart and set the data
var chart = anychart.treeMap(dataSet, "as-tree");
// set the chart title
chart.title("The 10 Largest Galaxies in the Known Universe");
// set a custom color scale
var customColorScale = anychart.scales.linearColor();
customColorScale.colors(['#37B8F7', '#ffcc00']);
chart.colorScale(customColorScale);
chart.colorRange().enabled(true);
chart.colorRange().length('90%');
// format the labels
chart.labels().useHtml(true);
chart.labels().format(
"<span style='font-size: 24px; color: #00076f'>{%name}</span><br>{%value}"
);
// format the tooltips
chart.tooltip().format(
"Scale: {%value} light years"
);
// sort in ascending order
chart.sort("asc");
// set the container id for the chart
chart.container("container");
// initiate drawing the chart
chart.draw();
});
</script>
</body>
</html>
恭喜現在已經學會了輕松地創建出色的交互式JavaScript樹形圖!請參閱樹形圖文檔 , 以 便 了解它還可以做些什么,或者使用不同的圖表庫。
一節聊到正則表達式的簡單應用,不足之處歡迎留言交流。
Javascript正則表達式示例之基本概念
今天,我們來看一下,如何使用正則表達式,匹配HTML標簽及相關信息。
為什么要加上相關信息呢?
因為,如果您想寫一個HTML語法樹解析庫的時候,可能會用到。
下面內容用到的語法
|:表示或者,要么前面,要么后面
(?<=我前面出現的內容)要匹配的內容:只匹配前面出現的字符之后的內容。
可視圖
要匹配的內容(?=我前面出現的內容):只匹配后面出現的字符之前的內容。
可視圖
分組捕獲:一對完整的小括號(),表示一個組。
\數字:你要使用那一個分組捕獲到的內容。
.*?:在正則表達式中,. 表示匹配任意字符,* 表示匹配 0 到任意次的前一個字符,? 表示非貪婪匹配,即盡可能匹配最少的字符。因此,.*? 表示匹配任意字符零次或多次,但盡可能匹配最少的字符。這個表達式通常用于匹配一個字符串中的所有內容,但是避免貪婪匹配導致的匹配錯誤。
^: 表示匹配開始
[要匹配的字符]:只匹配括號中的字符。
比如[0-9]、[a-z]、[A-Z]、[0-9a-zA-Z]、[0-9abc]等等。
[^要匹配的字符]:[]中加^表示匹配不是“要匹配的字符”。
<body><div id="left">left</div><div id="right">right</div></body>
const text = document.body.innerText;
text = text.replace(/\n/g, '');
console.log(text);
//輸出: leftright
假設沒有innerText的功能呢?實現這個功能,使用正則表達式無疑是最方便的。
var text = document.body.innerHTML.replace(/<[^>]+>/g,'');
text = text.replace(/\n/g, '');
console.log(text);
//輸出: leftright
匹配結果
可視圖
是的,這個正則表達式的意思是,查找<>并且包含他們之間不為>的一段字符串。
到這里,您以為就結束了嗎?您在網上搜索匹配HTML標簽,可能也會得到這么一個結果(例如:<[^>]+>、<.*?>、等等),但實際上這只是開始,我們本著只要是程序就可能有bug的原則,所以我們來看下面一個例子。
const strHtml = '<span data-code=">">>是大于符號。</span>';
const strRes = strHtml.replace(/<[^>]+>/g, '');
console.log(strRes);
// ">>是大于符號。
[可憐]bug出現了,怎么辦?別著急,請看下一個知識點。
2.1、首先,我們先解決第一點最后的bug。
const strHtml = '<span data-code=">">>是大于符號。</span>';
// 一個小改動即可。
const strRes = strHtml.replace(/<("[^"]*"|[^>])+>/g, '');
console.log(strRes);
// >是大于符號。
可視圖
完美[打臉] ,還沒結束……
const strHtml = "<span data-code='>'>>是大于符號。</span>";
const strRes = strHtml.replace(/<("[^"]*"|[^>])+>/g, '');
console.log(strRes);
// '>>是大于符號。
甲:這不是我寫的HTML不標準,是你的解析庫兼容性不好,瀏覽器都可以識別,你為什么不可以?
已:……。
const strHtml = `<i code="<"><小于符號。</i><i code='>'>>大于符號。</i>`;
// 繼續改造
const strRes = strHtml.replace(/<((["'])+.*?\2|[^>])+>/g, '');
console.log(strRes);
// <小于符號。>大于符號。
匹配結果
可視圖
是的,利用正則表達式分組捕獲的語法,實現了上面的需求。
2.2 現在,我們來看看,如何找到某個標簽的所有屬性。
const strHtml = `
<input type='text' disabled value="" class="txt txt-md" v-on:click="save('button')" />
`;
上面的例子中,有多種情況,我們首先來整理出來。
屬性1:type='text'
/[\w]+=(["'])+.*?/
屬性2:disabled
/[\w]+/
屬性3:value=""
/[\w]+=(["'])+.*?/
屬性4:class="txt txt-md"
/[\w]+=(["'])+.*?/
屬性5:v-on:click="save('button')"
/[\w:]+=(["'])+.*?/
其他情況:歡迎討論。
把所有情況連起來之后。
const strHtml = `<input type='text' disabled value="" class="txt txt-md" v-on:click="save('button')" />`;
const tagAttrs = strHtml.match(/(?<=\s)[\w:-]+(=(["']).*?\2)*/g) || [];
console.log(tagAttrs);
// ["type='text'", 'disabled', 'value=""', 'class="txt txt-md"', `v-on:click="save('button')"`]
匹配結果
可視圖
人人為我,我為人人,歡迎您的瀏覽,我們一起加油吧。
通過 HTML DOM,可訪問 JavaScript HTML 文檔的所有元素。
HTML DOM (文檔對象模型)
當網頁被加載時,瀏覽器會創建頁面的文檔對象模型(Document Object Model)。
HTML DOM 模型被構造為對象的樹:
HTML DOM 樹
通過可編程的對象模型,JavaScript 獲得了足夠的能力來創建動態的 HTML。
JavaScript 能夠改變頁面中的所有 HTML 元素
JavaScript 能夠改變頁面中的所有 HTML 屬性
JavaScript 能夠改變頁面中的所有 CSS 樣式
JavaScript 能夠對頁面中的所有事件做出反應
查找 HTML 元素
通常,通過 JavaScript,您需要操作 HTML 元素。
為了做到這件事情,您必須首先找到該元素。有三種方法來做這件事:
通過 id 找到 HTML 元素
通過標簽名找到 HTML 元素
通過類名找到 HTML 元素
通過 id 查找 HTML 元素
在 DOM 中查找 HTML 元素的最簡單的方法,是通過使用元素的 id。
本例查找 id="intro" 元素:
實例
var x=document.getElementById("intro");
如果找到該元素,則該方法將以對象(在 x 中)的形式返回該元素。
如果未找到該元素,則 x 將包含 null。
通過標簽名查找 HTML 元素
本例查找 id="main" 的元素,然后查找 id="main" 元素中的所有 <p> 元素:
實例
var x=document.getElementById("main");
var y=x.getElementsByTagName("p");
通過類名找到 HTML 元素
本例通過 getElementsByClassName 函數來查找 class="intro" 的元素:
實例
var x=document.getElementsByClassName("intro");
HTML DOM 后篇
我會接著介紹:
如何改變 HTML 元素的內容 (innerHTML)
如何改變 HTML 元素的樣式 (CSS)
如何對 HTML DOM 事件對出反應
如何添加或刪除 HTML 元素
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。