搜尋
首頁web前端js教程在D3.js中如何實現動態進度條

在D3.js中如何實現動態進度條

Jun 04, 2018 pm 03:38 PM
javascript進度

D3是一個被資料驅動的文檔。這篇文章主要介紹了基於D3.js 繪製動態進度條的方法,需要的朋友可以參考下

D3 是什麼

D3 的全名是(Data-Driven Documents),顧名思義可以知道是一個被資料驅動的文檔。聽名字有點抽象,說簡單一點,其實就是一個 JavaScript 的函數庫,使用它主要是用來做資料視覺化的。如果你不知道什麼是 JavaScript ,請先學習 JavaScript,推薦阮一峰老師的教學。

JavaScript 檔案的字尾名通常為 .js,故 D3 也常用 D3.js 稱呼。 D3 提供了各種簡單易用的函數,大大簡化了 JavaScript 操作資料的難度。由於它本質上是JavaScript ,用JavaScript 也是可以實現所有功能的,但它能大大減少你的工作量,尤其是在資料視覺化方面,D3 已經將產生可視化的複雜步驟精簡到了幾個簡單的函數,你只需要輸入幾個簡單的數據,就能夠轉換為各種絢麗的圖形。有過 JavaScript 基礎的朋友一定很容易理解它。

在網站頁面載入以及表單提交時,常使用進度條表達載入程序來優化使用者體驗,常見的進度條有矩形進度條和圓形進度條,如下圖所示:

 

我們經常使用svg或canvas來實現動態圖形的繪製,但繪製過程相對較繁瑣。對於直觀漂亮的進度條,社區也有提供成熟的方案例如highcharts/ECharts等等,但基於配置的開發方式終究無法實現100%的自訂繪製。本文將帶你使用D3.js從零一步一步實現動態進度條,並分享程式碼邏輯原理。

基礎需求

  • #了解svg如何繪製基礎圖形

  • 了解D3.js v4版本

  • 了解如何使用D3.js (v4)繪製svg的基礎圖形

##繪製圓形進度條

對於一個圓形進度條,我們先對其進行任務拆分:

  • 繪製嵌套圓弧

  • 圓心處的即時資料展示

  • #展現動畫

  • ##設計
1.繪製巢狀圓弧

對於圓形,svg提供現成的circle 標籤供使用,但是其劣勢在於,對於圓形進度條使用circle 可以滿足,但對圖形進一步擴展時例如繪製半圓, circle 的處理就棘手了。 D3.js提供arc 相關API對圓形的繪製方法進行了封裝:

var arc = d3.arc()
   .innerRadius(180)
   .outerRadius(240)
   //.startAngle(0)
   //.endAngle(Math.PI)
arc(); // "M0,-100A100,100,0,0,1,100,0L0,0Z"

上述程式碼實作了兩個巢狀圓的繪製邏輯, d3.arc() 傳回一個圓弧建構函數,並透過鍊式呼叫設定內圓與外圓的半徑大小,起始角度與結束角度。執行 arc() 建構函式即可取得用於綁定在 上的路徑資料。完整程式碼如下:

<!--html-->
<svg width="960" height="500"></svg>
<script>
 var arcGenerator = d3.arc().innerRadius(80).outerRadius(100).startAngle(0);
 var picture = d3.select(&#39;svg&#39;).append(&#39;g&#39;).attr(&#39;transform&#39;,&#39;translate(480,250)&#39;);
</script>

上述程式碼實作了2個步驟:

1.產生0度作為起點的圓弧建構器arcGenerator

2.設定transform 圖形偏移量,讓圖形在畫布中央

目前畫布上還沒有任何元素,接下來我們實際圖形的繪製。

var backGround = picture.append("path")
  .datum({endAngle: 2 * Math.PI})
  .style("fill", "#FDF5E6")
  .attr("d", arcGenerator);

我們將畫布picture 新增 元素,依據endAngle() 特性,使用datum() 方法將{endAngle:Math.PI} 也就是終點角度2π 綁定到 元素上,並將圓弧構造器賦值給path 路徑d 。這樣就產生了指定背景顏色的圓弧,實際圖形如下:

第一個圓弧畫好了,那麼依據svg的層級關係z-index ,所謂的進度條其實就是覆蓋在第一層圓弧之上的第二層圓弧。同理可得:

var upperGround = picture.append(&#39;path&#39;)
  .datum({endAngle:Math.PI / 2})
  .style(&#39;fill&#39;,&#39;#FFC125&#39;)
  .attr(&#39;d&#39;,arcGenerator)

程式碼執行後可得:

 

2.圓心處的即時資料展示

第一部分我們已經實作了基於兩個path 的巢狀圓。第二部分我們來實現圓心處的即時數據展示。在進度條進行載入時,我們在圓心處新增資料來表達目前的載入進度,使用 標籤做展示即可:

var dataText = g.append(&#39;text&#39;)
  .text(12)
  .attr(&#39;text-anchor&#39;,&#39;middle&#39;)
  .attr(&#39;dominant-baseline&#39;,&#39;middle&#39;)
  .attr(&#39;font-size&#39;,&#39;38px&#39;)

#暫時設定資料為12,設定水平置中垂直置中,效果如下圖:

 

3.展現動畫

通过1,2两部分内容我们已经知道了:

  • 绘制进度条的实质是改变上层弧的角度

  • 当弧度是 2π 时为整圆,当弧度是 π 时为半圆

  • 圆形中的数据即为当前弧度相对 2π 的百分比

综上我们只要改变弧度值和数值同时设定改变过程所需时长即可实现所谓"动画"。在ECharts提供的官方实例中,通过 setInterval 来实现每隔固定一段时间进行数据更新,其实在D3.js中同样提供了类似方法来实现类似 setInterval 的功能:

d3.interval(function(){
 foreground.transition().duration(750).attrTween(&#39;d&#39;,function(d){
  var compute = d3.interpolate(d.endAngle,Math.random() * Math.PI * 2);
  return function(t){
   d.endAngle = compute(t);
   return arcGenerator(d);
  }
  
 })
},1000)

对这段代码进行拆解:

  • d3.interval() 方法提供了 setInterval() 的功能

  • selection.transition.duration() 设置了当前DOM属性过渡变化为指定DOM属性的过程所需时间,毫秒为单位

  • transation.attrTween 为插值功能API,那么何谓插值?

概括来说,在给定的离散数据中补插函数,可以使这条连续函数通过全部数据点。举个例子,给定一个p,想实现其背景颜色的从左边红(red)到右边绿(green)的线性渐变,每一区域的色值该如何计算呢?只需:

var compute = d3.interpolate(d3.rgb(255,0,0),d3.rgb(0,255,0));

compute 即为插值函数,参数范围为[0,1],只要你输入该范围内的数字,那么 compute 函数将返回对应的颜色值。这样的插值有什么用呢?可看下图:

 

假设上图的p长度width为100,那么将[0,100]依比例关系转化为[0,10]的范围数据并输入 compute 函数中,即可得到某一区域对应的颜色。当然,对于线性面积的处理我们不应该使用离散数据作为输入和输出,所以D3.js提供更方便的线性渐变API d3.linear 等,这里就不展开描述了。

言归正传,代码 d3.interpolate(d.endAngle,Math.random() * Math.PI * 2); 实现了如下插值范围:

["当前角度值","随机角度值"] //表达区间而非数组

而后返回一个参数为 t 的函数,那么该函数的作用是什么呢?

t 参数与 d 类似,是D3.js内部实现的插值,其范围为[0,1]。 t 参数根据设置的 duration() 时长自动计算在[0,1]内合适的插值数量,并返回插值结果,实现线性平稳的过渡动画效果。

完成滚动条的动画加载效果,我们接下来写圆心实时数据的变化逻辑,只要实现简单的赋值即可,完整代码如下:

d3.interval(function(){
  foreground.transition().duration(750).attrTween(&#39;d&#39;,function(d){
   var compute = d3.interpolate(d.endAngle,Math.random() * Math.PI * 2);
   return function(t){
    d.endAngle = compute(t);
    var data = d.endAngle / Math.PI / 2 * 100;
    //设置数值
    d3.select(&#39;text&#39;).text(data.toFixed(0) + &#39;%&#39;);
    //将新参数传入,生成新的圆弧构造器
    return arcGenerator(d);
   }
  })
 },2000)

最终效果如下:

 

4.美化

1,2,3部分我们实现了最基本的进度条样式和功能,但样式看起来还是很单调的,我们接下来我们对进度条进行线性渐变处理。我们使用D3.js提供的线性插值API:

var colorLinear = d3.scaleLinear().domain([0,100]).range(["#EEE685","#EE3B3B"]);

colorLinear 同样是一个插值函数,我们输入[0,100]区间中的数值,就会返回对应["#EEE685","#EE3B3B"]区间内的颜色值。比如当进度条显示进度为"80%"时:

var color = colorLinear(80);
//color即为"80%"对应的色值

实现了颜色取值后,我们只需在进度条变化时,将原有颜色改变即可:

d3.interval(function(){
  foreground.transition().duration(750).attrTween(&#39;d&#39;,function(d){
   var compute = d3.interpolate(d.endAngle,Math.random() * Math.PI * 2);
   return function(t){
    d.endAngle = compute(t);
    var data = d.endAngle / Math.PI / 2 * 100;
    //设置数值
    d3.select(&#39;text&#39;).text(data.toFixed(0) + &#39;%&#39;);
    //将新参数传入,生成新的圆弧构造器
    return arcGenerator(d);
   }
  })
  .styleTween(&#39;fill&#39;,function(d){
   return function(t){
    var data = d.endAngle / Math.PI / 2 * 100;
    //返回数值对应的色值
    return colorLinear(data);
   }
  })
 },2000)

styleTween 与 attrTween 类似,是实现改变样式的插值函数。采用链式调用的形式同时对进度条数值和颜色的设置即可。最终实现的效果如下:

 

综上我们实现了在不同数值下颜色变化的圆形进度条,可常用于告警,提醒等业务场景。

绘制矩形进度条

矩形进度条相比圆形进度条简单了很多,同样基于插值原理,平滑改变矩形的长度即可。直接上代码:

<head>
 <style>
  #slider {
   height: 20px;
   width: 20px;
   background: #2394F5;
   margin: 15px;
  }
 </style>
</head>
<body>
 <p id=&#39;slider&#39;></p>
 <script>
  d3.interval(function(){
   d3.select("#slider").transition()
    .duration(1000)
    .attrTween("width", function() {
     var i = d3.interpolate(20, 400);
     var ci = d3.interpolate(&#39;#2394F5&#39;, &#39;#BDF436&#39;);
     var that = this;
     return function(t) {
      that.style.width = i(t) + &#39;px&#39;;
      that.style.background = ci(t);
     };
    });
  },1500)
 </script>
</body>

实现的效果如下:

 

总结

基於D3.js繪製進度條的關鍵點在於插值,從而正確地使圖形平滑過渡。如果一定要使用svg或純css實現矩形和圓形的進度條當然也是可行的,但對於路徑和動畫的處理,以及css的書寫要求都複雜了不少。我們觀察到使用D3.js繪製上述兩種進度條的邏輯程式碼幾乎完全使用js實現,同時程式碼量可以控制在20行左右並可封裝復用,已經非常精煉了,在自訂圖表開發上非常有優勢。

對於進度條的衍生版儀錶板圖表,相比基礎進度條增加了刻度描述和指針計算,但萬變不離其宗,只要掌握插值原理和使用,處理類似圖表都將得心應手。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

基於express中路由規則及取得請求參數的方法

##js提取中文拼音首字母的封裝工具類別_javascript技巧

詳解vuex的簡單使用

################# ####

以上是在D3.js中如何實現動態進度條的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。