最近公司有需求要做一些可視化的功能。之前一直都是用Echarts做的,但是Echarts現在滿足不了我們的需求,經過多方請教,查找發現只有D3可以滿足我們的需求,而且可以完美的適用到react框架中。第一次接觸到D3,發現這些圖標的可交互性非常豐富,而且動畫流暢簡潔。 所以,打算學習D3並且應用到項 ...
最近公司有需求要做一些可視化的功能。之前一直都是用Echarts做的,但是Echarts現在滿足不了我們的需求,經過多方請教,查找發現只有D3可以滿足我們的需求,而且可以完美的適用到react框架中。第一次接觸到D3,發現這些圖標的可交互性非常豐富,而且動畫流暢簡潔。 所以,打算學習D3並且應用到項目中。 原本以為D3也會和其他可視化庫類似,只需要找到與自己需要的圖表類似的圖表進行粘貼,複製。然後簡單的修改數據或者參數就可以達到自己使用的目的,結果總是差強人意....
從最基礎圖形學起 : 一、矩形
矩形又分為直角矩形和圓角矩形
代碼 :
1 矩形的參數共6個 2 x : 矩形左上角的x坐標。 3 y : 矩形左上角的y坐標。 4 width : 矩形的寬度。 5 height : 矩形的高度。 6 rx : 對於圓角矩形,指定橢圓在x方向的半徑。 7 ry : 對於圓角矩形,指定橢圓在y方向的半徑。 8 fill : 填充色 改變文字<text>的顏色也用這個。 9 storke : 輪廓線的顏色。 10 stroke-width : 輪廓線的寬度。 11 opacity : 透明度 12 13 <!-- 直角矩形 --> 14 <svg width="300" height="200" version="1.1"> 15 <rect x="20" y="20" width="200" height="100" 16 style="fill:steelblue;stroke:blue;stroke-width: 4;opacity: 0.4" /> 17 </svg> 18 19 20 <!-- 圓角矩形 --> 21 <svg width="300" height="200"> 22 <rect x="20" y="20" width="200" rx="20" ry="30" height="100" 23 style="fill:yellow;stroke:black;stroke-width:4;opacity:0.5" /> 24 </svg>
顯示的效果 :
二、圓形和橢圓形
代碼 :
1 圓形的參數有3個 : 2 cx : 圓形的x坐標。 3 cy : 圓形的y坐標。 4 r : 圓的半徑。 5 橢圓的參數與圓形類似,只是半徑分為水平半徑和垂直半徑 : 6 cx : 圓形的x坐標。 7 cy : 圓形的y坐標。 8 rx : 橢圓的水平半徑。 9 ry : 橢圓的垂直半徑。 10 11 <!-- 圓形 --> 12 <svg width="300" height="200"> 13 <circle cx="150" cy="100" r="60" 14 style="fill:yellow;stroke:black;stroke-width:4" /> 15 </svg> 16 <!-- 橢圓形 --> 17 <svg width="300" height="200"> 18 <ellipse cx="100" cy="100" rx="90" ry="50" 19 style="fill:blue;stroke:black;stroke-width:4" /> 20 </svg>
效果 :
三、線段
代碼 :
1 線段的參數是起點坐標和終點坐標 : 2 x1 : 起點的x坐標。 3 y1 : 起點的y坐標。 4 x2 : 終點的x坐標。 5 y2 : 終點的y坐標。 6 7 <!-- 線段 --> 8 <svg width="300" height="200"> 9 <line x1="20" y1="20" x2="170" y2="120" 10 style="stroke:black;stroke-width:4" /> 11 </svg>
效果 :
四、多邊形和折線
多邊形和折線的參數是一樣的,都只有一個points參數,這個參數的值是一系列的點坐標的。不同之處是多邊形會將終點和起點連接起來,而折線不連接。
代碼 :
1 <!-- 多邊形 --> 2 <svg width="300" height="200"> 3 <polygon points="150,20 80,80 110,160 190,160 220,80" 4 style="fill:yellow;stroke:black;stroke-width:4" /> 5 </svg> 6 7 <!-- 折線 --> 8 <svg width="300" height="200"> 9 <polyline points="150,20 80,80 110,160 190,160 220,80" 10 style="fill:white;stroke:blue;stroke-width:4"/> 11 </svg>
效果 :
五、路徑
<path>標簽的功能最豐富,前面列舉的圖形都可以用路徑製作出來。與折線類似,也是通過給出一系列點坐標來繪製。其用法是 : 給出一個坐標點,在坐標點前面添加一個英文字母,表示是如何運動到此坐標點的。英文字母按照功能可分為五類 :
移動類 :
M : 等於moveto。將畫筆移動到指定坐標。
直線類 :
L : 等於lineto。 畫直線到指定坐標。
H : 等於horizontal lineto 。 畫水平直線到指定坐標。
V : 等於vertical lineto 。 畫垂直直線到指定坐標。
曲線類 :
C : 等於curveto 。 畫三次貝塞爾曲線經兩個指定控制點到達終點坐標。
S : 等於shorthand/smooth surveto 。 與前一條三次貝塞爾曲線相連,第一個控制點為前一條曲線第二個控制點的對稱點,只需輸入第二個控制點和終點,即可繪製 一個三次貝塞爾曲線。
Q : 等於quadratic Bezier curveto 。 畫二次貝塞爾曲線經一個指定控制點到達終點坐標。
T : 等於Shorthand/smooth quadratic Bezier curveto 。 與前一條二次貝塞爾曲線相連,控制點為前一條二次貝塞爾曲線控制點的對稱點,只需輸入終點,即可繪製 一個二次貝塞爾曲線。
弧線類 :
A : 等於elliptical arc 。 畫橢圓曲線到指定坐標。
閉合類 :
Z : 等於closepath 。 繪製一條直線連接終點和起點,用來封閉圖形。
上述命令都是用大寫英文字母表示,表示坐標系中的絕對坐標。也可以用小寫英文字母,表示的是相對坐標(相對當前畫筆所在點)。
1 、直線
代碼 :
1 <!-- 路徑path 繪製直線 --> 2 <svg width="300" height="200"> 3 <path d="M30,10 L270,200 4 M30,10 H300 5 M30,10 V200" style="stroke:black;stroke-width:4" /> 6 </svg>
效果 :
2、 三次貝塞爾曲線
代碼 :
1 <!-- 路徑path 繪製三次貝塞爾曲線 --> 2 <svg width="500" height="200"> 3 <path d="M30,100 4 C100,20 190,20 270,100 5 S400,180 450,100" style="fill:white;stroke:black;stroke-width:4" /> 6 </svg>
效果 :
3、二次貝塞爾曲線
代碼 :
1 <!-- 路徑path 繪製二次貝塞爾曲線 --> 2 <svg width="500" height="200"> 3 <path d="M30,100 4 Q190,20 270,100 5 T450,100" style="fill:white;stroke:black;stroke-width:4" /> 6 </svg>
效果 :
4、弧線
弧線是根據橢圓來繪製的,參數較多 :
rx : 橢圓x方向的半軸大小。
ry : 橢圓y方向的半軸大小。
x-axis-rotation : 橢圓的x軸與水平軸順時針方向的夾角。
large-arc-flag : 有兩個值(1:大角弧度線 。 0 : 小角弧度線)。
sweep-flag : 有兩個值(1:順時針至終點。 0 : 逆時針至終點)。
x : 終點x坐標。
y : 終點y坐標。
代碼 :
1 <!-- 路徑path 繪製弧線 --> 2 <svg width="500" height="400"> 3 <path d="M100,200 4 a200,150 0 1 , 0 150,-150 z" 5 style="fill:yellow;stroke:black;stroke-width:4" /> 6 </svg>
a用了小寫字母,表示相對坐標。 M代表當前位置(100,,20) 所以終點位置(100+150,200-150),即(250,50),
包含弧線的x和y方向的半徑分別為200和150,橢圓的x軸與水平軸方向夾角0度。採用大角度,逆時針方向走向終點。
Z表示閉合迴路
效果 :
六、文字
在svg中可以使用<text>標簽繪製文字,其屬性有 :
x : 文字位置的x坐標。
y : 文字位置的y坐標。
dx : 相對於當前位置在x方向上平移的距離(值為正則往右,為負往左)。
dy: 相對於當前位置在y方向上平移的距離(值為正則往上,為負往下)。
textLength : 文字的顯示長度。(不足拉長,足則壓縮)。
rotate : 旋轉角度(順時針為正,逆時針為負)。
代碼 :
1 <!-- 文字 --> 2 <svg width="300" height="200"> 3 <text x="150" y="100" dx="-5" dy="5" rotate=180" textLength="90"> 4 I Love Yangyi 5 </text> 6 </svg>
效果 :
可以為文字中某段進行設置樣式,可以使用<tspan>標簽
代碼 :
1 <!-- 文字 添加標簽<tspan></tspan> --> 2 <svg width="300" height="200"> 3 <text x="150" y="100" dx="-5" dy="5" rotate=180" textLength="90"> 4 I Love <tspan fill="red">Yangyi</tspan> 5 </text> 6 </svg>
樣式 :
七、標記
標記(marker)是svg中一個重要的概念,能貼附於<path>、<line>、<polyline>、<polygon>元素上。最經典的應用就是給線段添加箭頭。
標記<marker>寫在<defs></defs>中,defs用於定義可重覆利用的圖形元素。來看<marker>的各屬性和意義 :
viewBox : 坐標系的區域。
refX,refY : 在viewBox內的基準點,繪製時此點在直線端點上。
markerUnits : 標記大小的基準有兩個值,即storekeWidth(線的寬度)和userSpaceOnUse(線前段的大小)
markerWidth,markerHeight : 標識的大小。
orient : 繪製方向,可設定為auto(自動確認方向)和角度值。
id : 標識的id號。
繪製一條帶箭頭的直線 :
代碼 :
1 <!-- 定義一個箭頭 --> 2 <svg width="300" height="300"> 3 4 <defs> 5 <marker id="arrow" markerUnits="strokeWidth" 、 6 markerWidth="12" markerHeight="12" 7 viewBox="0 0 12 12" refX="6" 8 refY="6" orient="auto"> 9 <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill:#000000" /> 10 </marker> 11 </defs> 12 13 <!-- 調用,繪製一條帶箭頭的直線 --> 14 15 <line x1="0" y1="0" x2="200" y2="100" 16 stroke="red" stroke-width="3" 17 marker-end="url(#arrow)" /> 18 19 </svg>
效果 :
繪製一條帶箭頭的曲線
代碼 :
1 <!-- 定義一個箭頭 --> 2 <svg width="300" height="300"> 3 4 <defs> 5 <marker id="arrow" markerUnits="strokeWidth" 6 markerWidth="12" markerHeight="12" 7 viewBox="0 0 12 12" refX="6" 8 refY="6" orient="auto"> 9 <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill:#000000" /> 10 </marker> 11 </defs> 12 13 <!-- 調用,繪製一條帶箭頭的曲線 --> 14 15 <path d="M20,70 T80,100 T160,80 T200,90" 16 style="fill:white;stroke:red;stroke-width:3" 17 marker-start="url(#arrow)" 18 marker-mid="url(#arrow)" marker-end="url(#arrow)" /> 19 </svg>
marker-start : 路徑起點處。
marker-mid : 路徑中間端點處。
marker-end : 路徑終點處。
使用marker-mid,箭頭將繪製在路徑的節點處,所以對直線無效。
效果 :
八、濾鏡
濾鏡的標簽為<filter>,和標記<marker>一樣,也是在<defs>中定義的。
濾鏡的種類很多, 例如 : feMorphology、feGaussianBlur、feFlood等,還有定義光源的濾鏡feDistantLight、fePointLight、feSpotLight,都是以fe開頭的,現在例舉一個濾鏡 feGaussianBlur的用法 :
代碼 :
做了一個不帶濾鏡的矩形和一個帶濾鏡的矩形,方便大家學習。
1 <!-- 定義一個濾鏡 --> 2 3 <svg width="500" height="300"> 4 <defs> 5 <filter id="GaussianBlur"> 6 <feGaussianBlur in="SourceGraphic" stdDeviation="2" /> 7 </filter> 8 </defs> 9 <!-- 沒有帶濾鏡的矩形 --> 10 <rect x="100" y="100" width="150" height="100" fill="blue" /> 11 12 <!-- 帶濾鏡的矩形 --> 13 <rect x="300" y="100" width="150" height="100" fill="blue" filter="url(#GaussianBlur)" /> 14 15 </svg>
feGaussianBlur是一個高斯模糊的濾鏡。in是使用濾鏡的對象,此處是源圖形SourceGraphic。 stdDeviation是高斯模糊唯一的參數,數值越大,模糊程度越高。
效果 :
九、漸變
漸變表示一種顏色平滑過渡到另一種顏色。svg中有線性漸變<linearGradient>和放射性漸變<radualGraduent>。本demo為線性漸變。
漸變也是定義在<defs>標簽中的。給漸變定義一個id號,在圖形元素上指定此id號即可。
x1、y1、x2、y2 :定義漸變的方向(可水平可垂直)
offset :定義漸變開始的位置
stop-color : 定義此位置的顏色
代碼 :
此處做了一個水平漸變的矩形和一個垂直漸變的矩形
1 <!-- 定義一個漸變 --> 2 3 <svg width="800" height="200"> 4 <!-- 定義水平線性漸變 --> 5 <defs> 6 <linearGradient id="myGradient" x1="0%" y1="0%" x2="100%" y2="0%"> 7 <stop offset="0%" stop-color="blue" /> 8 <stop offset="100%" stop-color="#f00" /> 9 </linearGradient> 10 </defs> 11 <!-- 定義水平垂直線性漸變 --> 12 <defs> 13 <linearGradient id="myGradientCz" x1="0%" y1="0%" x2="0%" y2="100%"> 14 <stop offset="0%" stop-color="blue" /> 15 <stop offset="100%" stop-color="#f00" /> 16 </linearGradient> 17 </defs> 18 <!-- 水平線性漸變 --> 19 <rect x="10" y="10" width="280" height="180" fill="url(#myGradient)" /> 20 <!-- 垂直線性漸變 --> 21 <rect x="330" y="10" width="280" height="180" fill="url(#myGradientCz)" /> 22 </svg>
效果 :
以上就是一些基本圖形的demo,以後想起來其他的還會繼續補充。
接下來會做一些複雜點的圖表, 希望大家支持 ~ 謝謝。
2019-04-23