D3中對svg 分析新增 defs元素 增加each()
阿新 • • 發佈:2017-12-15
lns post size pen lips dom ... 就是 參數
each() 方法允許我們定制對選擇集中DOM元素的處理行為:
selection . each ( func )
參數 func 是調用者定義的函數,在d3中被稱為 訪問器/accessor 。 d3將對選擇集中的 每一個 DOM對象, 依次 調用該訪問器函數。
在調用 訪問器 函數時,d3會將 this 指向當前要處理的 DOM對象 , 並傳入兩個參數:
datum : 當前DOM對象對應的數據
index :當前DOM對象在集合中的序號
可以認為 訪問器 是d3流水線中每個處理環節 用戶邏輯 的封裝接口,d3通過這個接口, 實現了 流水線框架 和 用戶處理邏輯 的 解耦 :
const d3Elements = d3Svg.selectAll(‘#dangan-elements‘).data([‘elements‘]); //圖片部分
d3Elements.enter().append(‘g‘).attr(‘id‘, ‘dangan-elements‘);
// svg選中所有class為 elementName 的依次進行處理
var clipBox = d3Elements.selectAll(‘.‘+elementName).data(data).enter()
.append(‘g‘)
.classed(elementName, true)
.classed(d => ({‘dangan-click‘: d.click}))
.attr(‘clip-path‘, (d,i) => `url(#${unique+clipName+i})`)
.each(function(d) {
console.log(d);
}
SVG defs元素
SVG的<defs>元素用於預定義一個元素使其能夠在SVG圖像中重復使用。例如你可以將一些圖形制作為一個組,並用<defs>元素來定義它,然後你就可以在SVG圖像中將它當做簡單圖形來重復使用。
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<g>
<rect x="100" y="100" width="100" height="100" />
<circle cx="100" cy="100" r="100" />
</g>
</defs>
</svg>
在<defs>元素中定義的圖形不會直接顯示在SVG圖像上。要顯示它們需要使用<use>元素來引入它們。如下面的代碼所示:
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="shape">
<rect x="50" y="50" width="50" height="50" />
<circle cx="50" cy="50" r="50" />
</g>
</defs>
<use xlink:href="#shape" x="50" y="50" />
<use xlink:href="#shape" x="200" y="50" />
</svg>
要引用<g>元素,必須在<g>元素上設置一個ID,通過ID來引用它。<use>元素通過xlink:href屬性來引入<g>元素。註意在ID前面要添加一個#。
在<use>元素中,通過x和y屬性來指定重用圖形的顯示位置。註意在<g>元素中的圖形的定位點都是0,0,在使用<use>元素來引用它的時候,它的定位點被轉換為<use>元素x和y屬性指定的位置。
哪些元素可以被定義為defs中的元素呢?
任何圖形元素,如:rect,line g symbol
1.SVG中的clip-path
SVG中,有個名叫<clipPath>的元素,人如其名,其專門用來定義剪裁路徑的。舉個簡單例子:
<defs><!-- 定義 -->
<clipPath id="clipPath"><!-- 定義剪裁路徑 -->
<rect x="0" y="0" width="80" height="80" /><!-- 路徑詳細 -->
</clipPath>
</defs>
上面的<clipPath>定義了一個80*80的矩形剪裁路徑。OK,假設現在SVG中有個圓,SVG代碼如下:
<circle cx="60" cy="60" r="50" fill="#34538b" />
按照我們淺顯的認識,應該會出現一個填充某種顏色的圓。
SVG一個普通的圓
但是,如果此時該圓同時設置了clip-path屬性,且值指向的就是上面定義的剪裁路徑#clipPath呢?
<circle cx="60" cy="60" r="50" fill="#34538b" clip-path="url(#clipPath)" />
則,十五的圓被剪裁成了銀杏葉:
剪裁之後的效果
跟<g>, <symbol>等元素類似,<clipPath>元素裏面除了rect元素, 還可以是circle, ellipse, line, polyline, polygon, ...等等,甚至是text文本。
<svg>
<defs>
<clipPath id="clipPath">
<text x="10" y="50" style="font-size: 20px;">一步之遙</text>
</clipPath>
</defs>
<g style="clip-path: url(#clipPath);">
<circle cx="60" cy="60" r="50" fill="#34538b" />
<rect x="0" y="0" width="60" height="90" style="fill:#cd0000;"/>
</g>
</svg>
http://www.zhangxinxu.com/wordpress/2014/12/css3-svg-clip-path/
2. enter().append("rect").append("rect")
添加的第二個rect 是在第一個的基礎裏添加的
相當於<rect>
<rect></rect>
</rect>
例 <p>Hello World 1</p>
<p>Hello World 2</p>
<script>
var width = 300; //畫布的寬度
var height = 300; //畫布的高度
var svg = d3.select("body") //選擇文檔中的body元素
.append("svg") //添加一個svg元素
.attr("width", width) //設定寬度
.attr("height", height); //設定高度
var dataset = [ 250 , 210 , 170 , 130 , 190 ];
var rectHeight = 25; //每個矩形所占的像素高度(包括空白)
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x",20)
.attr("y",function(d,i){
return i * rectHeight;
})
.attr("width",function(d){
return d;
})
.attr("height",rectHeight-2)
.attr("fill","steelblue")
.append("rect")
.attr("x",20)
.attr("y",function(d,i){
return i * rectHeight;
});
</script>
D3中對svg 分析新增 defs元素 增加each()