iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
1
AI & Data

D3.js資料視覺化的浪漫突進系列 第 26

Day26 D3js 浪漫復刻ExpertOption的養眼圖表

  • 分享至 

  • xImage
  •  

D3js 浪漫復刻ExpertOption的養眼圖表

用途

在以往實現d3圖表時,多半是功能優先,可能在漸變處理以及外觀樣式比較不那麼苛求,因次復刻了一個之前接觸過的二元期權的首頁,試著美化d3圖表

復刻對象ExpertOption

構成列表

  • 基本Scale
  • Path需要隨著時間移動
  • Area需要隨著時間移動
  • Circle(漸變)並需要隨著最新值移動
  • 其他裝飾

Scale

n為圖表上會存在的點為數量,假定為40。因此整個資料長度最大值為40,也就是xScaledomain會從0-39(40個)

let xScale = d3.scaleLinear()
                .domain([0, n - 1])
                .range([0, width]);

let yScale = d3.scaleLinear()
                .domain([-200, 200])
                .range([height, 0])
                .nice();

Area

d3.curveCatmullRom.alpha(0.1)為線段弧度,讓我們的圖表看起來圓潤一點。
y0 - y1為整個Area垂直的範圍。

let area = d3.area()
    .x((d, i) => xScale(i))
    .y1(d => yScale(d))
    .y0(d => yScale(-200))
    .curve(d3.curveCatmullRom.alpha(0.1));

Line

d3.curveCatmullRom.alpha(0.1)為線段弧度,讓我們的圖表看起來圓潤一點。

let line = d3.line()
              .x((d, i) => xScale(i))
              .y((d, i) => yScale(d))
              .curve(d3.curveCatmullRom.alpha(0.1));

defs

這是遮罩,用來讓我們隱藏超出我們期待邊界的部分。

使用方法:selection.attr("clip-path", "url(#clip)"),設定屬性clip-pathurl(指定隱藏圖層ID)

rootLayer.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height)

漸層色

漸變色是指向是Line的顏色,Area的顏色,因為是漸層變化,而且在svg元件上,我都是使用圖層的方式蓋上顏色。

此部分漸變色由於並沒有動態因變數而改變,所以直接寫在靜態html上。

使用方法

HTML

<defs>
    <linearGradient id="lineColor">
    <stop offset="100%" stop-opacity="0.7" stop-color="#2D9FF8"></stop></linearGradient>
</defs>
<defs>
    <linearGradient id="areaColor" x1="0" x2="0" y1="0" y2="1">
        <stop offset="0%" stop-opacity="0.7" stop-color="#315B90"></stop>
        <stop offset="50%" stop-color="#315B90" stop-opacity="0.4"></stop>
        <stop offset="100%" stop-color="#315B90" stop-opacity="0"></stop>
    </linearGradient>
</defs>

Javascript
透過url(#ID)指定要使用的圖層ID

let lines = linesLayer
        .append('path')
        .datum(data)
        .attr('class', 'line')
        .attr('stroke-width', 5)
        .attr('d', line)
        .attr('stroke', 'url(#lineColor)')

let areas = linesLayer
        .append('path')
        .datum(data)
        .attr('class', 'area')
        .attr('d', area)
        .attr('fill', 'url(#areaColor)');

移動原理

移動原理其實就是透過transform="translate"進行移動,每一個間隔時間會往左側移動一個單位,當移動到位置時,會重置位置。因此從外部看來,就像是一直往左側移動。而也因此在重置時會繪製新的線段,造成看起來好像示意圖一樣,無限的往左設滑動,其實只是一直重新繪製線段外加往左側移動。

部分程式碼

以下tick觸發時間為圖層準備開始動作時。

function tick() {
  data.push(random()); // 推入一筆資料
  
  // 重新繪製線段
  lines
    .attr('d', line)
    .attr("transform", null);
  
  // 重新繪製區塊
  areas
    .attr('d', area)
    .attr("transform", null);
  
  linesLayer
    .attr("transform", null) // 先將位移歸零重置
    .transition()            // 設定漸變
    .duration(1500)          // 時間1.5s
    .ease(d3.easeLinear)     // 平滑移動
    .attr("transform", "translate(" + xScale(-1) + ",0)") // 漸變時間1.5s置`xScale(-1)`的位置
    .on('end', tick) // 結束時觸發下一次`tick`,如此看起來會像是無限往左。
    
  data.shift();
}

其餘裝飾

其餘裝飾為title, html, css相關較不重要,至於會跟著最新值走的球,其實也只是跟著random出來的資料並使用yScale算出對應的位置,漸變時間設定與LinesLayer時間一樣即可。並固定x在最後。

結論

找一個現成的圖表仿製真的滿有趣的,雖然不清楚ExpertOption以及這種透資方是到底是不是正當的,他們的圖表功能做的真的挺完整的。

如果想詳細了解復刻圖表的Code請至Codepen

Codepen範例

參考

Mike Path Transitions
ExpertOption


上一篇
Day25 D3js d3-tip 好用的小工具
下一篇
Day27 D3js 動畫事件小技巧
系列文
D3.js資料視覺化的浪漫突進30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言