UI-opties
Pivotick biedt een flexibele UI-laag bovenop uw grafiek, waardoor u kunt bepalen hoe gebruikers omgaan met knooppunten, randen en het canvas. Met UI-opties kunt u:
- Configureer de algehele mode van de gebruikersinterface (volledig, viewer, statisch, enz.).
- Pas zijbalk en panelen aan om eigenschappen of extra informatie weer te geven.
- Definieer tooltips voor knooppunten en randen, met optionele aangepaste renderers.
- Configureer contextmenu's voor knooppunten, randen en het canvas.
- Declareer de facetten van het paneel filter, of laat ze afleiden uit uw gegevens.
- Plaats een legend op het canvas — een sleutel voor uw kleuren die ook dienst doet als filter en die vanzelf verschijnt wanneer uw kleuren worden verklaard door een gedeclareerd knooppunttype.
- Vul elk van deze oppervlakken asynchroon, op basis van gegevens die u op aanvraag ophaalt.
- Schakel alle functies uit waarvoor uw integratie geen nut heeft.
- Zet de eigen tekst van de bibliotheek in de taal van uw gebruikers: zie De gebruikersinterface vertalen.
UI-modus
De optie mode regelt het algehele gedrag en interactieniveau van de grafische gebruikersinterface.
fullstandaard: Volledige gebruikersinterface met alle panelen, menu's en interacties ingeschakeld.light: Minimale gebruikersinterface met essentiële interacties ingeschakeld.viewer: Hiermee kunt u alleen door de grafiek navigeren (pannen, zoomen, slepen) zonder dat er UI-panelen worden weergegeven.static: Statische grafiek, geen UI-panelen of interacties; de grafiek is alleen-lezen.
Gebruik het volgende voor afbeeldingsstijlgebruik van Pivotick:
const container = document.getElementById('graph-container')
const options = {
UI: {
mode: 'viewer'
},
}
const graph = Pivotick(container, options)Andere UI-componenten kunnen worden geconfigureerd via hun respectievelijke naamruimte
const options = {
UI: {
sidebar: {},
mainHeader: {},
propertiesPanel: {},
extraPanels: [],
tooltip: {},
contextMenu: {},
filter: {},
}
}Het bedieningsoppervlak in de full-modus
In de full-modus is het chroom een modusgestuurde lay-out: een linker mode rail (Selecteren / Maken / Bekijken / Fysica), een contextueel gereedschapspaneel voor de actieve aanwijzermodus, twee vervolgkeuzelijsten — Beeld (canvasachtergrond en schakelaars) en Natuurkunde (lay-out + simulatie) — de bovenste balk (zoeken, filteren, notities, ongedaan maken/opnieuw uitvoeren), de selectie zijbalk (eigenschappen, facetten, buren en een rij met bulkacties), en een viewportrail aan de rechterkant (fit-and-center, zoom, instellingen, volledig scherm) en een minimap in de vrije rechterbenedenhoek, die zichzelf wegklapt wanneer het canvas te klein is om de kamer te sparen (UI.minimap: false om het te laten vallen). light in de modus worden de zijbalk en de minimap verwijderd; viewer behoudt alleen de viewportrail; static is een kaal canvas.
Migreren vanuit het hoekchroom
De zwevende overlays GraphControls en GraphToolbar zijn verwijderd. Indeling en natuurkunde is verplaatst naar de natuurkunde-flyout (UIManager.physicsFlyout) — ze zijn verzonden in de Bekijk de vervolgkeuzelijst (UIManager.viewFlyout) in 1.5.0, die nu de canvasachtergrond bevat en de netschakelaars. Selecteer/maak gereedschappen live in het gereedschapspaneel (UIManager.toolPanel) en moderail (UIManager.modeRail). De De optie UI.selectionMenu is verdwenen — gebruik contextMenu voor acties per knooppunt en de bulkactierij in de zijbalk voor acties met meerdere selecties. UIManager.graphNaviation was hernoemd naar graphNavigation. De optie UI.modeRail en de uitgeschakelde optie Explore / Enrich slots zijn verwijderd — registreer een echte modus met addRailMode in plaats daarvan. Zie de CHANGELOG.
De vier modi van de rail zijn ingebouwd, maar niet de enige die deze kan bevatten: een plug-in voegt deze toe eigen met addRailMode, wat is hoe een Explore- of Enrich-modus weet wat uw data betekent, wordt gebouwd.
Functies uitschakelen
De UI-modus bepaalt hoeveel chroom een grafiek krijgt. Elke functie in dat chroom kan ook één voor één worden uitgeschakeld, en zo laat een integratie vallen wat het is backend of zijn gebruikers hebben er geen nut voor.
Een uitgeschakelde functie neemt alles mee wat erbij komt: de knop, het paneel, het contextmenu-item en de sneltoets werken allemaal samen, dus er blijft niets over achter om te klikken of te drukken en stilletjes te weigeren.
const options = {
UI: {
mode: 'full',
notes: { enabled: false },
history: { enabled: false },
inspector: { enabled: false },
editors: { deletion: { enabled: false } },
},
}De schakelaars
| Optie | Wat hoort erbij |
|---|---|
UI.topBar.enabled | De bovenste strip, de gereserveerde hoogte, de eigen snelkoppelingen (Shift+J, Shift+K, Shift+N, Mod+Z) en eventuele hostacties. Gebruik de onderstaande schakelaars om één pil te laten vallen en de rest te bewaren. |
UI.search.enabled | De zoekpil, de knooppuntkiezer en Shift+J. |
UI.filter.enabled | De Filtergrafiekpil, het bijbehorende paneel en Shift+K. graph.queryEngine filtert nog steeds uit code. |
UI.notes.enabled | De Notitiepil en het paneel Notities, Shift+N, het gereedschap Notitie toevoegen, Notitie toevoegen in het canvasmenu, N, het notitiecontextmenu, en noteManager.addNote, dat weigert. |
UI.history.enabled | De knoppen voor ongedaan maken/opnieuw uitvoeren, hun geschiedeniskeuzemenu en Mod+Z / Mod+Shift+Z. graph.history gaat door met opnemen. |
UI.inspector.enabled | In het knooppuntmenu staat het item Eigenschappen inspecteren en I. |
UI.notifications.enabled | Toast. graph.notifier.* wordt een no-op-return undefined. |
UI.sidebar.enabled | De hele zijkolom en de breedte die daarvoor nodig was. |
UI.propertiesPanel.enabled | Het eigenschappenpaneel van de zijbalk en het scheidingsteken ervan. |
UI.neighborsPanel.enabled | Het aangrenzende paneel van de zijbalk en het scheidingsteken ervan. |
UI.viewFlyout.enabled | De View rail-knop en het bijbehorende paneel. |
UI.physicsFlyout.enabled | De natuurkunderailknop en het bijbehorende paneel. |
UI.tooltip.enabled | Beweeg de muis over tooltips, inclusief vastgezette tooltips. Neemt ook { nodes, edges, groups } of (element, kind) => boolean, zie Tooltips. |
UI.contextMenu.enabled | Elk contextmenu. |
UI.navigation.enabled | De viewportrail: passen, zoomen en volledig scherm. |
UI.legend: false | De canvaslegende, inclusief degene die hij zelf zou afleiden. |
UI.minimap: false | De minikaart. |
UI.emptyState: false | Op de kaart wordt een leeg canvas weergegeven. |
UI.table: false | Het datadock en zijn Shift+T. |
UI.pivotMode: false | De Pivotrail-modus, wat er ook wordt geregistreerd. |
Schrijfpadfuncties hebben dezelfde schakelaar onder UI.editors, dus alleen-lezen integratie elimineert de betaalbaarheid in plaats van elke klik te vetoën: nodeCreator, edgeCreator, nodeEditor, edgeEditor en deletion.
Het gedrag van de renderer wordt uitgeschakeld onder render: zoomEnabled (wat ook de zoomknoppen van de rail, waarbij ze fit en gecentreerd blijven), dragEnabled, selectionBox.enabled (het selectiekader en het gereedschap Selecteren ▸ Lasso), enableNodeExpansion (de chevron, zijn Enter en de streepjes stortten in overzicht), enableFocusMode, en interactionEnabled voor alles tegelijk. simulation.enabled stopt de lay-out van rennen.
De Create-modus volgt zijn tools
De modus Spoor maken bevat precies vier gereedschappen: Knooppunt toevoegen, Rand toevoegen, Notitie toevoegen en Bewerken knooppunt. Schakel ze alle vier uit en de modus verlaat de rail, samen met de C snelkoppeling, in plaats van te openen op een leeg paneel. Selecteer blijft altijd.
Je eigen acties in de bovenste balk
Een actie op het hele canvas, zoals het opslaan ervan, hoort thuis in de bovenste balk naast het groep ongedaan maken-opnieuw uitvoeren. UI.topBar.actions declareert pillen getekend in dezelfde stijl als Zoeken, Filter en notities, dus een thema dat deze opnieuw opmaakt, verandert deze ook.
const options = {
UI: {
topBar: {
actions: [{
id: 'save-graph',
text: () => storedId ? 'Update graph' : 'Save as graph',
async onclick(_event, ctx) {
if (storedId) return updateGraph(storedId, ctx.graph)
const values = await ctx.promptData({
fields: [{ key: 'name', label: 'Name', type: 'text' }],
})
if (values) storedId = await createGraph(values.name, ctx.graph)
},
menu: () => storedId
? [{ text: 'Save as new graph…', onclick: saveAsNew }]
: [],
}],
},
},
}- Waar.
placement: 'end'(de standaardinstelling) plaatst de pil net vóór het ongedaan maken-opnieuw uitvoeren groep;'start'zet het na de ingebouwde pillen aan de linkerkant. Pillen houden de orde ze zijn aangegeven in. - Wat er staat.
text,title,visibleenenablednemen een waarde of een functie aan van de grafiek. De functies worden na elke gegevenswijziging opnieuw uitgelezengraph.UIManager.refreshTopBar(), en zodra een belofte die dooronclickwordt geretourneerd, wordt afgehandeld. Zolang die belofte niet bestaat, is de pil uitgeschakeld, dus een langzame opslag kan niet twee keer worden gestart. - Wat het krijgt.
onclick(event, ctx)ontvangt de grafiek en twee helpers die de modale bibliotheek:ctx.promptData({ fields })wordt omgezet in de waarden ofnullop annuleren, enctx.confirm({ body })losttruealleen op via de bevestigingsknop.ctx.refresh()leest elke actie opnieuw. - Een caret. Met
menuwordt de pil een splitsknop: het label looptonclick, en een dakje opent de rijen, in hetzelfde rijformaat als de contextmenu's (zonder submenu's). Een functieformulier krijgt dezelfdectxen wordt op elke aangeroepen vernieuwen en elke opening; terwijl er geen rijen worden geretourneerd, heeft de pil geen dakje. Ontsnappen of een ergens anders klikken sluit de rijen. - Een snelkoppeling.
shortcuttekent een badge op de pil. Het is alleen een label: registreer het jezelf binden.
Een plug-in voegt een pil toe met ctx.addTopBarAction(action), die een ontdoener retourneert (zie Plug-ins). De pillen volgen de strip: geen in viewer of static modus, en geen met UI.topBar.enabled: false.
Een leeg canvas
Een grafiek zonder knooppunt en zonder notitie toont een kaart in het midden van het canvas, een bron dus als er niets te tekenen is, wordt dit niet gelezen als een grafiek die niet kan worden geladen. Er staat: "Niets aan de hand het canvas nog niet', tenzij je het iets anders geeft om te zeggen:
const options = {
UI: {
emptyState: {
render: ({ initial, graph }) => {
const box = document.createElement('div')
box.textContent = initial ? 'Nothing is related to this record.' : 'The canvas is empty.'
const button = document.createElement('button')
button.textContent = 'Find related'
button.onclick = () => graph.UIManager.openPivotMode()
box.append(button)
return box
},
},
},
}De kaart volgt de gegevens. Door een knooppunt of een notitie toe te voegen, wordt deze weggenomen en de laatste verwijderd van hen, met de hand of door de inname die hen heeft gebracht ongedaan te maken, brengt het terug. Knooppunten de filters verbergen tellen nog steeds mee: de grafiek is versmald, niet leeg.
render wordt uitgevoerd elke keer dat de kaart verschijnt, niet bij elke wijziging terwijl deze open is. initial is true totdat de grafiek een knooppunt heeft gehad, dus een analist die een volledig canvas heeft leeggemaakt, kan iets anders verteld wordt dan wat een lege bron verteld wordt. Een geretourneerde tekenreeks wordt weergegeven als platte tekst, en render kan async zijn, zoals de haken hieronder.
De kaart gebruikt het chroomoppervlak en de rand, zodat deze het thema volgt. Het laat de canvasbewegingen door, dus pannen, zoomen en het canvasmenu werken er doorheen, behalve over interactieve inhoud: een knop, een link, een formulierbesturingselement of iets met een tabindex krijgt zijn eigen klikken. UI.emptyState: false toont helemaal niets.
Asynchrone inhoud
Elke door de consument geleverde content hook kan een Promise retourneren in plaats van de inhoud zelf. Dat bedekt de zijbalk mainHeader.render, propertiesPanel.render / nodePropertiesMap / edgePropertiesMap, neighborsPanel.render, een extra paneel title en render, de tooltip render, renderNodeExtra, renderEdgeExtra en vastgoedkaarten, en de lege canvas's render.
Dit geldt voor het geval waarin de gegevens van een knooppunt een referentie naar een record zijn, in plaats dan het record zelf, en de interessante inhoud zit achter een HTTP-oproep:
const options = {
UI: {
tooltip: {
renderNodeExtra: async (node, { signal }) => {
const res = await fetch(`/enrich/${node.getData().uuid}`, { signal })
return renderChips(await res.json()) // an HTMLElement
},
},
},
}Voeg async toe, stuur signal door en de bibliotheek zorgt voor de rest:
| Tijdelijke aanduiding | Terwijl de belofte in behandeling is, bezet een thema-skelet de slot. |
| Wisselen | Bij het oplossen vervangt de inhoud de tijdelijke aanduiding. |
| Stoutheid | Een resultaat dat binnenkomt nadat het slot is verdwenen (je hebt de muisaanwijzer op een ander knooppunt geplaatst, de selectie gewijzigd, het paneel vernieuwd) is dropped. Alleen de meest recente weergave voor een oppervlak kan een commit uitvoeren, in welke volgorde ze ook worden opgelost. |
| Annulering | ctx.signal wordt afgebroken wanneer een render wordt vervangen of de grafiek wordt afgebroken, dus een doorgestuurde fetch wordt geannuleerd in plaats van gelekt. |
| Mislukking | Een afgewezen belofte levert een compacte foutlijn op in plaats van voor altijd een spinner achter te laten. Een afgebroken render is geen mislukking en toont niets. |
De rendercontext
Elke inhoudshaak krijgt een RenderContext als zijn laatste argument. Bestaande synchrone hooks negeren het eenvoudigweg.
render: async (element, { signal, isStale }) => {
const rows = await fetchRows(element, signal)
if (isStale()) return '' // cheap guard for non-abortable work
return renderRows(rows)
}De tijdelijke aanduiding aanpassen
UI.asyncContent overschrijft wat wordt weergegeven tijdens de behandeling en bij mislukking. Beide accepteer een string, een HTMLElement of een functie van het oppervlak:
const options = {
UI: {
asyncContent: {
placeholder: (surface) => surface === 'tooltip' ? 'Loading…' : mySkeleton(),
error: 'Could not load',
},
},
}surface is een van 'tooltip', 'properties', 'neighbors', 'mainHeader', 'extraPanel' of 'emptyState'.
Synchrone haken zijn onaangeroerd
Het direct retourneren van inhoud gedraagt zich precies zoals altijd: dezelfde oproep, hetzelfde frame, geen tijdelijke aanduiding en geen wrapper-element. Niets over een bestaand integratieveranderingen.
Wat kan niet asynchroon zijn
Twee groepen blijven met opzet synchroon:
HeaderMapEntry.title/subtitlevoedt het automatisch passende titelslot en knooppunt zoeken (resolveNodeByName), die beide nu de tekst nodig hebben. Gebruik een asyncmainHeader.renderals u opgehaalde details in de header nodig heeft.PropertyEntry.name/value— haal in plaats daarvan de rijen op: een asyncnodePropertiesMapwordt één keer opgelost en geeft dan gewone invoer terug dan een spinner in elke cel te plaatsen.
De renderer per frame haakt (render.renderNode, renderLabel, renderCluster en NodeStyle.html) zijn ook alleen voor synchronisatie: ze lopen binnen het tekenpad, per knooppunt, per tik. Als u een async-knooppunt decoration nodig heeft, haalt u de gegevens van het knooppunt op en laat de synchrone renderer het lezen.