之前用 [[d3.js]] 測試綁定資料時,都是參考網路上的教學,也都是比較簡單的單一元素,今天測試如果我的圖形需要多個圖層元素組合而成,那應該要如何做呢?

一開始我的想法是用function,把圖層元素組合的程式包成一個function,接著將元素的一些參數都改成變數,要產生幾個就呼叫幾次function,這樣的做法測試是可行的。

雖然用function可以解決,但是好像不符 [[D3.js]] 的理念,所以又在網路上多多學習,果然是我對它不夠了解,沒有用到它精華的地方。

這次測試的想法是,我有兩個圓,外圓比較大,內圓比較小且是白色的,所以兩個圓疊起來就像是一個甜甜圈,而我想要產生三個甜甜圈,而這三個甜甜圈有不同的大小與顏色。

測試成功的程式碼如下:

HTML:
<div>
    <svg id="svg_test02" width="500" height="300"></svg>
</div>

Javascript:

// circle_cx是圓心x的座標位置;circle_r_o是外圓的半徑;circle_r_i是內圓的半徑;fill_d是外圓的顏色
json_text02 = [ 
  {"circle_cx": 80,"circle_r_o": 50,"circle_r_i": 40,"fill_d":"#FF0000"},
  {"circle_cx": 200,"circle_r_o": 60,"circle_r_i": 50,"fill_d":"#00FF00"},
  {"circle_cx": 350,"circle_r_o": 70,"circle_r_i": 60,"fill_d":"#0000FF"} ]

svg_test02 = d3.select("#svg_test02")

//先產生多個<g>,因為陣列有3個元素,所以會新增3個新的<g>。因為實際沒有元素,所以要用.enter()增加<g>元素
svg_test02_g = svg_test02.selectAll('g').data(json_text02).enter().append('g') 

//選擇所有的<g>,並增加外圓,因為實際沒有元素,所以要用.enter()
svg_test02_g           
  .selectAll('g')
  .data(json_text02) 
  .enter() 
  .append('circle')
  .attr('cx', (d) => { return d.circle_cx} )
  .attr('cy', 150)
  .attr('r', (d) => { return d.circle_r_o})
  .attr('fill',(d) => { return d.fill_d })

//選擇所有的<g>,並增加內圓,因為實際沒有元素,所以要用.enter()
svg_test02_g           
  .selectAll('g')
  .data(json_text02)
  .enter() 
  .append('circle')
  .attr('cx', (d) => { return d.circle_cx} )
  .attr('cy', 150)
  .attr('r', (d) => { return d.circle_r_i})
  .attr('fill','#ffffff')  //固定白色

執行結果如下: