تخطيط ضبطها تلقائيا
الرسم البياني لخمس عقد والرسم البياني لخمسمائة يريدان فيزياء مختلفة تمامًا، و وكذلك الأمر بالنسبة للرسم البياني المكون من نقاط صغيرة مقابل إحدى بطاقات الصور الكبيرة. بدلا من اختيار مجموعة واحدة من إعدادات القوة والأمل، Pivotick تستمدها مما هو في الواقع على الشاشة - عدد العقد، حجم العقدة، حجم اللوحة القماشية - وإعادة اشتقاقها كلما تغييرات الرسم البياني. هذا هو الافتراضي.
قم بتوسيع الرسم البياني أدناه وشاهد تحرك المقابض: تنخفض مسافة الرابط مثل اللوحة القماشية يصبح مزدحمًا، ويرتفع السحب المركزي لتثبيت كل شيء في الإطار.
- ** إنها تحرك المقابض التي يمكنك رؤيتها فقط. ** يقوم التشغيل التلقائي بنفس عناصر التحكم مثل الفيزياء منبثقة، وتتبع أشرطة التمرير - لا يحدث شيء خلف الرافعة المخفية.
- أنت تفوز دائمًا. اسحب شريط التمرير، أو اختر ضيق / فضفاض، ويتوقف تلقائيًا من أجل الخير؛ لن يتم إعادة ضبطه أبدًا على الاختيار الذي قمت به.
- يظل هادئًا. تتجمع المحفزات التي تصل معًا، ويحدث التغيير أيضًا يتم تخطي حجم صغير يمكن رؤيته - لذا فإن المحور الذي يضيف أربعين عقدة يكلف عملية ترحيل واحدة.
- لا يتم تنشيط المحاكاة المتوقفة مؤقتًا أبدًا.
يتم تشغيل الوضع التلقائي ما لم يقم الرسم البياني بتكوين القوة بنفسه، بحيث تستمر الإعدادات الحالية لهم. راجع ضبط التخطيط التلقائي لمعرفة القاعدة الدقيقة.
js
// Nothing here configures a force, so the layout tunes itself — that is the
// default. `physics: 'auto'` is spelled out only because the documentation
// gallery pins every other example to `'manual'` for stable screenshots.
//
// Setting any force option instead (d3LinkDistance, d3ManyBodyStrength,
// d3CollideRadiusMultiplier, d3VelocityDecay, d3GravityStrength,
// d3GravityStrengthConnected, d3AlphaDecay, cooldownTime) would keep your value
// and switch the tuning off for that graph.
const options = {
simulation: { physics: 'auto' }
}js
// Auto re-tunes on every visible change to the graph, so growing it is all it
// takes to watch the knobs move. Triggers arriving together are coalesced into a
// single pass, and a change too small to matter is skipped entirely — so a pivot
// that adds forty nodes costs one relayout, not forty.
let seq = 0
function addBatch(graph, size = 20) {
const existing = graph.getNodes()
const nodes = []
const edges = []
for (let i = 0; i < size; i++) {
const id = `n-${++seq}`
const pool = existing.concat(nodes)
const parent = pool[Math.floor(Math.random() * pool.length)]
nodes.push({ id, data: { label: id } })
edges.push({ from: parent.id, to: id })
}
graph.updateData(nodes, edges)
}
function reset(graph) {
for (const node of graph.getNodes()) {
if (!data.nodes.some((seed) => seed.id === node.id)) graph.removeNode(node.id)
}
seq = 0
}js
// Auto only ever moves the knobs the Physics flyout exposes, so whatever it
// decided can simply be read back — and overridden by dragging a slider, which
// hands control back to you for good.
function readKnobs(graph) {
const { repulsion, linkDistance, centering } = graph.simulation.getPhysicsKnobs()
return {
nodes: graph.getNodes().length,
repulsion,
linkDistance,
centering,
auto: graph.simulation.isAutoPhysicsEnabled()
}
}js
// A small seed graph — small enough that fixed force settings would leave it
// huddled in the middle of the canvas.
const data = {
nodes: [
{ id: 'core', data: { label: 'core' } },
{ id: 'api', data: { label: 'api' } },
{ id: 'web', data: { label: 'web' } },
{ id: 'db', data: { label: 'db' } },
{ id: 'queue', data: { label: 'queue' } }
],
edges: [
{ from: 'web', to: 'api' },
{ from: 'api', to: 'core' },
{ from: 'core', to: 'db' },
{ from: 'core', to: 'queue' }
]
}