Minimapa
O modo full já encaixa uma visão geral de todo o gráfico em um canto da tela, e uma linha — plugins: [minimap()], como abaixo — coloca seu próprio gráfico configurado lá, em qualquer modo. Clique em qualquer lugar para trazer a visualização para lá; arraste o retângulo para deslocar. O gráfico abaixo é mais largo que sua janela de visualização, então há algum lugar para onde ir. A pequena seta no canto interno do minimapa dobra-o apenas para aquele botão quando a tela é mais importante do que a visão geral.
Mesmo assim, é um plugin, não embutido no Chrome - o modo full simplesmente o instala para você e reserva a cópia passada aqui. Ele se instala através do PluginContext que é entregue e não usa nada que um plugin próprio não possa usar - ele lê a extensão do gráfico com renderer.getContentBounds(), calcula a região visível invertendo os cantos da tela através de renderer.screenToGraphCoordinates() e move a visualização com renderer.setViewport(). Veja Plugins para toda a superfície.
Também permanece barato em um gráfico que realmente precisa de um. A imagem reside em um bitmap fora da tela em cache que só é re-rasterizado quando o gráfico muda (ou a cada 10 tiques de simulação enquanto um layout é estabelecido); panorâmica e zoom redesenhar uma imagem e um retângulo, qualquer que seja a contagem de nós. Após 1.500 nós, ele para de desenhar cada nó e pinta a densidade, que lê melhor do que dezenas de milhares de pontos sobrepostos e não resolve nenhum estilo por nó.
Aumente o zoom com os controles da janela de visualização e arraste o retângulo no minimapa — a imagem do conteúdo nunca é redesenhada, apenas o retângulo se move.
// import { minimap } from 'pivotick'
const options = {
UI: {
// `full` mode brings a minimap of its own; `light` and `viewer` need asking
// (`UI.minimap: true`, or the plugin below). `static` never has one.
mode: 'full',
// The other thing full mode brings. Off here: this card is about the minimap.
table: false
},
// A plugin installs itself through the PluginContext it is handed — the core never
// needs to know it exists. `graph.use(minimap())` works just as well, at any time.
// Passed here it replaces the one full mode would have mounted, configuration and all.
plugins: [
minimap({
position: 'bottom-right', // the corner the built-in chrome leaves free
width: 220
// height: omitted → follows the canvas's aspect ratio
})
],
render: {
nodeTypeAccessor: (node) => node.getData()?.kind,
nodeStyleMap: {
hub: { color: '#0072B2', size: 13 },
leaf: { color: '#E69F00', size: 7 }
}
},
simulation: {
d3LinkDistance: 60
}
}// A graph deliberately bigger than the viewport, so the minimap has something to
// navigate: six clusters of satellites around a spine.
const nodes = []
const edges = []
const hubs = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta']
hubs.forEach((hub, hubIndex) => {
const angle = (hubIndex / hubs.length) * Math.PI * 2
nodes.push({
id: hub,
data: { name: hub, kind: 'hub' },
x: Math.cos(angle) * 420,
y: Math.sin(angle) * 420
})
if (hubIndex > 0) edges.push({ from: hubs[hubIndex - 1], to: hub })
for (let leafIndex = 0; leafIndex < 9; leafIndex++) {
const id = `${hub}-${leafIndex}`
const spread = (leafIndex / 9) * Math.PI * 2
nodes.push({
id,
data: { name: id, kind: 'leaf' },
x: Math.cos(angle) * 420 + Math.cos(spread) * 130,
y: Math.sin(angle) * 420 + Math.sin(spread) * 130
})
edges.push({ from: hub, to: id })
}
})
const data = { nodes, edges }