2016-04-14
本篇文章談?wù)?d3 的動畫、svg 圖形生成器以及 d3 提供的 layout
一、動畫
1. 鼠標 hover ,顯示當前坐標
- 使用 .on() 為圖表添加交互
- 當前 this 指向的 d3 對象:
d3.select(this)
- 事件對象:
d3.event
- 常用事件 'mouseover', 'mouseout'
2. 為圖表添加動畫
代碼如下:
circles.transition()
// 為每個結(jié)點按序增加延遲時間,達成依次出現(xiàn)的效果
.delay(function(d, i){
return i * 10;
})
// 動畫總時長
.duration(100)
// 更新樣式
.attr(circleAttrs);
更新樣式:
- 坐標 從原點移至 x, y
- 半徑 從小變大
3. 新增結(jié)點,動態(tài)更新比例尺
- 返回當前鼠標坐標:
var coods = d3.mouse(this);
- 反向獲取比例尺的值:
xScale.invert()
- 更新 data 數(shù)組
data.push(obj)
; - 更新比例尺的
domain 區(qū)間
- 更新坐標軸 重新
.call(xAxis)
二、Layout
什么是 layout?
layout 的作用是將數(shù)據(jù)轉(zhuǎn)成適合繪圖的結(jié)構(gòu),d3 提供了多種 layout, 如:Pie, Tree, Force, Partition, Cluster, Bundle 等等。更多介紹...
下面以繪制樹形圖為例:
{% highlight javascript %}
var tree = d3.layout.tree().size([degree, radius]);
// 得到結(jié)點數(shù)據(jù)
var nodeData = tree.nodes(data);
// 得到連線數(shù)據(jù)
var linkData = tree.links(nodeData);
{% endhighlight %}
1. 數(shù)據(jù)轉(zhuǎn)換
parent
和 children
指針,聯(lián)系著各個對象。
2. 生成曲線
{% highlight javascript %}
var diagonal = d3.svg.diagonal.radial()
// 點變換器
.projection(function(d){
return [d.y, d.x/180* Math.PI];
});
{% endhighlight %}
設(shè)置結(jié)點之間連線的形式,d3.svg.diagonal.radial()
調(diào)用徑向?qū)蔷€生成器。
對角線生成器:輸入兩個頂點坐標,生成一條貝塞爾曲線。
3. 移動
由于繪制后的樹形圖是以左上角為原點,向上展開的。故定位時需要做旋轉(zhuǎn)。
translate()
, rotate()
- 初始化時,位于左上角;
- 整體 y 軸向下移動;
- 結(jié)點右移,注意到此時葉子結(jié)點是重合的(即 “曹丕”、“曹植”);
- 整體順時針旋轉(zhuǎn);
- 結(jié)點逆時針旋轉(zhuǎn),回到水平線。
補充:
其中 .size([degree, radius]
設(shè)定范圍,通過設(shè)置樹形開口的角度以及延伸半徑長度。
a. 角度
b. 半徑
c. 為啥要叫 “半徑”?設(shè)置角度為 360 度后,便一目了然了
三、圖形生成器
圖形生成器是 d3 提供的一個非常好用的功能,通過輸入數(shù)據(jù),生成繪制 SVG 圖形所需要的格式。
如以折線舉例:
圖中 7 個點數(shù)據(jù)如下:
使用 d3 提供的 line 生成器,d3.svg.line()
, 便可把數(shù)據(jù)整合成繪制 path 所要的格式了,即添加 M, L, Z 等。
<path
d="M0,500 L125,500 L250,500 L375,500 L500,500 L625,500 L750,500 L750,0 L625,125 L500,187.5 L375,237.5 L250,262.5 L125,312.5 L0,375Z" >
</path>
常用圖形生成器有:
// 折線
d3.svg.line()
.x()
.y()
// 區(qū)域
d3.svg.area()
.x0()
.x1()
.y0()
.y1()
// 坐標軸
d3.svg.axis()
.scale()
.orient()
.ticks()
// 弧形
d3.svg.arc()
.innerRadius()
.outerRadius()
四、其他
發(fā)現(xiàn)的一些技巧
- 使用 tickSize(-config.height) 來繪制分割細線;
-
shape-rendering: crispEdges;
使得數(shù)軸和刻度線精確到像素級 - 一種簡化寫法
- '(' + [margin.left, margin.top] + ')' 強制類型轉(zhuǎn)換時,自動會轉(zhuǎn)成 '( margin.left, margin.top )' 形式;
- 最佳實踐: 設(shè)置屬性應(yīng)當與設(shè)置動畫分離開來