簡素化する
多くのグラフはほとんどが繰り返しです。 2 つのイベントは 40 個の IP を共有し、各 IP にはノード、 ラベルと 2 つのエッジですが、重要なのは「これら 2 つのイベントが 40 個の IP を共有する」ということです。ハブには、 他にどこにもつながっていない数十の葉。 Simplify は、同じ役割を果たすノードを折り畳みます。 1 つの グループ がその場所に描画されます:
const options = {
render: {
nodeTypeAccessor: (node) => node.getData().type,
},
UI: {
simplify: {
rules: [{ kind: 'neighbours', minSize: 5 }],
},
},
}グループはデータではなくビューです
graph.getNodes()、getEdges()、テーブル、エクスポート、および元に戻す履歴は実際のノードを参照します。 グループはグラフが変更されるたびにそれらから再計算され、それに関するものは何も保存されません。
グラフを簡略化します で実行されているのを確認してください カード。
ルール
UI.simplify.rules は順序付きリストです。各ルールはいくつかのノードにキーを与え、ノードはキーを共有します。 キーは少なくとも minSize あれば 1 つのグループになります。
- ルールは順番に 実行され、それぞれはその上のルールによって作成されたグループを通常のものとして認識します。 ノード。したがって、グループは後のルールによって再度グループ化できます。
- ルールはノードフィルターの後に実行されるため、グループはルールを通過したもののみを保持します。 IP が 40 個あり、グループは 37 になります。エッジ層はグループを変更しません。片方だけをオフにする 線を隠します。
- メモが添付されたノードと展開されたクラスターは、決してグループ化されません。閉鎖クラスター 他のノードと同様にグループを作成します。
- 宣言されたルールは、
enabled: falseと表示されていない限りオンになります。
UI.simplify を使用しない場合、full モードでは、Simplify レールでオフになっている組み込みルールが提供されます。 モード;他のモードでは何も実行されません。 UI.simplify.enabled: false は機能を削除します。
隣人ルール
{ kind: 'neighbours', minSize: 5, typeOf: (node) => node.getData().type }1 つのタイプ のノードが、全く同じノードにリンクし、同じ方法で と折り畳まれます。 それらを指す同じノードと、それらが指す同じノード。ハブの葉は、 最も単純なケース。イベント A と B が 3 つの TTP を共有し、それぞれに 2 つの独自の TTP がある場合、次の結果が得られます。 3 つのグループ: A と B の間で 3 つが共有され、各側に 2 つずつあります。
- タイプはルール独自の
typeOf、それ以外の場合はUI.simplify.typeOf、 それ以外はrender.nodeTypeAccessor。ノード間にタイプ グループがないノード。 - 何もリンクされていないノードは決してグループ化されません。グループにはぶら下がる何かが必要です。
- リンクを獲得したノードは、そのグループを離れ、新しい隣接ノードに一致するノードに移ります。もし 残りが
minSize未満になるとグループは解散します。 - グループはそのメンバーのほとんどを維持しながらそのアイデンティティを維持するため、新しいノードは 同じ近隣者は、既存のグループを移動せずに既存のグループに参加します。
連鎖の法則
{ kind: 'chains', minSize: 5, typeOf: (node) => node.getData().type }1 つのノードからぶら下がっているチェーンを折り畳みます。それぞれ独自のハッシュを持つ 30 個のファイルを保持するイベント、 30 チェーン file > sha256: それぞれが独自のハッシュをリンクしているため、ファイルは隣接するファイルを共有しません。 したがって、隣人のルールにより、彼らは放っておかれます。チェーン ルールにより、それらは 1 つのファイル グループにまとめられます。 ハッシュの 1 つのグループにリンクされ、それらの間の 30 のリンクが 1 本の線として描画されます。
- ノードの tail は、そのノードからの唯一のリンクが下流に続くノードです。 ステップリンクはチェーンに沿ってのみ使用できます。他の 2 つのノード、分岐、またはサイクルからリンクされたノードが終了します。 そこに鎖を。
- 同じ形状のリードチェーン が同じものを共有する場合、一緒に折り畳まれるノード リンクとタイプ。 5 つの孤立したペア
domain → ipにより、1 つのドメインにリンクされた 5 つのドメインからなる 1 つのグループが得られます。 5 つの IP のグループ。 - 鎖の各レベルも折り畳まれます: 彼らの頭の下、または人の頭の下 一致しない場合は自分のものになります。
- リンク数 ダウンストリームのみ: 別のノードを指す唯一のリンクを持つノードがそのノードではありません 尻尾。
- 近隣ルールの後に配置され、そのルールが残したものをフォールドします。近隣ルールが作成したグループ 尻尾になる可能性があります。
少数のリンクとコア
{ kind: 'degree', minDegree: 2 }
{ kind: 'kcore', k: 2 }これらのルールは、ノードがどの程度リンクされているかに応じてノードをキャンバスから取り出し、それらをキャンバスに折り込みます。 ノードがぶら下がっているため、カウントはキャンバス上に残ります。
- 少数のリンク (
degree) は、minDegree未満のリンクを持つノードを折りたたみます: 2 では、ハブが離脱します ハブ上で 1 つのグループになります。 - コアの外側 (
kcore) は、k未満のリンクを持つノードを剥がし、再度実行します。 残っているものを使用して、立っているすべてのノードが他のノード間でkリンクを持つまで続けます。 2で折りたたむ 葉だけでなく木全体がグラフから垂れ下がっています。
同じノードに接触する折り畳まれたノードは、そのタイプに関係なく、グループを共有します。 グループは 1 つのノードを保持できます。アンカーには「1 more」と表示されます。折り畳まれたノードがリンクされる 同じグループに入るため、ハブからぶら下がっているパスはハブの葉と一緒に折り畳まれます。の実行 折りたたまれたノードが何も触れずに放置されていると、それ自体が独自のグループとなり、すべてのノードがそれにリンクされます。 1 つのグループを共有するものはありません。どちらの設定も 1 から 10 まであり、リンクはどちらの方向でもカウントされます。
隣接ルールの後、グループはこれらのルールの 1 つのノードになります。そのリンクはそのラインになります。グループ 錨から一人でぶら下がっている状態はそのままです。
コミュニティ
{ kind: 'communities', level: 4 }上記のルールでは大きすぎるグラフの場合、コミュニティは近傍全体を折りたたむ: ノードをさらに増やす グラフの残りの部分が 1 つのグループになるのではなく、互いに密にリンクされています。 タイプ。それらはライデン アルゴリズムを使用して検出され、同じグラフでは毎回同じになります。
levelは、1、細かい、多くの小さなコミュニティから、7、粗い、少数の大きなコミュニティまで続きます。 もの。 Simplify モードではスライダーとなり、手を離すと適用されます。- コミュニティは ** ワーカー** でページ外で見つかり、グラフが表示されたときにのみ再度見つかります。 形状が変化します。一方、カードには グループ化… と表示され、前のグループは残ります。ないところ ワーカーは開始できます。コンテンツ セキュリティ ポリシーは、たとえば BLOB ワーカーをブロックします。同じコードです。 ページ上で実行されます。
useWorker: falseはそれを求めます。 - すべてのルールと同様に、1 つのノードのコミュニティはノードのままであり、注釈付きのノードはノードから残ります。
- 他の組み込みルールとは異なり、コミュニティは宣言されたときのみ単純化モードになります。
ピボット着陸
{ kind: 'landings', minSize: 2 }グループで取り込み、ピボット レビューペインのフッターに、選択した行が表示されます 折りたたみ: タイプごとに 1 つのグループ、ピボットしたノードからぶら下がっています。 40 個の IP が次のように到着します 40 ドットの代わりに「40 × ip」。
- グループは、摂取したものに追加を保持します。すでにキャンバス上にあったノードはそのまま残ります どこにあったか。
- 近隣ルールとは異なり、メンバー ** は、後でリンクされるものは何であっても** のままです。抜いて、削除して 取り消すか、取り込みを取り消して取り消します。 「元に戻す」はグループを解散し、「やり直し」はグループを元に戻します。
- ノード数が
minSize(デフォルトでは 2) より少ないタイプは、プレーン ノードとして配置されます。 - ルールが最初に実行されるため、その後のルールでは各ランディングが 1 つのノードとして認識されます。その必要はありません それを宣言します。最初のグループ化された着陸は、それを単純化モードの一番上に追加し、オンにします。 別の場所に配置するか、最小グループを変更するには、それを宣言します。
- どの着陸がグループ化されるかは、オープン グループと同様にセッションの間持続します。
- 上陸グループの
landing由来の名前:{ runId, pivotId, pivotLabel }、 ピボット定義のラベルを使用します。チップは12 × ip · Event elementsを読み取ることができます 実行IDを解析せずに。
すべてのピボット結果をグループ化して表示するには、pivotIngestGrouped を設定します。ワンクリックで実行され、autoIngest ピボットはレビューを開くことはありませんが、グループ化されることもあります。
new Pivotick(el, data, { pivotIngestGrouped: true })レビューのフッターには次のオプションが続きます。
pivotIngestGrouped | 選択したものを取り込む および すべてを取り込む | 2番目のボタン |
|---|---|---|
| オフ (デフォルト) | 土地が緩んでいる | グループで摂取 |
| に | 土地をグループ化した | ゆるめに摂取 |
UI.simplify がオフの場合、このオプションは何も行わず、2 番目のボタンはありません。
コードから 1 つの取り込みを選択するには、group を渡します。
await graph.pivots.ingest('correlations', 'triage', { group: true })カスタムルール
独自のルールは、ノードごとにキーを返す partition(view) です。
{
kind: 'custom',
id: 'bySensor',
label: 'By sensor', // its name in the Simplify mode
description: 'Sightings reported by the same sensor.',
minSize: 2, // the default for a custom rule
partition: (view) => new Map(view.nodes
.filter((node) => view.typeOf(node) === 'sighting')
.map((node) => [node.id, node.getData().sensor])),
}view は、このルールで見られるグラフです。
| メンバー | それは何ですか |
|---|---|
nodes | このルールがグループ化できるノード: フィルターを通過するもの。メンバーの代わりに以前のルールのグループが含まれます。注釈が付けられたノード、取り出されたノード、および拡張されたクラスターは除外されます。 |
inNeighbours(node) / outNeighbours(node) | このノードへの、またはこのノードからの線を含む描画されたノード。 |
typeOf(node) | ルールをグループ化するタイプ: UI.simplify.typeOf、それ以外の場合は render.nodeTypeAccessor。 |
groupOf(node) | ノードの背後にあるグループ (以前のルールで作成されたグループの場合)。 |
マップから除外されたノードはそのまま残り、view.nodes にない ID は無視されます。あ スローするルールはオフになり、Simplify モードのカードにはその旨が表示され、他のルールは無効になります。 まだ走ります。
簡略化モード
レール上の Simplify ボタンは、ルールごとに 1 枚のカードを実行順序で開きます: スイッチ、その 設定とルールの内容。設定は最小グループの - / + ステッパーです。 最小のリンクまたはコアの強度、およびコミュニティ レベルのスライダー。によって宣言されたルール アプリには app タグが付いています。上部の概要には、キャンバス上にあるノードの数が表示されます。 そのうちの何人がフィルターを通過するか、レール ボタンはルールがフォールドされる間にグループをカウントします。
グループで働く
グループはノードとして描画され、明確な場合はそのメンバーのために機能します。
- ダブルクリック、Enter、サイドバーまたはコンテキストメニューで開きます。そのメンバーが来ます グループの色のウォッシュ内で通常のノードに戻り、軽く引くとノードが保持されます。 一緒に。それらの上のチップをドラッグして、すべてを移動します。 × で折り返されます。そのツールチップ グループを作成したルールに名前を付けます。メンバーは座っていた場所に戻ります。無料がない人 独自の場所がグループ全体に広がり、ライブ物理学が穏やかにプッシュされます。 クラスター。
simulation.fitViewOnExpandCollapseは開閉時のビューにフィットします。グループUI.simplify.openConfirmAbove(100) を超えるメンバーがいる場合は、最初に問い合わせます。 - 選択 を選択すると、サイドバーの並べ替え可能なリストでそのメンバーが表示されます。 引き出すは、 メンバーが元に戻されるまでグループから外します。コンテキスト メニューから次の操作を実行します。 グループが開いているか、グループが開いているかどうかをデータ ドック内のその行から確認します。 選択範囲にわたって、選択されたすべてのメンバーが抽出されます。
- サイドバーまたはコンテキスト メニューの 表で表示 では、データ ドック内のメンバーがリストされます。 ここで、列フィルターによってさらに絞り込まれます。テーブル上のチップには、すべてのノードが再度リストされます。
- メンバーの選択、ピボット、削除 がメンバーに作用します。ピボットと削除が実行されます 通常のフックなので、
onBeforeDeleteは実際のノードを参照します。非表示、削除、ピボット グループを保持する選択は、そのメンバーにも作用します。 - グループを選択すると、そのグループがリンクしているノードが点灯し、ノードを選択するとそのグループが点灯します。 隣人たち。編集と接続はグループでは提供されません。グループには独自のデータがありません。
開いているグループと取り出されたノードはセッション中存続し、手順を元に戻すことはできません。復元するには graph.simplify.open() と pullOut() に電話してください。
手作りで作ったグループ
2 つ以上のノードを選択し、サイドバーのバルク バーで グループ化 または 選択したノードをグループ化 選択したノードのコンテキスト メニュー内。タイトルを入力するか、提示されたタイトルをそのまま使用します (「3 × ip、2 × ドメイン」)。 そして、選択内容はそのタイトルの下で 1 つのグループに折りたたまれます。
- 手作りのグループが勝ちます。 そのルール、手動 は他のグループよりも先に実行されるため、選択されたノードが決まります。 ルールグループを残します。選択されたグループにはそのメンバーが与えられ、ノードは 2 番目のグループに選択されます。 手作りグループは最初に出発します。注釈付きのノードと開いたクラスターは除外され、 プロンプトには数が表示されます。
- メンバーがリンクしているものはすべて 維持されます。削除または除外されたものは、 描かれた;メンバーが 1 人残ったグループはまったく描画されず、そのメンバーを連れて戻ってきます。
- サイドバー パネルまたはコンテキスト メニューから、名前変更 およびグループ解除 を実行します。空のタイトル タイプごとにラベルを再度付けます。バルクバーのグループ解除 は、すべての手作りグループを削除します。 選択が保持されるか、そのままになります。
- グループ化、名前変更、およびグループ解除は、開いたり引き出したりするのとは異なり、手順を元に戻すです。
- これはビューステートです。エクスポートされておらず、リロードすると消えてしまいます。保持するには、
getManualGroups()を保存してください そしてそれをsetManualGroups()に返します。直後に復元、オープン、またはプルされたグループnew Graph()は開口部のレイアウトの一部です。閉じたグループは 1 つのドットとして配置され、開いたグループは 1 つのドットとして配置されます。 メンバーは一緒に保たれます。
const id = graph.simplify.groupNodes(['ip-1', 'ip-2', 'dom-7'], 'Suspicious infra')
graph.simplify.renameGroup(id, 'Cleared infra')
graph.simplify.ungroup(id)検索中
検索では、折りたたまれたノードも含め、すべてのノードが検索されます。
- グループ内の一致の結果行には、in 12 × ip と表示されます。
- これを選択すると、メンバーの選択 と同様に、グループが開き、ノードが選択されます。とのグループ
openConfirmAboveより多くのメンバーは非公開のままになり、代わりに選択されます。 - キャンバス上のすべてを表示、結果の最後の行、またはShift+Enter、結果を閉じます すべての一致を検索して点灯します。他のものはすべて消えます。マッチを持ったグループにも火が灯り、 そしてそのリング上のテーマカラーの弧が彼らのシェアを示しています。そのツールチップはそれらをカウントします。 2/12 は「198.51」 に一致します。 Esc、空のキャンバスをクリックするか、次の検索で終了します。
凡例のエントリにカーソルを合わせると、同じようにグループにマークが付けられます。そのエントリのノードを保持するグループが点灯します。 そのため、タイプが混在するグループは、すべてが 1 つであるとはみなされません。
独自の検索機能を持つアプリは、同じ方法で一致をマークできます。 graph.simplify.setMatches(nodes, query)、setMatches([]) でクリアします。
見た目
グループは、そのタイプの色でディスクの周りにあるリングであり、グループが形成されるとディスク上にカウントが表示されます。 そのためのスペースとその下のラベル。それは制限まで、その数に応じて増加します。タイプを混合したグループ ニュートラルディスクとリングをタイプごとに分割します。
デフォルトでは、ラベルは 12 × ip です。 typeLabel はタイプに名前を付けます:
UI: {
simplify: {
typeLabel: (type, count) => `${count} ${count === 1 ? type : `${type}s`}`,
},
}render.groupStyle(group) は、デフォルトに重ねられた NodeStyle を返すため、tiers、html、 shape とバッジは、ノードと同様にグループでも機能します。 render.groupOutline(group) は何を設定しますか オープングループ上のチップはこう言います:
render: {
groupStyle: (group) => group.rule === 'bySensor' ? { color: '#6b7280' } : undefined,
groupOutline: (group) => `${group.members.length} from ${group.rule}`,
}groupStyle は、ライブラリが描画するスタイルである base も受け取ります。返品したものが置き換えられます そのため、層を追加するホストは base.tiers を分散して、ディスク上にカウントを保持します。
render: {
groupStyle: (group, base) => ({
tiers: [...(base.tiers ?? []), { width: 140, height: 44, style: { html: () => chip(group) } }],
}),
}それぞれが GroupInfo を受け取ります。
| フィールド | それは何ですか |
|---|---|
id | グループがメンバーのほとんどを維持している間は安定しています。 |
rule | 'neighbours'、'chains'、'degree'、'kcore'、'communities'、'landings'、'manual'、またはカスタム ルールの id。 |
members | それが表す実際のノード。 |
typeCounts | 各タイプのメンバーの数。 '' はタイプがありません。 |
anchors | リンク先の描画ノードとグループが含まれます。 |
open | メンバーがキャンバスに戻っているかどうか。 |
level | 見つかったコミュニティ レベル。 |
title | 手作りグループのタイトル。 |
landing | 着陸グループのランとピボット: { runId, pivotId, pivotLabel }。 |
グループのツールチップには、そのルールの名前が表示され、そのルールのリンク先がリストされます。また、混合グループの場合は、そのルールがリストされます。 タイプ別のメンバー。 tooltip.renderGroupExtra(group, ctx) は次のように独自の行を追加します。 renderNodeExtra はノードに対して行われます。グループは tooltip.render と renderNodeExtra をスキップします。 ノードのデータ用に書き込まれます。
ホストからの種類と色
グループは自分のパートをrender.nodeTypeAccessorで数え、各メンバーの色で色分けします。 スタイルカラー。 2 つの UI.simplify オプションは、ルールとグループごとに変更します。 スタイル、凡例、またはフィルターに触れる:
typeOf(node)は、すべてのルールがグループ化するタイプであり、すべてのグループはその部分を次のようにカウントします。 レーベル、ミックスリングのシェア、手作りグループのタイトル。ルール自身のtypeOfが依然として勝ちます そのルールのために。colorOf(node)はグループ内のノードを表す色です: ディスクとリング、オープン ツールチップのチップを洗います。undefinedを返すと、ノードのスタイルの色に戻ります。あ グループ自身のgroupStyleが、閉じられた図面の最後の言葉をまだ持っています。
要素ごとにスタイルを設定し、サブタイプごとにグループ化し、ノード自体を描画するホスト:
const options = {
render: {
nodeTypeAccessor: (node) => node.getData().element,
nodeStyleMap: { attribute: { shape: 'none', html: drawAttribute } },
},
UI: {
simplify: {
typeOf: (node) => `${node.getData().element}:${node.getData().subtype}`,
colorOf: (node) => palette[node.getData().subtype],
},
},
}表の中で
データ ドックには実際のノードがリストされます。折りたたまれたノードの Visibility 列には grouped が表示されます。 Group 列には、グループが存在する場合にそのグループの名前が付けられます。線が引かれているエッジ グループもgroupedと読みます。
実行時
graph.simplify はルールとグループを保持します。
| 方法 | 何をするのか |
|---|---|
setRules(rules) / getRules() | ルールを置き換えます。それぞれの状態とそれが折りたたまれたものを読み取ります。 |
setRuleEnabled(id, on) / setRuleSetting(id, n) | Simplify モードのスイッチとステッパーの機能。 setRuleMinSize(id, n) は最小のグループのみを設定します。 |
getGroups() / groupOf(node) | すべてのグループ、およびノードが組み込まれた最初のグループ。後でルールが再度折り畳まれたグループも、それを保持するグループの横にリストされ、両方ともそのメンバーをリストします。 summary().groups は、キャンバスが描画する閉じたグループをカウントします。 |
open(group) / close(group) | グループのメンバーをキャンバス上に配置するか、後ろに折り曲げます。 |
pullOut(node) / putBack(node) / isPulledOut(node) | ノードをどのグループにも属さないようにするか、元に戻します。 |
groupNodes(nodes, title?) / renameGroup(group, title) / ungroup(groups) / isManual(group) | グループを手動で作成、タイトル変更、または削除;それぞれが元に戻すステップです。 |
getManualGroups() / setManualGroups(list) | 手作りしたグループを保存し、復元します。 |
groupLanding(runId) / ungroupLanding(runId) / isLandingGrouped(runId) | ピボット ランによって追加されたものを 着地グループ に折りたたむか、もう一度緩めに描きます。 |
summary() | 描画され、フィルターを通過し、折り畳まれるノードの数。 |
setMatches(nodes, query) / matchesIn(group) | 検索の一致を保持するグループにマークを付けます。グループがいくつ保持しているかを読み取ります。 |
onChange(listener) | グループ化が変更された後に呼び出されます。購読解除を返します。 |