Layout ajustado automaticamente
Um gráfico de cinco nós e um gráfico de quinhentos exigem uma física muito diferente, assim como um gráfico de pequenos pontos versus um gráfico de grandes cartões de imagem. Em vez de escolher um conjunto de configurações de força e esperar, Pivotick deriva-as do que realmente está na tela - contagem de nós, tamanho do nó, tamanho da tela - e as deriva novamente sempre que o gráfico muda. Este é o padrão.
Aumente o gráfico abaixo e observe os botões se moverem: a distância do link diminui à medida que a tela fica lotada e o puxão de centralização aumenta para manter tudo no quadro.
- Ele move apenas os botões que você pode ver. Auto aciona os mesmos controles do submenu Física, e os controles deslizantes seguem em frente — nada acontece atrás de uma alavanca oculta.
- Você sempre ganha. Arraste um controle deslizante ou escolha Tight / Loose e pare automaticamente para sempre; ele nunca irá se sintonizar novamente com uma escolha que você fez.
- Ele permanece calmo. Os gatilhos que chegam juntos são unidos e uma mudança pequena demais para ser vista é ignorada — portanto, um pivô que adiciona quarenta nós custa um relé.
- Nunca ativa uma simulação pausada.
Auto está ativado, a menos que o próprio gráfico configure uma força, portanto, as configurações existentes mantêm as suas. Consulte Ajuste automático de layout para obter a regra exata.
// 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' }
}// 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
}// 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()
}
}// 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' }
]
}