d3.js學習1----json檔案格式
1. JSON 格式
JSON(JavaScript Object Notation)就是javascript物件表示法, 是一種輕量級的資料交換語言,以文字為基礎,且易於讓人閱讀。儘管 JSON 是 Javascript 的一個子集,但 JSON 是獨立於語言的文字格式,並且採用了類似於C語言家族的一些習慣。
json簡單說就是javascript中的物件和陣列,所以這兩種結構就是物件和陣列兩種結構,通過這兩種結構可以表示各種複雜的結構。
1、物件:物件在js中表示為“{}”括起來的內容,資料結構為 {key:value,key:value,...}的鍵值對的結構,在面向物件的語言中,key為物件的屬性,value為對應的屬性值,所以很容易理解,取值方法為 物件.key 獲取屬性值,這個屬性值的型別可以是 數字、字串、陣列、物件幾種。
經過物件、陣列2種結構就可以組合成複雜的資料結構了。
示例:
名稱 / 值對按照最簡單的形式,可以用下面這樣的 JSON 表示"名稱 / 值對":
1{"firstName":"Brett"}
這個示例非常基本,而且實際上比等效的純文字"名稱 / 值對"佔用更多的空間:
1firstName=Brett
但是,當將多個"名稱 / 值對"串在一起時,JSON 就會體現出它的價值了。首先,可以建立包含多個"名稱 / 值對"的 記錄,比如:
1{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"}
從語法方面來看,這與"名稱 / 值對"相比並沒有很大的優勢,但是在這種情況下 JSON 更容易使用,而且可讀性更好。例如,它明確地表示以上三個值都是同一記錄的一部分;花括號使這些值有了某種聯絡。
表示陣列
當需要表示一組值時,JSON 不但能夠提高可讀性,而且可以減少複雜性。例如,假設您希望表示一個人名列表。在XML中,需要許多開始標記和結束標記;如果使用典型的名稱 / 值對(就像在本系列前面文章中看到的那種名稱 / 值對),那麼必須建立一種專有的資料格式,或者將鍵名稱修改為 person1-firstName這樣的形式。
如果使用 JSON,就只需將多個帶花括號的記錄分組在一起:
{
"people":[
{"firstName":"Brett","lastName":"McLaughlin","email":"aaaa"},
{"firstName":"Jason","lastName":"Hunter","email":"bbbb"},
{"firstName":"Elliotte","lastName":"Harold","email":"cccc"}
]
}
{
"programmers": [{
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre": "fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
}
這裡最值得注意的是,能夠表示多個值,每個值進而包含多個值。但是還應該注意,在不同的主條目(programmers、authors 和 musicians)之間,記錄中實際的名稱 / 值對可以不一樣。JSON 是完全動態的,允許在 JSON 結構的中間改變表示資料的方式。
在處理 JSON 格式的資料時,沒有需要遵守的預定義的約束。所以,在同樣的資料結構中,可以改變表示資料的方式,甚至可以以不同方式表示同一事物。
使用方法:
掌握了 JSON 格式之後,在 JavaScript 中使用它就很簡單了。JSON 是 JavaScript 原生格式,這意味著在 JavaScript 中處理 JSON 資料不需要任何特殊的 API 或工具包。
賦值給變數
例如,可以建立一個新的 JavaScript 變數,然後將 JSON 格式的資料字串直接賦值給它:
var people = {//people裡面有三個屬性和值,是programmers authors 和 musicians,它門不一樣,用{}"programmers": [{//programmers裡面有很多個程式設計師的資訊,這些可以構成一個數組,每個數組裡面有不一樣的屬性,照樣用{}包括
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre": "fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
};
這非常簡單;people包含前面看到的 JSON 格式的資料。但是,這還不夠,因為訪問資料的方式似乎還不明顯。
訪問資料儘管看起來不明顯,但是上面的長字串實際上只是一個數組;將這個陣列放進 JavaScript變數之後,就可以很輕鬆地訪問它。實際上,只需用點號表示法來表示陣列元素。所以,要想訪問 programmers 列表的第一個條目的姓氏,只需在 JavaScript 中使用下面這樣的程式碼:
1people.programmers[0].lastName;//花括號裡面的就是用.來訪問,另一個按陣列訪問注意,陣列索引是從零開始的。所以,這行程式碼首先訪問 people變數中的資料;然後移動到稱為 programmers的條目,再移動到第一個記錄([0]);最後,訪問 lastName鍵的值。結果是字串值 “McLaughlin”。
下面是使用同一變數的幾個示例。people.authors[1].genre // Value is "fantasy"
people.musicians[3].lastName // Undefined. This refers to the fourth entry, and there isn't onepeople.programmers[2].firstName // Value is "Elliotte"
利用這樣的語法,可以處理任何 JSON 格式的資料,而不需要使用任何額外的 JavaScript 工具包或 API。
修改資料
正如可以用點號和方括號訪問資料,也可以按照同樣的方式輕鬆地修改資料:
1people.musicians[1].lastName="Rachmaninov";
在將字串轉換為 JavaScript 物件之後,就可以像這樣修改變數中的資料。
換回字串最終結論是,如果要處理大量 JavaScript 物件,那麼 JSON 是一個好選擇,這樣就可以輕鬆地將資料轉換為可以在請求中傳送給伺服器端程式的格式。
JSON巢狀格式
許多JavaScript樹形控制元件使用JSON巢狀格式描述樹形結構,如下所示:
{
id: '100000',
text: '廊坊銀行總行',
children: [
{
id: '110000',
text: '廊坊分行',
children: [
{
id: '113000',
text: '廊坊銀行開發區支行',
leaf: true
},
{
id: '112000',
text: '廊坊銀行解放道支行',
children: [
{
id: '112200',
text: '廊坊銀行三大街支行',
leaf: true
},
{
id: '112100',
text: '廊坊銀行廣陽道支行',
leaf: true
}
]
},
{
id: '111000',
text: '廊坊銀行金光道支行',
leaf: true
}
]
}
]
}
關於JSON巢狀格式可以搜尋百度詞條:“多叉樹”。
例項比較XML和JSON都使用結構化方法來標記資料,下面來做一個簡單的比較。
用XML表示中國部分省市資料如下:
<?xml version="1.0" encoding="utf-8"?>
<country>
<name>中國</name>
<province>
<name>黑龍江</name>
<cities>
<city>哈爾濱</city>
<city>大慶</city>
</cities>
</province>
<province>
<name>廣東</name>
<cities>
<city>廣州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>臺灣</name>
<cities>
<city>臺北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>烏魯木齊</city>
</cities>
</province>
</country>
用JSON表示如下:
{
"name": "中國",
"province": [{
"name": "黑龍江",
"cities": {
"city": ["哈爾濱", "大慶"]
}
}, {
"name": "廣東",
"cities": {
"city": ["廣州", "深圳", "珠海"]
}
}, {
"name": "臺灣",
"cities": {
"city": ["臺北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["烏魯木齊"]
}
}]
}
編碼的可讀性,xml有明顯的優勢,畢竟人類的語言更貼近這樣的說明結構。json讀起來更像一個數據塊,讀起來就比較費解了。不過,我們讀起來費解的語言,恰恰是適合機器閱讀,所以通過json的索引.province[0].name就能夠讀取“黑龍江”這個值。
編碼的手寫難度來說,xml還是舒服一些,好讀當然就好寫。不過寫出來的字元JSON就明顯少很多。去掉空白製表以及換行的話,JSON就是密密麻麻的有用資料,而xml卻包含很多重複的標記字元。
2. GeoJSON 格式
GeoJSON 是一種對地理資料結構進行編碼的格式。它只是一個採用上述 JSON 格式的用於描述地理資訊的格式。它的語法和 JSON 是一樣的,只是對各名稱做了規範,形如
3. TopoJSON 格式
TopoJSON 是 GeoJSON 簡化後的版本,可以說是 GeoJSON 的小孩。D3.js 的作者認為 GeoJSON 不太好,比較推崇 TopoJSON 格式。
TopoJSON 與 GeoJSON 相比,檔案大小縮小了 80% ,因為:
邊界線只記錄一次(例如廣西和廣東省的交界線只記錄一次)
不使用浮點數,只使用整數
不過 TopoJSON 似乎只在 D3.js 中比較廣泛的使用,還不是世界範圍內認可的格式。
要注意,無論 GeoJSON 還是 TopoJSON ,它們本質上有是 JSON 格式的檔案,都遵循 JSON 的語法,只不過對變數的名稱做了不同的規範。
在 http://mapshaper.org/ 可以試著轉換 GeoJSON 和 TopoJSON 的資料,我們會看到對於同一個地理資料檔案,TopoJSON 的檔案大小大概相當於 GeoJSON 的 20% ,這對於解決因檔案量過大而造成的讀取速度過慢是相當簡單有效的。