D3.js
  • D3.js Nedir, Ne Değildir?
  • JS Grafik Kütüphaneleri
  • Modüler D3.js
    • D3.js Eklenti Oluşturma
  • Başlangıç
  • Seçiciler
  • Element Biçimlendirme
  • Olaylar (Events)
  • Geçişler ve Animasyonlar
    • Kontrol Fonksiyonları
    • Bir Geçişin Yaşam Döngüsü
  • Ölçekler (Scales)
    • Sürekli Girdili ve Sürekli Çıktılı
    • Sürekli Girdili ve Kesikli Çıktılı
    • Kesikli Girdili ve Gesikli Çıktılı
  • Eksen (Axes)
  • Şekiller (Shapes)
    • Çizgi (line) Oluşturucu
    • Area (alan) Oluşturucu
    • Stack (yığın) Oluşturucu
    • Arc (yay) Oluşturucu
    • Pie (pasta) Oluşturucu
    • Symbols (semboller)
  • Düzenler (Layouts)
    • Tree Layout
    • Cluster Layout
    • Treemap Layout
    • Pack Layout
    • Partition Layout
    • Chord Layout
    • Force Layout
  • Kaynaklar
Powered by GitBook
On this page

Was this helpful?

  1. Düzenler (Layouts)

Force Layout

PreviousChord LayoutNextKaynaklar

Last updated 5 years ago

Was this helpful?

D3’ün kuvvet düzeni, görsel öğelerin konumlandırılması için fizik tabanlı bir simülatör kullanıyor. Kuvvetler, elemanlar arasında kurulabilir, örneğin:

  • tüm elemanlar birbirlerini iterler,

  • başka elementler ağırlık merkezlerine tutturulur

  • bağlantılı elemanlar birbirinden sabit bir mesafeye sahiptir

  • elementler üst üste gelmeyebilir (çarpışma tespiti)

Kuvvet yerleşimi, elemanları başka yollarla başarılması zor olacak şekilde konumlandırmamızı sağlar.

Örnek olarak, her biri A, B veya C kategorisine sahip olan birkaç çevremiz var ve aşağıdaki kuvvetleri ekledik:

  • tüm düğümler birbirini çeker (düğümleri bir araya getirmek için)

  • çarpışma algılama (dairelerin üst üste gelmesini durdurmak için),

  • kategorilerine bağlı olarak üç merkezden birine çekilir

Kuvvet yerleşimi, diğer D3 düzenlerinden daha büyük miktarda hesaplama (tipik olarak birkaç saniye gerektirir) gerektirir ve çözüm, adım adım (yinelemeli) bir şekilde hesaplanır. Genellikle, SVG / HTML öğelerinin konumları, simülasyon yinelendikçe güncellenir, bu nedenle düğümlerin sürekli konumlandırıldığını görürüz.

var width = 300, height = 300
var nodes = [{}, {}, {}, {}, {}]

var simulation = d3.forceSimulation(nodes)
  .force('charge', d3.forceManyBody())
  .force('center', d3.forceCenter(width / 2, height / 2))
  .on('tick', ticked);

Burada basit 5 nesneye sahip bir dizi oluşturduk ve iki kuvvet işlevi forceManyBody ve forceCenter'ı sisteme ekledik. (Bunlardan birincisi elemanları birbirlerini iter, ikincisi ise elemanları bir merkez noktasına doğru çeker.)

Simülasyon her yinelendiğinde, ticked fonksiyonu çağrılır. Bu işlev düğüm dizisini birleştirerek elemanları daire içine alır ve konumlarını günceller:

function ticked() {
  var u = d3.select('svg')
    .selectAll('circle')
    .data(nodes)

  u.enter()
    .append('circle')
    .attr('r', 5)
    .merge(u)
    .attr('cx', function(d) {
      return d.x
    })
    .attr('cy', function(d) {
      return d.y
    })

  u.exit().remove()
}

Kuvvet simülasyonunun gücü ve esnekliği, çekim, itme ve çarpışma algılama gibi bir takım etkilere ulaşmak için elementlerin pozisyonunu ve hızını ayarlayan kuvvet fonksiyonlarından gelir. Kendi kuvvet fonksiyonlarımızı tanımlayabiliriz, ancak D3 yerleşik olarak bir takım faydalı işlevlerle gelir:

  • forceCenter (sistemin ağırlık merkezini ayarlamak için)

  • forceManyBody (elemanların birbirini çekmesi veya itmesi için)

  • forceCollide (çakışan elemanları önlemek için)

  • forceX ve forceY (elemanları belirli bir noktaya çekmek için)

  • forceLink (bağlı elemanlar arasında sabit bir mesafe oluşturmak için)

forceCenter

forceCenter, elemanlarınızı bir merkez noktası etrafında bir bütün olarak merkezlemek için (zorunlu değilse) kullanışlıdır. (Bu öğeler olmadan sayfadan kaybolabilir.)

d3.forceCenter(100, 100) 
d3.forceCenter().x(100).y(100)

Yukarıdaki 2 örnekte aynı şeyi yapar. Kullanım şekli tercihe kalmış. Eklemek için:

simulation.force('center', d3.forceCenter(100, 100))

forceManyBody

forceManyBody, tüm öğelerin birbirini çekmesini veya itmesini sağlar. Çekim veya itme gücü, .strength() kullanılarak ayarlanabilir; burada pozitif bir değer elementlerin birbirini çekmesine neden olurken, negatif bir değer elementlerin birbirlerini itmesine neden olur. Varsayılan değer -30'dur.

simulation.force('charge', d3.forceManyBody().strength(-20))

forceCollide

forceCollide, üst üste gelen öğelerin durmasını sağlamak için kullanılır ve düğümlerin bir arada toplanması sırasında özellikle kullanışlıdır. .radius() kullanarak elemanların yarıçapını belirtmeliyiz:

var numNodes = 100

var nodes = d3.range(numNodes).map(function(d) {
  return {radius: Math.random() * 25}
})

var simulation = d3.forceSimulation(nodes)
  .force('charge', d3.forceManyBody().strength(5))
  .force('center', d3.forceCenter(width / 2, height / 2))
  .force('collision', d3.forceCollide().radius(d => d.radius)))

forceX ve forceY

forceX ve forceY, elemanların belirtilen pozisyonlara doğru çekilmesine neden olur. Tüm elemanlar için tek bir merkez kullanabilir veya her eleman için bu gücü uygulayabiliriz.

Çekim gücü, .strength() kullanılarak yapılandırılabilir. Örnek olarak, her biri 0, 1 veya 2 kategorisine sahip olan bir dizi öğemiz olduğunu varsayalım.

var xCenter = [100, 300, 500]

simulation.force('x', d3.forceX().x(function(d) {
  return xCenter[d.category];
}))

Yukarıdaki örneğin ayrıca forceCollide kullandığını unutmayın.

Eğer verilerimiz sayısal bir boyuta sahipse, elemanları bir eksen boyunca konumlandırmak için forceX veya forceY kullanabiliriz:

simulation.force('x', d3.forceX().x(function(d) {
  return xScale(d.value);
}))
.force('y', d3.forceY().y(function(d) {
  return 0;
}))

forceLink

forceLink, bağlantılı elemanları aralarında sabit bir mesafe olacak şekilde iter. Hangi öğeleri birbirine bağlamak istediğimizi belirten bir dizi bağlantı gerektirir. Her link nesnesi, bir değer ve dizinin endeks olduğu değer olan bir kaynak ve hedef eleman belirtir.

var links = [
  {source: 0, target: 1},
  {source: 0, target: 2},
  {source: 0, target: 3},
  {source: 1, target: 6},
  {source: 3, target: 4},
  {source: 3, target: 7},
  {source: 4, target: 5},
  {source: 4, target: 7}
]

Bağlantı dizimizi daha sonra .links() kullanarak forceLink işlevine aktarabiliriz:

simulation.force('link', d3.forceLink().links(links))

Bağlantılı elemanların uzaklığı ve gücü .distance() (varsayılan değer 30) ve .strength() kullanılarak yapılandırılabilir.