在以往實現d3
圖表時,多半是功能優先,可能在漸變處理以及外觀樣式比較不那麼苛求,因次復刻了一個之前接觸過的二元期權的首頁,試著美化d3圖表
。
n
為圖表上會存在的點為數量,假定為40
。因此整個資料長度最大值為40
,也就是xScale
的domain
會從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();
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));
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));
這是遮罩,用來讓我們隱藏超出我們期待邊界的部分。
使用方法:selection.attr("clip-path", "url(#clip)")
,設定屬性clip-path
為url(指定隱藏圖層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
。
Mike Path Transitions
ExpertOption