Tabela de dados
UI.table divide um data dock na parte inferior da tela: os nós e bordas do gráfico como uma grade classificável e selecionável. Ela existe porque um layout de força é estruturalmente ruim em três coisas que as pessoas fazem constantemente – ler valores exatos, selecionar em escala e decidir por onde começar.
O loop pretendido é tabela para encontrar, tela para entender, barra lateral para ler: classifique por grau para localizar os hubs, clique com a tecla Shift pressionada nos vinte primeiros e aja sobre eles com as ações em massa da barra lateral.
const options = {
UI: { mode: 'full' },
}Isso é tudo o que é preciso. No modo full, o dock fica na parte inferior dobrado em sua barra de cabeçalho; clique na divisa — ou pressione Shift+T — para mostrar a mesa. UI.table: false remove-o completamente.
Não há deliberadamente nenhum botão na barra de ferramentas para isso. A barra é o controle: todas as pílulas na barra superior abrem algo sobre a tela, enquanto o dock é uma região dividida que já mostra sua própria divisa.
O dock é apenas no modo full – é uma linha de grade ao lado da barra lateral, e os outros modos prometem uma tela sem tanto cromo.
A tabela não muda nada que você não pediu
O dock não sofre mutação em nada. Reflete o gráfico e orienta a seleção; ocultar e fixar permanece com as ações em massa, e restaurar um nó oculto permanece com o painel de filtro. O que o dock acrescenta é um instrumento muito melhor para construir a seleção em que aqueles atuam.
A única coisa que pode mudar é o que a tela mostra, e somente mediante solicitação: o botão Aplicar ao gráfico oculta os elementos que seus filtros de coluna deixam de fora. Até você pressioná-lo, estreitar uma coluna é ler, não filtrar.
Ele lista todo o gráfico
A tabela não espelha a tela. Ele lista todos os nós - e na guia Bordas todas as arestas - incluindo aqueles atualmente ocultos, e a coluna Visibility inicial diz onde cada um está:
| Valor | Estilos | Significado |
|---|---|---|
visible | quieto, sem cor | Na tela agora |
filtered | chip âmbar | Oculto por um filtro - um filtro de nó, ou para uma borda sua layer está desligada. Mude o filtro para recuperá-lo |
excluded | ficha vermelha | Um nó escondido à mão; restaure-o da lista de nós ocultos do painel de filtro |
nested | contorno tracejado | Um nó dentro de um cluster que a tela fechou, ou uma borda com extremidade em um: sua linha é desenhada para o cluster. Nada o filtrou; abra o cluster para vê-lo |
endpoint | contorno neutro | Uma aresta cujo fim foi filtrado. Nada foi feito até a borda em si |
Cada estado difere em peso, borda e cor, portanto a coluna é lida sem depender de matiz. Toda a linha de um elemento oculto também recua, mantendo o olho no que é realmente desenhado.
Uma aresta lê endpoint em preferência a filtered, porque essa é a razão pela qual você precisa consertar primeiro: enquanto um nó que ela toca desaparece, reativar sua camada não pode trazer a aresta de volta.
Isso é deliberado. "23 nós ocultos" é uma afirmação que você deve poder inspecionar, e uma tabela que elimina silenciosamente as linhas que você está procurando é pior do que nenhuma tabela. Classifique por Visibility para ver exatamente o que um filtro retirou.
Nós dentro de clusters
O conteúdo de um cluster também obtém linhas, como peers dos próprios nós do gráfico, com uma coluna Cluster fornecendo o caminho de onde vieram (Team B / Squad, mais externo primeiro) e uma coluna Children informando o tamanho de cada cluster. Ambas as colunas aparecem sempre que o gráfico possui clusters. A opção Nested nodes do cabeçalho remove essas linhas novamente se você quiser apenas o nível superior, e UI.table.nested: false nunca as oferece.
Eles são listados de forma plana, em vez de recuados em seu cluster propositalmente: a tabela existe para responder a perguntas que o canvas não pode - quais nós são os hubs, quais estão acima de um limite - e isso só continua funcionando se uma classificação ou filtro atingir todas as linhas igualmente. Uma árvore só pode classificar irmãos.
O que vale a pena saber é que um nó aninhado não é desenhado por este gráfico. Um cluster aberto renderiza um subgráfico próprio separado, então:
Visibilitylênestedenquanto qualquer cluster acima do nó está fechado evisiblequando todos estão abertos. Nunca éfiltered— nenhum filtro o coloca lá.Degreeconta as arestas reais do nó. Enquanto seu cluster está fechado, a tela os atrai para o cluster, portanto, esta é a contagem do próprio nó, em vez de uma descrição da imagem.- Clicar na linha seleciona o nó, para que a barra lateral possa mostrá-lo – geralmente a única maneira de acessá-lo. A tela circunda o cluster fechado que a representa. Clicar duas vezes abre esse cluster, um nível por toque. Com
render.enableNodeExpansion: falseo cluster permanece fechado e a visualização é centralizada nele.
Classificando e restringindo
Clique em qualquer cabeçalho de coluna para classificar; clique novamente para reverter. Colunas filtráveis aumentam um controle no cabeçalho que restringe as linhas - cada coluna no conjunto derivado tem uma, e uma coluna que você declara recebe uma solicitando filterable: true.
Qual controle você obtém segue o type da coluna, então você pode perguntar a uma coluna o que ela realmente é capaz de responder:
type | Controle | Partidas |
|---|---|---|
numberRange | um par Min / Max | dentro do intervalo; qualquer extremidade pode ser deixada vazia |
select · multiselect · boolean | um dropdown dos valores que a coluna contém | exatamente esse valor ou associação quando a célula é uma lista |
text · regex · não digitado | uma caixa de texto | substring que não diferencia maiúsculas de minúsculas |
O menu suspenso é construído a partir dos próprios valores da coluna, em vez de uma lista de opções declarada, portanto, nunca oferece uma opção que voltaria vazia. Acima de 50 valores distintos, ele fica de lado para a caixa de texto - um menu suspenso tão longo que não é um controle que alguém possa usar.
Um filtro de linha não é o filtro do gráfico. Isso muda o que você está lendo: a tela permanece intacta e a coluna Visibility continua relatando a verdade ao lado dela, para que os dois possam discordar sem que nenhum deles esteja errado. Empurrar seu estreitamento para a tela é um ato separado e explícito – veja abaixo.
A contagem do encaixe reflete ambos: 40 nodes torna-se 12 of 40 nodes quando você estreita.
Aplicando os filtros ao gráfico
Aplicar ao gráfico, na barra de ferramentas do dock, oculta os elementos que seus filtros de coluna deixam de fora. É a ponte entre os dois tipos de filtragem: estreite as linhas até que a tabela liste o que lhe interessa, depois pressione uma vez e a tela mostrará a mesma coisa.
É um push único, não um link ao vivo, e o botão indica em qual dos três estados você se encontra:
| Botão | Significado |
|---|---|
Apply to graph, apagado | Nada é empurrado. Desativado até que um filtro de coluna esteja realmente restringindo algo. |
Clear, aceso | O gráfico é filtrado e está de acordo com seus filtros. Pressione para restaurá-lo. |
Apply to graph, aceso | O gráfico é filtrado por um push earlier e seus filtros foram movidos. Pressione para atualizá-lo. |
Duas propriedades que vale a pena conhecer, porque são elas que mantêm o push previsível:
- Ele oculta exatamente as linhas que os filtros deixaram de fora — nunca "mostra apenas estas". Portanto, um nó adicionado após o push permanece na tela. O que você empurrou é uma declaração sobre um momento, não uma pergunta permanente. O interior de um aglomerado aberto se estreita apenas na medida em que suas próprias fileiras estão entre as que foram deixadas de fora; com linhas aninhadas desativadas, nada as nomeia e o interior permanece intacto.
- A coluna
Visibilityé never parte de um push, embora ainda restrinja as linhas como qualquer outra. Seus valores são o estado de filtro do gráfico, portanto, pressioná-los ocultaria o que está atualmente na tela e então discordaria de si mesmo.
Enquanto um push está ativo, a contagem relata as duas metades - 12 of 40 nodes · 28 hidden - e o painel de filtro cresce uma linha Da tabela que o nomeia e pode limpá-lo, portanto, um push nunca é um filtro que você não consegue encontrar quando o dock é dobrado.
O push chega como um único filtro sob uma chave reservada, o que significa que ele compõe com o painel de filtros em vez de competir com ele: nada que você define no próprio formato desse painel atrapalha um push, e um push nunca limpa os filtros do painel. Os dois são combinados, então um nó precisa sobreviver a ambos.
Passe filterGraph: false para um dock cujos controles nunca podem tocar a tela:
const options = {
UI: { mode: 'full', table: { filterGraph: false } },
}Selecionando
| Gesto | Efeito |
|---|---|
| Clique em uma linha | Selecione esse elemento |
| Ctrl/Cmd-clique | Adicionar ou remover uma linha |
| Clique com a tecla Shift pressionada | Faça um intervalo, na ordem listada atualmente |
| Selecionar tudo | Cada linha listada atualmente – pós-classificação, pós-filtro |
| Clique duas vezes | Selecione ** e ** centralize a tela nela |
| Passe o mouse | Destaque o elemento na tela |
| Clique com o botão direito | O menu de contexto do elemento; uma linha de uma seleção múltipla abre a seleção |
Funciona em ambas as direções: prenda um grupo com elástico na tela e as linhas correspondentes são marcadas e roladas. A seleção é a mesma lida pelas ações em massa da barra lateral, portanto o loop fecha sem qualquer fiação extra.
As linhas ocultas são selecionadas como qualquer outra - esse é o objetivo de listá-las.
Colunas
Sem columns declarado, o dock resolve isso para você, em três níveis:
- Declarado —
UI.table.columnsvence imediatamente. - Das suas facetas — caso contrário, se você declarou
UI.filter.facets, as colunas serão construídas a partir delas. Descreva seus dados uma vez e o painel de filtros e a tabela concordarão sobre isso. - Scanned — caso contrário, os dados são lidos, ordenados por coverage para que as chaves bem preenchidas venham primeiro e a cauda esparsa fique na extrema direita.
De qualquer forma, as colunas com reconhecimento de gráfico agrupam os dados. Para nós, Visibility e Label lideram - uma medianiz de status e o nome, as duas coisas que você verifica para encontrar uma linha - unidas por Cluster em um gráfico que possui clusters, desde um aninhado row precisa dizer de onde veio. As contagens fecham: Degree, mais Children em um gráfico que possui clusters. As contagens ficam no final porque são a aritmética do gráfico, e não os dados do próprio elemento, e são colunas estreitas e de largura fixa, de modo que alguns dígitos nunca ocupam a parte da linha que um nome precisa. As bordas mantêm a mesma calha Visibility e depois são lidas como uma frase — Source / Label / Target.
A classificação padrão é a coluna Label, não a principal: a classificação por Visibility em aberto não informa nada enquanto cada linha ainda lê visible.
Tudo é mostrado por padrão e a grade rola lateralmente em vez de deixar cair nada. Em nós com muitas propriedades, use o seletor Columns para desligar o que você não precisa - o que também retira o controle de filtro do cabeçalho.
Colunas derivadas são filtráveis. Seus rótulos, tipos e alinhamento já foram inferidos, e o filtro de linha é inferido desse mesmo tipo — portanto, uma tabela que você nunca configurou é aquela que você ainda pode restringir. As colunas declaradas são o oposto: você obtém exatamente o conjunto que escreveu, filterable: false, a menos que diga o contrário.
As colunas integradas
tableColumns contém as colunas que nenhuma grade genérica poderia calcular, porque elas tratam da posição de um elemento no gráfico e não de seus dados:
import { Pivotick, tableColumns } from 'pivotick'
new Pivotick(el, data, {
UI: {
mode: 'full',
table: {
open: true,
// Reference a built-in's key through the object rather than typing it —
// the key itself is namespaced so it can never clash with a data key.
sort: { key: tableColumns.degree.key, direction: 'desc' },
columns: [
tableColumns.visibility,
{ ...tableColumns.degree, label: 'Links' },
tableColumns.label,
{ key: 'severity', label: 'Severity', type: 'numberRange', filterable: true },
],
},
},
})label · degree · degreeIn · degreeOut · visibility · pinned · children · cluster, mais source e target para bordas. Clone um para ajustá-lo, como acima.
Um TableColumn é um FilterFacet com alguns extras de apresentação (width, align, sortable, filterable, hidden, format), e é por isso que uma faceta pode ser usada como uma coluna inalterada.
Exportando
Os botões CSV e JSON escrevem exatamente o que você está vendo: esta guia, essas colunas visíveis nesta ordem, esta classificação, este filtro de linha. Valores brutos, nunca a saída format de uma coluna, portanto o arquivo permanece legível por máquina.
Não o gráfico inteiro - isso está a graph.getNodes() de distância para qualquer pessoa com código. Passe export: false para deixar os botões de fora.
Downloads em uma página incorporada
Um iframe em sandbox pode bloquear um download completamente. Quando isso acontece, o dock diz isso, em vez de deixar um botão que parece não fazer nada.
Escala
Acima de virtualizeAbove linhas (200 por padrão), as linhas são janelas: apenas o que cabe na janela de visualização mais uma margem está no DOM, enquanto a barra de rolagem ainda mede todo o conjunto de dados. A classificação reordena a matriz subjacente, nunca o DOM, e uma reconstrução mantém a posição de rolagem e a seleção.
Abaixo do limite, cada linha é renderizada, o que mantém o caso comum simples de inspecionar.
Opções
| Opção | Padrão | O que isso faz |
|---|---|---|
enabled | true | false (ou UI.table: false) remove totalmente o dock |
tabs | ['nodes', 'edges'] | As visualizações own da tabela. Um não renderiza nenhuma faixa interna |
columns / edgeColumns | derivado | Veja Colunas |
open | desarmar | Unset começa dobrado na barra; true inicia expandido; false não deixa nenhuma doca (Shift+T ainda traz) |
collapsed | dobrado | Dobrado na barra de cabeçalho. Com open: true, 'auto' segue o quarto disponível até você escolher por si mesmo |
height | 0.35 | Uma contagem de pixels ou uma fração da tela. Fixado para que a tela mantenha um mínimo utilizável |
sort | a coluna Label | { key, direction } |
rowActivate | 'select' | 'selectAndCenter' também move a tela; 'none' torna as linhas inertes |
filterGraph | true | Oferta Aplicar ao gráfico. false para um dock que nunca consegue filtrar a tela |
nested | true | Liste o conteúdo de um cluster como linhas próprias. Consulte Nós dentro de clusters |
export | ['csv', 'json'] | false esconde os botões |
virtualizeAbove | 200 | Contagem de linhas acima das quais as linhas estão em janelas |
A doca comporta mais que a mesa
A tabela é um painel no dock, e qualquer outra coisa que você registrar é outra:
const dispose = graph.UIManager.addDockTab({
label: 'Audit',
render: () => myAuditPane(), // called once, the first time the pane is opened
toolbar: () => [clearButton], // rebuilt on every activation
})A faixa do dock mostra Table │ Audit. A troca troca o corpo ** e ** dos controles de cabeçalho, já que Select all, as exportações e Columns pertencem à tabela e não significam nada em outro painel. Um painel não renderiza nenhuma faixa – nada deve apontar para um switch com uma configuração.
A tabela não é um caso especial: ela vem através do mesmo addDockTab, então um painel que você registra é igual e não convidado. order o coloca (pedidos iguais mantêm a ordem de registro, e um painel registrado posteriormente - como sempre acontece com um plugin - chega após o integrado). O triturador devolvido o remove.
Há uma região, portanto há uma altura e uma dobra, independentemente de quantos painéis houver nela. Dois painéis não podem, cada um, sustentar uma faixa redimensionável e lutar pela tela.
Um painel pode, portanto, ser adicionado sem ser mostrado: ele se junta à faixa, incluindo a barra dobrada, e espera ser clicado. activateDockTab é o ato separado de trazer um para a frente e a única coisa que desdobra o cais.
Dois níveis de switch e por que eles parecem diferentes
Nodes e Edges são as próprias guias da tabela, não as do dock. São duas visualizações de um único painel, portanto não estão listadas ao lado de Audit — isso afirmaria que uma visualização da tabela e um painel separado são o mesmo tipo de coisa.
Os dois níveis são desenhados de forma diferente para que possam ficar próximos um do outro e ainda assim serem lidos como externo e interno:
| Parece | Classe | |
|---|---|---|
Table │ Audit | guias de altura total, sublinhadas quando ativas, fechadas por uma regra | pvt-dock-tabs / pvt-dock-tab |
Nodes │ Edges | um pequeno grupo de comprimidos segmentados | pvt-dock-views / pvt-dock-view |
Um painel com suas próprias visualizações faz o que a tabela faz: desenhe a opção em seu toolbar e chame refresh() em seu identificador para alterar o corpo. As classes internas são públicas, então seu switch é o integrado, e não uma reformulação dele:
function viewSwitch(current, pick) {
const strip = document.createElement('div')
strip.className = 'pvt-dock-views'
for (const view of VIEWS) {
const button = document.createElement('button')
button.className = 'pvt-dock-view'
button.textContent = view.label
button.classList.toggle('active', view.key === current)
button.addEventListener('click', () => pick(view.key))
strip.appendChild(button)
}
return strip
}
graph.UIManager.addDockTab({
label: 'Audit',
toolbar: (pane) => [viewSwitch(current, (key) => { current = key; pane.refresh() })],
render: () => renderCurrentView(),
})Ambos os níveis têm seu sotaque ativo de --pvt-theme-primary, portanto, um consumidor que retifica o tema retifica o dock com ele; substitua qualquer classe para ir mais longe.
refresh() não é educação opcional - o dock mantém o elemento render entregue a ele, então um painel que trocasse seu próprio DOM deixaria o dock reanexando um nó obsoleto na próxima vez que ele fosse para a frente.
Consulte o cartão de galeria Adicionar um painel de encaixe para um ativo e Plugins para a rota do plugin.
UI.dock — as configurações da própria região
open, collapsed e height descrevem a região, não a tabela, e UI.dock é onde eles pertencem:
// A dock holding only a plugin's pane, open on load
UI: { mode: 'full', table: false, dock: { open: true, height: 0.3 } }UI.table ainda carrega as mesmas três configurações e sempre carregava; aqueles são honrados e UI.dock vence onde ambos estão definidos. Alcance UI.dock quando a mesa estiver desligada - essa é a única porta para um encaixe que a guia de um plugin trouxe consigo.
Controle programático
graph.openTable()
graph.closeTable()
graph.toggleTable()Cada um é autônomo quando não há dock (qualquer modo, exceto full ou UI.table: false). openTable() também traz o painel da tabela para a frente, então uma chamada nomeada para a tabela mostra um. Para dirigir pela região sem isso:
graph.UIManager.dock?.setOpen(true) // the region
graph.UIManager.activateDockTab('table') // a pane, unfolding the dock if need be
graph.UIManager.getDockTabs() // what is registered, in strip orderO dock aciona a API de seleção comum, então qualquer coisa que lê uma seleção vê o que a tabela construiu:
graph.selectElements([nodeA, nodeB]) // replaces the selection
graph.addToSelection([nodeC]) // nodes only
graph.removeFromSelection([nodeA])Redimensionar e dobrar
Arraste o divisor ao longo da borda superior do encaixe para redimensioná-lo. A tela mantém o chão o que você pedir - uma tela sem altura não é um gráfico.
A divisa recolhida dobra o encaixe em sua barra de cabeçalho. Deixado sozinho, collapsed: 'auto' toma essa decisão por você e dobra o dock em um layout muito curto para ele e para uma tela utilizável; na primeira vez que você o recolhe ou expande manualmente, ou arrasta a divisória, ele para de decidir e deixa para você.
A barra dobrada ainda nomeia seus painéis, e os controles ativos permanecem nela – a contagem de linhas da tabela, uma revisão dinâmica dizendo que está sendo buscada. É isso que permite que um painel chegue enquanto o dock está dobrado e seja notado sem precisar pegar a tela para avisar. Clicar em um painel abre o encaixe nele.
Um painel que desdobrou o encaixe para se mostrar devolve a região quando é removido, portanto, um painel que vai e vem deixa um encaixe fechado fechado. Dobrá-lo, redimensioná-lo ou mudar para outro painel acaba com isso: cada um é uma decisão sua sobre a região, e nada a desfaz em seu nome.
Abrir o dock nunca move o gráfico
A simulação se ajusta ao container, não à tela, portanto, a abertura e o fechamento do Chrome não podem alterar um layout. Redimensione o dock o quanto quiser: o gráfico permanece no mesmo lugar e um novo layout fornece o mesmo resultado com o dock aberto ou fechado.