久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

JS開發(fā)實現(xiàn)數(shù)據(jù)可視化的十大經(jīng)典案例!

 wenxuefeng360 2022-11-05 發(fā)布于四川
  • 2016-08-16 09:46:56

  • 基于 D3.js ,,編寫 HTML,、SVG 和 CSS 就能讓你的數(shù)據(jù)變得生動起來,這是一個基于數(shù)據(jù)操作 DOM 的 JavaScript 庫,。


    我看來,,每一位 Web 開發(fā)者最應(yīng)該學(xué)習(xí)的三個 JavaScript 庫就是 jQuery,、Underscore 和 D3。在學(xué)習(xí)它們的過程中,,你將會從新的角度去思考如何寫代碼:jQuery 讓你知道如何用盡量少的代碼,,盡可能多地操作 DOM;Underscore (或者稱之為 lodash)用函數(shù)式的工具改變你寫程序的方式,;而 D3 給了你大量的操作數(shù)據(jù)的工具,,以及圖形化編程的思想。如果你還不了解 D3,,請花一些時間看看它的例子,,體會一下 D3 能做到什么。

    這可不是你老爸的圖表庫,。

    D3 有極高的靈活性,,它是一個比較基礎(chǔ)的可視化 js 庫,api 和 jQuery 很像,,可以把數(shù)據(jù)和 HTML 結(jié)構(gòu)或者 SVG 文檔對應(yīng)起來,。D3 有豐富的數(shù)學(xué)函數(shù)來處理數(shù)據(jù)轉(zhuǎn)換和物理計算,它擅長于操作 SVG 中的路徑 (path) 和幾何圖形 (circle,、ellipse,、rect…)。

    這篇文章旨在給讀者一個 D3 的概覽,,在接下來的例子里,,你會看到輸入的數(shù)據(jù)、數(shù)據(jù)變換和最后的輸出文檔,。我將不會解釋逐個函數(shù)做了什么,,我會把代碼展示給你看,希望從中你能知道大致這些代碼是怎么工作的,。只有在 Scales 和 Selections 的部分我才會重點解釋,。

    柱狀圖

    圖片描述

    codepen中查看代碼

    我說過在 D3 中,你能使用到的圖表遠比 Playfair 先生發(fā)明過的要多,,但是學(xué)跑前先走好路,,我們從最簡單的柱狀圖開始,,了解一下 D3 是怎么將數(shù)據(jù)和文檔流結(jié)合在一起的:

    d3.select('#chart')
      .selectAll("div")
      .data([4, 8, 15, 16, 23, 42])
      .enter()
      .append("div")
      .style("height", (d)=> d + "px")

    selectAll 方法返回了一個 D3 selection。D3 selection 是一個數(shù)組,,當針對一個數(shù)據(jù)點創(chuàng)建一個 div ,,然后通過 enter() 和 append() 調(diào)用這個 div 時,selection 中的元素就會被創(chuàng)建出來,。

    上述代碼中的輸入數(shù)據(jù)是一組數(shù)組:[4, 8, 15, 16, 23, 42],,對應(yīng)的輸出 HTML 結(jié)構(gòu)是:

    <div id="chart">
      <div style="height: 4px;"></div>
      <div style="height: 8px;"></div>
      <div style="height: 15px;"></div>
      <div style="height: 16px;"></div>
      <div style="height: 23px;"></div>
      <div style="height: 42px;"></div>
    </div>

    所有不需要通過 JS 控制的視覺層內(nèi)容都寫到 CSS 中:

    #chart div {  display: inline-block;  background: #4285F4;  width: 20px;  margin-right: 3px;}

    GitHub 貢獻表

    只需要更改柱狀圖代碼中的幾行,,我們就能得到一個 GitHub 貢獻表,。

    圖片描述

    codepen中查看代碼

    和柱狀圖不同地方在于,圖表中根據(jù)數(shù)據(jù)變化的不再是元素的高度,,而是元素的 background-color (背景色),。

    const colorMap = d3.interpolateRgb(
      d3.rgb('#d6e685'),
      d3.rgb('#1e6823')
    )
    
    d3.select('#chart')
      .selectAll("div")
      .data([.2, .4, 0, 0, .13, .92])
      .enter()
      .append("div")
      .style("background-color", (d)=> {return d == 0 ? '#eee' : colorMap(d)
      })

    colorMap 函數(shù)接收的輸入值要在0到1之間,返回的是一個顏色值,,這個值是在以輸入值中兩兩數(shù)據(jù)為顏色值之間的漸變色值,。插值法是圖形編程和動畫的關(guān)鍵點。在后面我們將會看到更多這方面的例子,。

    SVG

    D3 最大的魅力大概來自于它能應(yīng)用在 SVG 上,,也就是說平面圖形比如圓形、多邊形,、路徑和文本,,它都可以交互。 
    圖片描述

    <svg width="200" height="200">
      <circle fill="#3E5693" cx="50" cy="120" r="20" />
      <text x="100" y="100">Hello SVG!</text>
      <path d="M100,10L150,70L50,70Z" fill="#BEDBC3" stroke="#539E91" stroke-width="3"></svg>

    上述代碼實現(xiàn)的是:

    • 一個圓心在 (50,120),,半徑是 20 的圓形;

    • 一段位于 (100,100) 的文本;

    • 一個 3px 粗邊的三角形,,d 指的是方向,從點 (100,100) 畫線到點 (150,170) 再到點 (50,70) 結(jié)束

    可以算是 SVG 中很好用的元素了,。

    圓形

    圖片描述

    codepen中查看代碼

    上面的例子中給出的數(shù)據(jù)結(jié)構(gòu)是很簡單的一組數(shù)據(jù),,D3 的能力遠不止于此,它還可以操作更復(fù)雜的數(shù)據(jù)類型,。

    const data = [{  label: "7am",  sales: 20
    },{  label: "8am",  sales: 12
    }, {  label: "9am",  sales: 8
    }, {  label: "10am",  sales: 27
    }]

    對每一個數(shù)據(jù)點,,我們都將有一個 g (組)元素在 #chart 中,根據(jù)對象的屬性,,每個組里會有一個 元素和一個 元素,。

    下面的代碼將輸入數(shù)據(jù)和 SVG 文檔一一對應(yīng)起來,你能看出它的原理嗎,?

    <svg height="100" width="250" id="chart">
      <g><circle cy="40" cx="50" r="20"/><text y="90" x="50">7am</text>
      </g>
      <g><circle cy="40" cx="100" r="12"/><text y="90" x="100">8am</text>
      </g>
      <g><circle cy="40" cx="150" r="8"/><text y="90" x="150">9am</text>
      </g>
      <g><circle cy="40" cx="200" r="27"/><text y="90" x="200">10am</text>
      </g></svg>

    折線圖

    圖片描述

    codepen 中查看代碼

    用 SVG 實現(xiàn)折線圖再簡單不過,,我們將下面這些數(shù)據(jù):

    const data = [
      { x: 0, y: 30 },
      { x: 50, y: 20 },
      { x: 100, y: 40 },
      { x: 150, y: 80 },
      { x: 200, y: 95 }
    ]

    轉(zhuǎn)換成以下的 SVG 文檔:

    <svg id="chart" height="100" width="200">
      <path stroke-width="2" d="M0,70L50,80L100,60L150,20L200,5"></svg>

    **注意:**SVG 代碼中的 y 值和輸入值的 y 值不同,是用 100 減去給定的 y 值,,因為在 SVG 中屏幕的左上角是 (0,0),所以在縱坐標最大值是 100 的坐標系中,,需要這么處理。

    可以這么實現(xiàn)只由一條 path 構(gòu)成的圖形:

    const path = "M" + data.map((d)=> {  return d.x + ',' + (100 - d.y);
    }).join('L');const line = `<path stroke-width="2" d="${ path }"/>`;document.querySelector('#chart').innerHTML = line;

    上面的代碼看著可麻煩了,,D3 其實提供了路徑生成函數(shù)來簡化這個步驟:

    const line = d3.svg.line()
      .x((d)=> d.x)
      .y((d)=> 100 - d.y)
      .interpolate("linear")d3.select('#chart')
      .append("path")
      .attr('stroke-width', 2)
      .attr('d', line(data))

    清爽多了,!interpolate 函數(shù)可接受不同的參數(shù),畫出不一樣的圖形,,除了 'linear’,,還可以試試看 'basis’、’cardinal’……

    圖片描述

    Scales

    Scales 函數(shù)可以將一個輸入集映射到一個輸出集中,。

    codepen中查看代碼

    上述例子所用的數(shù)據(jù)都是假數(shù)據(jù),,不會超過坐標軸所設(shè)定的范圍。當數(shù)據(jù)是動態(tài)變化的時候,,事情可就沒有這么簡單了,,你需要將輸入映射到固定范圍的輸出中,也就是我們的坐標軸,。

    假設(shè)我們有一個 500px X 200px 大小的折線圖區(qū)域,,輸入數(shù)據(jù)是:

    const data = [
      { x: 0, y: 30 },
      { x: 25, y: 15 },
      { x: 50, y: 20 }
    ]

    如果 y 軸的范圍在 [0,30],x 軸的范圍在 [0,50],,那數(shù)據(jù)就能被漂亮地呈現(xiàn)在屏幕上,。不過現(xiàn)實是,y 軸范圍在0到200,,x 軸范圍在0到500間,。

    我們可以用 d3.max 獲取到輸入數(shù)據(jù)中的最大的 x 值和 y 值,然后創(chuàng)建出對應(yīng)的 scales,。

    scale 和上面用到的顏色差值函數(shù)類似,,都是將輸入值對應(yīng)到固定的輸出范圍中。

    xScale(0) -> 0xScale(10) -> 100xScale(50) -> 500

    對于超出輸出值范圍的輸入值,,同樣適用:

    xScale(-10) -> -100xScale(60) -> 600

    在生成折線圖的代碼中 scales 可以這么使用:

    const line = d3.svg.line()
      .x((d)=> xScale(d.x))
      .y((d)=> yScale(d.y))
      .interpolate("linear")

    scales 還能讓圖形更優(yōu)雅地顯示出來,,比如加上一點間距:

    const padding = 20;const xScale = d3.scale.linear()  .domain([0, xMax])  .range([padding, width - padding])
    
    const yScale = d3.scale.linear()  .domain([0, yMax])  .range([height - padding, padding])

    現(xiàn)在可以在有動態(tài)數(shù)據(jù)集的前提下生成該集的折線圖,這條折線圖保證會在 500px X 200px 的范圍內(nèi),,并且距離該區(qū)域的四邊都有 20px 的間距,。

    線性的 scale 最常見,不過還有處理指數(shù)的 pow,、處理非數(shù)值數(shù)據(jù)(比如分類,、命名等)的 ordinal scales,除此之外還有Quantitative Scales,、Ordinal Scales 和 Time Scales,。

    比如把我的壽命當做輸入值,映射到 [0,500] 的區(qū)域內(nèi):

    const life = d3.time.scale()
      .domain([new Date(1986, 1, 18), new Date()])
      .range([0, 500])// 0 到 500 之間的哪個點才是我的 18 歲生日呢,?life(new Date(2004, 1, 18))

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多