D3.js

维基百科,自由的百科全书
跳转到导航 跳转到搜索
D3.js
File:Logo D3.svg
开发者Mike Bostock、Jeffrey Heer、Vadim Ogievetsky与社群
首次发布2011年2月18日,​15年前​(2011-02-18
当前版本
    Module:EditAtWikidata第29行Lua错误:attempt to index field 'wikibase' (a nil value)
    源代码库
    • {{URL|example.com|可选的显示文本}}
    Module:EditAtWikidata第29行Lua错误:attempt to index field 'wikibase' (a nil value)
    编程语言JavaScript
    引擎
      Module:EditAtWikidata第29行Lua错误:attempt to index field 'wikibase' (a nil value)
      类型数据可视化JavaScript函数库
      许可协议BSD许可证
      网站d3js.org

      D3.jsD3Data-Driven Documents)是一个使用动态图形进行资料可视化JavaScript程序库。与W3C标准兼容,并且利用广泛实现的SVG、JavaScript和CSS标准,改良自早期的Protovis程序库。与其他的程序库相比,D3对视图结果有很大的可控性。D3是2011年面世的,同年的8月发布了2.0.0版。到2021年9月,D3已被更新到了7.0.3版[1]

      D3.js已被数十万个网站使用[2],最常被运用在在线新闻网站呈现交互式图形、呈现数据资料的图表和呈现含有地理信息的资料。另外SVG的输出功能也使得D3.js能用于印刷出版物的绘制上。

      历史[编辑]

      在D3.js开发之前已经有出现过许多尝试做资料可视化的包,例如Prefuse英语Prefuse,Flare和Protovis程序库,他们都可以视为D3.js的前身。然而Prefuse和Flare皆有缺点,皆不能只透过浏览器完成渲染,皆须要透过额外插件来完成。

      例如2005年发布的Prefuse是一个资料可视化程序库,但是它需要透过网页的Java插件才能于浏览器中呈现;而Flare是2007年发布的另一个资料可视化工具包,由于其是使用ActionScript编程语言开发,因此也需要额外插件,即Flash插件才能完成渲染。

      2009年,斯坦福大学的史丹佛可视化团队(Stanford Visualization Group)的杰佛瑞·赫尔、迈克·保斯托英语Mike_Bostock和瓦迪姆·欧格菲兹齐利用开发Prefuse和Flare的经验开始用Javscript开发了可从给定资料产生SVG图形的Protovis程序库。而Protovis程序库在业界和学界皆有一定的知名度[3]

      2011年,史丹佛可视化团队停止开发Protovis,并开始开发新的资料可视化程序库,借由之前开发Protovis的经验,开发出了D3.js程序库,在注重于Web标准的同时提供了更丰富的平台也有了更好的性能[4]

      技术原理[编辑]

      D3.js透过预先建立好迁入于网页中的JavaScript函数来选择网页元素、建立SVG元素、调整CSS来呈现资料,并且也可以设定动画、动态改变对象状态或加入工具提示来完成用户交互功能。使用简单的D3.js函数就能够将大型的数据数据结构与SVG对象进行绑定,并且能生成格式化文本和各种图表。其数据数据结构的格式可以是JSONCSV(以逗号分隔的资料)或GeoJSON,也可以透过自己写JavaScript函数来读取其他或自定义格式的资料,例如Shapefile[5]

      对象选择[编辑]

      D3.js所使用的对象选择方式是透过使用CSS样式选择器来选择一个或多个或一组文档对象模型对象,然后透过类似jQuery的方式控制所选的对象[6]。例如,选择所有的<p>...</p>网页元素,将之改成方形类别、移动位置、并更换颜色为淡紫色在D3.js中只要使用简单的代码即可完成:

       d3.selectAll("p")                 // 選擇所有 <p> 網頁元素
         .style("color", "lavender")     // 將顏色 "color" 樣式改成 "lavender" 淡紫色 (薰衣草色)
         .attr("class", "squares")       // 將 "class" 改成 "squares"
         .attr("x", 50);                 // 將屬性值 "x" (水平位置) 改為 50px
      

      动态改变对象状态[编辑]

      透过D3.js定义的对象成员函数function transition (name)则可以在一定时间内平滑地改变对象的属性或样式的值,例如可以在500毫秒内逐渐将所有的<p>...</p>网页元素渐变为粉红色

       d3.selectAll("p")             // 選擇所有 <p> 網頁元素
         .transition("trans_1")      // 定義一個transition,命名為"trans_1"
           .delay(0)                 // 觸發後延遲0毫秒後開始動畫
           .duration(500)            // 漸變時間500毫秒
           .ease(d3.easeLinear)           // 使用線性漸變,並且....
         .style("color", "pink");    // ...並且最終變為粉紅色
      

      资料绑定[编辑]

      File:D3 Example Data-binding.svg
      左边的代码渲染的结果

      D3.js有提供一高级应用例如设定与对象相关系,或者将加载的资料直接绘成对象。在D3.js中,可以将资料与对象绑定,如此一来,当资料读入之后根据资料产生对应具有相关的属性(形状、颜色或数值等)和行为(动画或事件等)的SVG对象[7][8][9]

      // 資料
        var countriesData = [
           { name:"Ireland",  income:53000, life: 78, pop:6378, color: "black"},
           { name:"Norway",   income:73000, life: 87, pop:5084, color: "blue" },
           { name:"Tanzania", income:27000, life: 50, pop:3407, color: "grey" }
        ];
      // 建立svg網頁物件
        var svg = d3.select("#hook").append("svg")
              .attr("width", 120)
              .attr("height", 120)
              .style("background-color", "#D0D0D0");
      // 從資料建立關聯的svg網頁元素
          svg.selectAll("circle")                  // 建立還不存在的圓形樣板
            .data(countriesData)                   // 綁定資料
          .enter()                                 // 對每個資料......
            .append("circle")                      // 綁定資料列中的......資料到圓形
              .attr("id", function(d) { return d.name })            // 圓形的id為國家名
              .attr("cx", function(d) { return d.income / 1000  })  // 圓形的x坐標位置為收入
              .attr("cy", function(d) { return d.life })            // 圓形的y坐標位置為預期收入
              .attr("r",  function(d) { return d.pop / 1000 *2 })   // 圓形的半徑為國家人口數
              .attr("fill", function(d) { return d.color });        // 給表示不同國家的圓形不同顏色
      

      资料读取[编辑]

      File:Emojione BW 1F5FE.svg
      左边的代码渲染结果示意图。直接将地理信息透过D3.js转为SVG而未进行设定时,将会显示为未设定颜色(默认黑色)的地图。透过上述其他方法亦可完成各类交互式图表等相关应用。

      D3.js除了有提供将加载的资料直接绘成对象的功能之外,也支持从文件读取资料并直接生成SVG图像。此应用使得D3.js可以用简单的代码完成与地理信息相关的资料可视化,而新版本的D3.js也改善了地理座标的转换系统[10],因此能准确地呈现包含地理信息的图表,例如“japan.json”中存了日本GeoJSON地理信息,则D3.js可以直接并加载并显示日本地图:

      d3.json("japan.json", function(topodata) {//載入JSON檔案
      	var features = topojson.feature(//從GeoJSON中取出日本地形
      		topodata, 
      		topodata.objects["japan"]
      	).features;
      	var path = d3.geo.path().projection( 
      		d3.geo.mercator()
      		.center([138,37])	//指定為日本經緯度位置
      		.scale(6000) 		//放大至符合圖形大小
      	);
      	d3.select("svg")
      		.selectAll("path")	// 建立還不存在的路徑物件樣板
      		.data(features)		// 綁定日本地形資料
      		.enter()		// 對所有的物件.....
      		.append("path")		// 插入路徑物件
      		.attr("d",path);	// 路徑物件的路徑依照日本經緯度位置填入地形資料
      });
      

      然而许多政府机关提供的文件皆为Shapefile,而由于D3.js也可以透过自己写JavaScript函数或引用他第三方程式库来读取其他例如Shapefile的资料[5]

      		//需先引入Shapefile庫
      shapefile.open("japan.shp")		//載入日本的Shapefile檔案
        .then(source => source.read()
          .then(function log(result) {	//若Shapefile載入完畢
            if (result.done) return;
            console.log(result.value);	//印出載入到的地理資訊
            //下同
          }))
        .catch(error => console.error(error.stack));
      

      根据资料产生节点[编辑]

      当文件顺利读入并与D3.js对象绑定之后,一般D3.js在使用上基本上会明确地用.enter()函数、暗示更新的函数以及.exit()函数来调用资料集中范围内的资料,其中,d3.js没有“update()”函数,需要自行时做对应功能来完成enter、update以及exit流程[11]。接在.enter()函数后方的指令会作用在所有资料上并设定到前一段指令selectAll()选择的网页元素中所有未就绪的网页元素。[12]

      其他特色[编辑]

      除了D3.js之外亦有许多可以抓取并处理资料的程序库,例如jQuery,但D3.js与jQuery不同于,D3.js使用了数据驱动化来更有效地处理资料,例如,原先使用循环来处理资料,并且要预先把网页元素产生出来,而D3.js则可以使用select或selectAll来批量完成资料处理,并会会视情况自动生成所需的网页元素,而使得网页有更多的弹性,也能支持能动态地即时地作出反应的交互性功能[13]

      相关程序库[编辑]

      Three.js[编辑]

      D3.js可以与Three.js结合,透过结合了D3.js的资料可视化、图表产生与Three.js的WebGL特性可以实现三维资料可视化、图表的呈现[14]

      参考文献[编辑]

      1. ^ 引用错误:没有为名为d3 Releases的参考文献提供内容
      2. ^ Websites using D3. Wappalyzer. [2018-09-11]. (原始内容存档于2018-09-11). 
      3. ^ Academic example: Savva, Manolis; Kong, Nicholas; Chhajta, Arti; Li, Feifei; Agrawala, Maneesh; Heer, Jeffrey, ReVision: Automated Classification, Analysisand Redesign of Chart Images, ACM User Interface Software & Technology, 2011 [2013-01-23], (原始内容存档于2018-04-04) 
      4. ^ 4.0 4.1 Bostock, Michael; Ogievetsky, Vadim; Heer, Jeffrey, D3: Data-Driven Documents, IEEE Transactions on Visualization and Computer Graphics (IEEE Press), October 2011, 17 (12): 2301–2309 [2018-09-11], PMID 22034350, doi:10.1109/TVCG.2011.185, (原始内容存档于2018-09-05) 
      5. ^ 5.0 5.1 Streaming Shapefile Parser. [2018-09-12]. (原始内容存档于2018-08-15). 
      6. ^ Bostock, Ogievetsky & Heer 2011[4], chap. 3
      7. ^ Bostock, Mike, Thinking with Joins, 2012-02-05 [2018-09-12], (原始内容存档于2014-05-28) 
      8. ^ A Pen by Lopez Hugo. Codepen.io. [2016-08-01]. (原始内容存档于2016-03-22). 
      9. ^ Edit fiddle. JSFiddle.net. [2016-08-01]. (原始内容存档于2016-12-28). 
      10. ^ 李建兴. D3.js 5.0釋出,支援非同步樣版、導入專業資料配色法. ithome.com. 2018-04-18 [2018-09-16]. (原始内容存档于2018-09-16). 
      11. ^ SVG D3.js - Enter、Update 和 Exit. oxxostudio.tw. 2015-09-17 [2018-10-06]. (原始内容存档于2018-10-06). 
      12. ^ Three Little Circles. Mbostock.github.io. [2016-08-01]. (原始内容存档于2016-07-19). 
      13. ^ 何宗谕. 初探D3.js ─ 資料視覺化的利器. 计算机及信息网络中心电子报 (台湾大学). 2017-03-20, 第0040期 [2018-09-16]. ISSN 2077-8813. (原始内容存档于2018-02-02). 
      14. ^ sghall. D3Three.js. github.com. [2018-09-13]. (原始内容存档于2018-06-11). 

      延伸阅读[编辑]

      D3.js入门相关文章
      D3.js高级相关文章
      其他D3.js相关文章
      影片资源

      外部链接[编辑]