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圖像中將它當作簡單圖形來重複使用。
<defs>
<g>
<rect x="100" y="100" width="100" height="100" />
<circle cx="100" cy="100" r="100" />
</g>
</defs>
</svg>
在<defs>元素中定義的圖形不會直接顯示在SVG圖像上。要顯示它們須要使用<use>元素來引入它們。以下面的代碼所示:
<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>
2. enter().append("rect").append("rect")
添加的第二個rect 是在第一個的基礎裏添加的
至關於 <rect>
<rect></rect>
</rect>
例 <p>Hello World 1</p>
<p>Hello World 2</p>
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; });