Naar inhoud
Pivotick
Main Navigation Startpagina
Aan de slag
Configuratie
Gegenereerde API-documentatie
GalerijProjectenProbeer het uit!

Nederlands

English
简体中文
Français
Deutsch
Português
日本語
العربية
Español

Nederlands

English
简体中文
Français
Deutsch
Português
日本語
العربية
Español

Weergave

Sidebar Navigation

Aan de slag

Projecten met Pivotick

Configuratie

Callbacks

Verbindingslagen

Vereenvoudigen

Indeling

Weergave

Simulatie

Interface aanpassen

Zijbalk

Tooltip

Contextmenu

Filters

Legenda

Gegevenstabel

Interface vormgeven

Interface vertalen

Plug-ins

Pivotick-API

Pivots en verrijking

Pivotresultaten opslaan

Ongedaan maken en geschiedenis

Beveiliging

API-documentatie

Galerij

Basis

Knopen vormgeven

Verbindingen vormgeven

Indelingen

Gebeurtenissen en callbacks

Interface aanpassen

Bewerken en maken

Notities en annotaties

Filteren, zoeken en hiërarchie

Programmatische besturing

Thema's en prestaties

Pivots en verrijking

Uitgelichte voorbeelden

Vereenvoudig de grafiek ​

Het grootste deel van deze grafiek bestaat uit herhaling: acht IP's op beide gebeurtenissen, zes domeinen op één, negen bestanden op een gastheer, tien waarnemingen. UI.simplify.rules vouwt knooppunten die dezelfde rol spelen samen tot één groep op hun plaats getekend. De gegevens zijn onaangetast: graph.getNodes() retourneert nog steeds elke knooppunt.

Hier gelden twee regels, in volgorde. Door sensor is eigendom van de app: hij geeft elke waarneming zijn sensor als een sleutel, en knooppunten die een sleutel delen, worden één groep. De ingebouwde burenregel vouwt dan op knooppunten van één type die zijn gekoppeld aan exact dezelfde knooppunten.

  • Open de modus Vereenvoudigen op de rail om een regel uit te schakelen of de kleinste groep ervan te wijzigen.
  • Dubbelklik op een groep om de leden ervan weer op het canvas te plaatsen. Sleep de chip erboven naar verplaats ze samen; de × vouwt ze terug.
  • Selecteer een groep: de zijbalk vermeldt de leden, elk met Uittrekken.

De pagina Vereenvoudigen behandelt de regels, aangepaste regels en het uiterlijk van de groep.

js
const plural = { ip: 'IPs', domain: 'domains', file: 'files', sighting: 'sightings' }

const simplify = {
    rules: [
        // An app rule: a key per node, and nodes sharing a key become one group.
        // It runs first, so the sightings split by sensor before the neighbour
        // rule would fold all ten of them together.
        {
            kind: 'custom',
            id: 'bySensor',
            label: 'By sensor',
            description: 'Sightings reported by the same sensor.',
            partition: (view) => new Map(view.nodes
                .filter(node => view.typeOf(node) === 'sighting')
                .map(node => [node.id, node.getData().sensor])),
        },
        // The built-in rule: one type, exactly the same neighbours, five or more.
        { kind: 'neighbours', minSize: 5 },
    ],
    typeLabel: (type, count) => `${count} ${plural[type] ?? type}`,
}
js
const options = {
    UI: {
        mode: 'full',
        // Off: this card is about neither the minimap nor the data dock.
        minimap: false,
        table: false,
        simplify,
    },
    // Longer links, so the labels under the groups have room.
    simulation: { physics: 'manual', d3LinkDistance: 70 },
    render: {
        nodeTypeAccessor: (node) => node.getData().type,
        nodeStyleMap: {
            event: { color: '#7c3aed', size: 16 },
            host: { color: '#475569', size: 14 },
            ip: { color: '#0ea5e9' },
            domain: { color: '#10b981' },
            file: { color: '#e11d48' },
            sighting: { color: '#f59e0b' },
        },
        // A group made by the app's rule names its sensor.
        groupStyle: (group) => group.rule === 'bySensor'
            ? { text: () => `${group.members.length} from ${group.members[0].getData().sensor}` }
            : undefined,
    },
}
js
// Two events share eight IPs, the first alone has six domains, a host has nine
// files, and the second event has ten sightings from two sensors.
const ips = Array.from({ length: 8 }, (_, i) => ({ id: `ip-${i}`, data: { type: 'ip', label: `198.51.100.${10 + i}` } }))
const domains = Array.from({ length: 6 }, (_, i) => ({ id: `dom-${i}`, data: { type: 'domain', label: `site-${i}.example` } }))
const files = Array.from({ length: 9 }, (_, i) => ({ id: `file-${i}`, data: { type: 'file', label: `sample-${i}.bin` } }))
const sightings = Array.from({ length: 10 }, (_, i) => ({
    id: `seen-${i}`,
    data: { type: 'sighting', label: `Sighting ${i + 1}`, sensor: i < 6 ? 'north' : 'south' },
}))

const data = {
    nodes: [
        { id: 'ev-1', data: { type: 'event', label: 'Event 1' } },
        { id: 'ev-2', data: { type: 'event', label: 'Event 2' } },
        { id: 'host', data: { type: 'host', label: 'Build host' } },
        ...ips, ...domains, ...files, ...sightings,
    ],
    edges: [
        ...ips.flatMap(ip => [{ from: 'ev-1', to: ip.id }, { from: 'ev-2', to: ip.id }]),
        ...domains.map(domain => ({ from: 'ev-1', to: domain.id })),
        ...files.map(file => ({ from: 'host', to: file.id })),
        ...sightings.map(sighting => ({ from: 'ev-2', to: sighting.id })),
        { from: 'ev-2', to: 'host' },
    ],
}
Pager
Volgende paginaAan de slag