yay ortasında kendi teğet tam metin taban çizgisinin yönü olacak şekildedir VE aynı zamanda iki ağaç düğümlerini ayıran vektör ile eş doğrusaldır.
Biz sorunu çözmek için kullanabilirsiniz.
matematik Biraz gereklidir. İlk olarak, yatay eksene göre olan bir vektör v
açısını döndüren bir işlev tanımlayalım:
function xAngle(v) {
return Math.atan(v.y/v.x) + (v.x < 0 ? Math.PI : 0);
}
Daha sonra, her kene de, en yerinde metin eksi taban çizgisine açısını dönmesine izin verin.Birincisi, birkaç fayda fonksiyonları: eklendi resmi::
düzenlemek 2
function isFiniteNumber(x) {
return typeof x === 'number' && (Math.abs(x) < Infinity);
}
function isVector(v) {
return isFiniteNumber(v.x) && isFiniteNumber(v.y);
}
bulunabiliyor ve sonra da tick
işlevinde,
linkText.attr('transform', function (d) {
// Checks just in case, especially useful at the start of the sim
if (!(isVector(d.source) && isVector(d.target))) {
return '';
}
// Get the geometric center of the text element
var box = this.getBBox();
var center = {
x: box.x + box.width/2,
y: box.y + box.height/2
};
// Get the tangent vector
var delta = {
x: d.target.x - d.source.x,
y: d.target.y - d.source.y
};
// Rotate about the center
return 'rotate('
+ (-180/Math.PI*xAngle(delta))
+ ' ' + center.x
+ ' ' + center.y
+ ')';
});
});
düzenlemek eklemek Kavisli yaylar yerine düz çizgilerle (sadece <text>
yerine) <text>
iç <textPath>
, bununla linkText
ilgilendiren tick
fonksiyonunun bir kısmının yerini alabilecek:
linkText.attr('transform', function(d) {
if (!(isVector(d.source) && isVector(d.target))) {
return '';
}
// Get the geometric center of this element
var box = this.getBBox();
var center = {
x: box.x + box.width/2,
y: box.y + box.height/2
};
// Get the direction of the link along the X axis
var dx = d.target.x - d.source.x;
// Flip the text if the link goes towards the left
return dx < 0
? ('rotate(180 '
+ center.x
+ ' ' + center.y
+ ')')
: '';
});
ve bu ne elde ediyoruz:
Bildirimi nasıl Link, daha fazla sağa işaret etmek için, daha fazla sola işaret etmek üzere, metin çevrilir.
Buradaki sorun, metnin bağlantının altında kalmasıdır.
linkText.attr('transform', function(d) {
if (!(isVector(d.source) && isVector(d.target))) {
return '';
}
// Get the geometric center of this element
var box = this.getBBox();
var center = {
x: box.x + box.width/2,
y: box.y + box.height/2
};
// Get the vector of the link
var delta = {
x: d.target.x - d.source.x,
y: d.target.y - d.source.y
};
// Get a unitary vector orthogonal to delta
var norm = Math.sqrt(delta.x * delta.x + delta.y * delta.y);
var orth = {
x: delta.y/norm,
y: -delta.x/norm
};
// Replace this with your ACTUAL font size
var fontSize = 14;
// Flip the text and translate it beyond the link line
// if the link goes towards the left
return delta.x < 0
? ('rotate(180 '
+ center.x
+ ' ' + center.y
+ ') translate('
+ (orth.x * fontSize) + ' '
+ (orth.y * fontSize) + ')')
: '';
});
ve şimdi sonuç aşağıdaki gibidir:
Gördüğünüz gibi, metin, çizgi üstünde güzel bile bağlantıyı oturur şöyle That sabitlenebilir sola doğru işaret eder.
Son olarak, yayları tutarken ve bir tarafı sağa doğru eğriltirken, sorunu çözmek için iki adet <textPath>
öğesi oluşturmanız gerektiğini düşünüyorum. Biri source
'dan target
'a, diğeri ise ters yöne gitmek için. Bağlantı sağa doğru (delta.x >= 0
) ve ikincisi ise sola (delta.x < 0
) doğru gittiğinde ilkini kullanırsınız ve sonuç daha güzel görünür ve kodun orijinalden daha karmaşık olması gerekmez. Sadece biraz daha mantık ekledi.
https://stackoverflow.com/questions/8663844/add-text-label-onto-links-in-d3-force-directed-graph adresine bakın. –