Zum Inhalt springen

Pivot-Ergebnisse speichern ​

Pivots & Enrichment endet mit einer Aufnahme: Die ausgewählten Kandidaten werden auf der Arbeitsfläche angezeigt, mit dem Pivot markiert, der sie gebracht hat, und nirgendwo anders. save ist der Schritt zurück – der Pivot schreibt seine eigenen Ergebnisse in das System, aus dem sie stammen, und die Bibliothek führt die Bücher darüber, was sich gekreuzt hat.

summarize  →  fetch  →  triage  →  ingest  →  save
  "2,143"     the 210    the 12    on canvas   in the source system

Die Bibliothek schreibt niemals selbst irgendwo und verfügt über keine Anmeldeinformationen. Was es beiträgt, ist die Buchhaltung – welche Elemente ein Lauf erstellt hat, ob sie geschrieben wurden, welche fehlgeschlagen sind und was ein Wiederholungsversuch beinhalten sollte – denn das ist der Teil, den nur es kennt.

Eines deklarieren ​

js
const objects = {
    id: 'objects',
    label: 'Objects & attributes',
    fetch: (nodes, narrowing, ctx) => api.objects(nodes[0].id, { signal: ctx.signal }),

    save: async ({ origin, nodes, children, edges }, ctx) => {
        const written = await api.createObjects(origin[0].id, [...nodes, ...children], {
            signal: ctx.signal,
        })
        return {
            savedNodeIds: written.ok.map(o => o.localId),
            savedEdgeIds: edges.map(e => e.id),
            canonicalIds: Object.fromEntries(written.ok.map(o => [o.localId, o.uuid])),
            message: written.failed.length ? `${written.failed.length} refused` : undefined,
        }
    },
}

Die Nutzlast besteht aus Live-Diagrammobjekten, nicht aus Rohfragmenten:

FeldWas es enthält
originwhat the pivot was run on — "which event does this attach to"
nodesdie Knoten, die dieser Lauf erstellt hat
childrenBeigefügter Behälterinhalt, abgeflacht; each reachable from its container through parentNode
edgesdie Kanten, die dieser Lauf erzeugte
vouchedwas vor diesem Lauf bereits auf der Arbeitsfläche war
attempt1 beim ersten Mal, höher bei einem erneuten Versuch

Lassen Sie save weg und die Pivot-Ergebnisse sind nicht speicherbar. Sie gelangen nie in das Hauptbuch, werden nie ungespeichert gezählt und für sie wird keine Speicherung angezeigt. Das ist die richtige Deklaration für einen Pivot über abgeleitete Daten – Sie können die Ausgabe einer Korrelations-Engine nicht zurückschreiben – und sie verhindert, dass dauerhaft „210 nicht gespeichert“ ohne Abhilfe angezeigt wird.

Was Sie zurückgeben ​

ZurückgegebenMittel
undefined / trueDie gesamte Nutzlast wurde geschrieben
false oder Werfennichts davon war; Der Fehler erreicht den Wiederholungstoast
{ savedNodeIds, savedEdgeIds }ein teilweiser Schreibvorgang – Alles, was nicht benannt ist, bleibt ungespeichert
{ canonicalIds }ids the source system assigned, keyed by the local id
{ message }wird wörtlich im Ergebnis-Toast angezeigt
{ cancelled: true }the analyst backed out: nothing recorded, no toast, not an attempt

savedNodeIds deckt nodes und children zusammen ab. Eine ID, die ein Element benennt, das dieser Lauf nicht erstellt hat, wird ignoriert: Ein Pivot schreibt niemals, was er nicht erstellt hat, und kann daher auch nicht melden, dass es geschrieben wurde.

Ein Speichervorgang, der eine geschriebene Kante meldet, aber nicht die Knoten, die er verbindet, wird für bare Münze genommen. Was das Quellsystem sagt, dass es geschrieben hat, kann nicht von der Bibliothek außer Kraft gesetzt werden.

Zuerst den Analysten fragen ​

Manchmal benötigt ein Schreibvorgang eine Antwort, bevor er ausgeführt werden kann, beispielsweise welche Beziehung jedes Ergebnis mit dem Knoten verknüpft, von dem aus es angereichert wurde. ctx.promptData öffnet das eigene Modal der Bibliothek mit den gleichen Optionen wie hinter der Knoten- und Kantenerstellung: deklarativ fields oder render + getValues für Ihr eigenes HTML. Es wird auf die Werte oder null beim Abbrechen aufgelöst.

js
save: async (payload, ctx) => {
    const answer = await ctx.promptData({
        fields: [{ key: 'relationship', label: 'Relationship', type: 'text', defaultValue: 'related-to' }],
    })
    if (!answer) return { cancelled: true }
    await api.attach(payload, answer.relationship, { signal: ctx.signal })
},

Das Modal wird mit Speichern betitelt und übermittelt, sofern title und submitLabel nichts anderes angeben. Wenn Sie { cancelled: true } zurückgeben, bleibt der Lauf genau so, wie er vor dem Klicken war: immer noch nicht gespeichert, kein Toast, kein Wiederholungsversuch, und der nächste Versuch ist immer noch attempt: 1. Eine Speicherung über mehrere Durchläufe stoppt beim ersten Abbruch und der Bericht zählt sie unter cancelled und nicht als Fehler. Bei einem abgebrochenen Wiederholungsversuch wird der Toast wieder in den ursprünglichen Zustand versetzt.

Nur ein Speichern, auf das jemand geklickt hat, kann fragen. Das Speichern des Pivot-Bedienfelds, das Speichern eines Überprüfungsbereichs und der Wiederholungsdurchgang des Toasts interactive: true; autoSave und ein einfaches graph.pivots.save() nicht, also löst ihr promptData null sofort auf, ohne dass nichts gezogen wird. Ein Host mit einer eigenen Schaltfläche „Speichern“ übergibt die Flagge ebenfalls:

js
await graph.pivots.save(undefined, { interactive: true })

Bitte um einen ​

js
await graph.pivots.save()          // every savable run with something still unsaved
await graph.pivots.save(runId)     // one run
await graph.pivots.save(pivotId)   // every unsaved run of one pivot

graph.pivots.unsaved()             // the runs still waiting
graph.pivots.unsavedCount()        // { nodes, edges } — exact, not advisory
graph.pivots.unsavedCount(pivotId) // one pivot's share of it
graph.pivots.isSaved(node)         // false for the unsaved *and* the not-savable
graph.pivots.isSavable(node)       // which of those two it is

Teil eines Laufs ​

js
const selected = graph.renderer.getGraphInteraction().getSelectedNodeIDs() ?? []
await graph.pivots.save({ elements: selected })   // Nodes, Edges or their ids

Jeder Lauf, der eines der benannten Elemente erstellt hat, wird einmal abgefragt, wobei die Nutzlast auf den Namen beschränkt wird. Ein benannter Knoten bringt die ausstehenden untergeordneten Knoten unter sich, und eine Kante entsteht, wenn ein Ende benannt wird und das andere ebenfalls benannt wird oder nicht ungeschrieben bleibt: der Ursprung, ein bereits gespeicherter Knoten, alles, worauf das Hauptbuch nicht wartet. Eine ausgelassene Kante zu einem ausstehenden Knoten bleibt erhalten, sodass bei einem Schreibvorgang niemals eine Zeile ins Nichts gesendet wird. Benannte Elemente, auf die nichts wartet, werden ignoriert und der Aufruf erhält für jede angeforderte Ausführung einen Toast.

Der Rest bleibt ausstehend und zählt. Wiederholen und canonicalIds funktionieren wie für den gesamten Lauf. Ein Lauf wird im Verlauf nur dann als dauerhaft markiert, wenn nichts mehr davon zu schreiben ist. isSavable(el) und isSaved(el) geben an, ob ein Menüeintrag wie Auswahl speichern etwas zu tun hat.

Die Läufe erfolgen nacheinander und es wird jeweils nur das gesendet, was noch nicht gespeichert ist – ein erneuter Versuch ist also derselbe Aufruf. Das Ergebnis kommt als Toast: Saved 12 nodes oder Saved 9 of 12 mit einem Retry, der denselben Toast übernimmt, anstatt einen zweiten zu stapeln.

In der Benutzeroberfläche befinden sich die Anzahl und die Schaltfläche am Fuß des Pivot-Bedienfelds, und ein Überprüfungsbereich trägt den Anteil seines eigenen Anbieters in der Kopfzeile. Solange die Zahl Null ist, wird nichts angezeigt.

Beide schreiben alles, was noch aussteht, und haben keine Möglichkeit, etwas auszuwählen. Eine Anwendung, die das Speichern an einer anderen Stelle anbietet, z. B. einen Eintrag Ausgewählte speichern im Knotenmenü, kann sie deaktivieren:

js
new Pivotick(el, data, { pivots: [objects], pivotSaveControls: false })
graph.pivots.saveControls = true   // and back, at runtime

Nur die beiden Bedienelemente gehen. Das Hauptbuch, die Zählungen, save(...), sein Toast und Wiederholungsversuch sowie canonicalIds funktionieren wie zuvor.

autoSave: true schreibt jeden Lauf in dem Moment, in dem er landet, ohne Geste. Es wird ausgeführt, nachdem die Aufnahme aufgelöst wurde, und nicht innerhalb der Datei, sodass ein langsames Backend den Canvas nie aufhält und ein Fehler über den Notifier gemeldet wird und die Daten dort bleiben, wo sie sind. Kombinieren Sie es mit autoIngest: true für einen Pivot, der von Ende zu Ende freihändig ist und ein Ereignis in Objekte erweitert, die bereits der Quelle gehören.

IDs, die das Quellsystem prägt ​

Durch das Speichern wird normalerweise etwas erstellt, und das erstellte Ding erhält normalerweise eine vom Quellsystem gewählte ID, nicht die, die Ihr Anbieter verwendet hat, als es ein Kandidat war. Der morgige Lauf gibt dann dieselben Objekte unter IDs zurück, die Dedup nicht erkennt, und der Analyst erhält zwölf Duplikate dessen, was er gestern gespeichert hat.

Geben Sie canonicalIds zurück und die Bibliothek behält den Alias. Dedup aufnehmen, die untergeordneten Union- und Edge-Endpunkte konsultieren es alle, sodass bei der erneuten Ausführung stattdessen 12 bereits auf Arbeitsfläche angezeigt wird.

js
graph.pivots.canonicalId(node)   // 'a1b2…' — the id the source assigned
Warum der Knoten die ID behält, unter der er gelandet ist

Die Umschlüsselung würde sich auf Kanten, Cluster, Auswahl, Abfrage-Engine, Herkunft und Verlauf auswirken – ein Vorteil, den der Alias bereits dort bietet, wo er wichtig ist. Der ehrliche Preis: graph.getNode(canonicalId) fehlt immer noch, und canonicalId() ist der Lesevorgang, der dies nicht tut.

Das Rückgängigmachen erreicht das Quellsystem nicht ​

Durch das Rückgängigmachen eines gespeicherten Laufs werden seine Knoten aus der Arbeitsfläche entfernt. Es wird nicht etwas von dem System entfernt, auf das sie geschrieben wurden, und die Bibliothek gibt keine kompensierenden Schreibvorgänge aus: Das Rückgängigmachen einer lokalen Ansicht ist keine Transaktion über zwei Systeme hinweg.

Die Historie sagt es, anstatt es Ihnen zu überlassen, es herauszufinden: Ein als durchgeschrieben markierter Lauf wird mit gespeichert gechipt, und in der Fußzeile des Menüs wird gezählt, was eine Spanne hinterlassen würde. PivotRun trägt einen saved-Zähler für eine Oberfläche, die vor dem Klick warnen möchte. Unter Rückgängig machen und Verlauf erfahren Sie, wie ein dauerhafter Eintrag behandelt wird.

Auch ein fehlgeschlagener Speichervorgang berührt nie die Arbeitsfläche. Der Analytiker akzeptierte diese zwölf Knoten; Eine Backend-Ablehnung ist eine Information über das Backend und keine Umkehrung ihrer Entscheidung. Sie bleiben, bleiben ungespeichert und sind weiterhin wiederholbar.

Nicht gespeicherte Knoten markieren ​

js
new Pivotick(el, data, { pivots: [objects], pivotMarkUnsaved: true })

Fügt auf jedem Knoten, den ein Lauf erstellt und nicht zurückgeschrieben hat, eine pvt-node-unsaved-Klasse ein, die ein Stylesheet aufnehmen kann – die Standardeinstellung ist ein gestrichelter Rand. Standardmäßig deaktiviert und eine Klasse anstelle eines Randabzeichens: Ein Knoten hat vier Randecken und nur zwei, sobald er untergeordnete Knoten hat, und ein Marker, der ein deklariertes Potenzial vom Rand entfernt, kostet mehr, als er angibt.