データテーブル
フォース レイアウトは、人々が常に行っている 3 つのこと、つまり正確な値を読み取るのが苦手です。 大規模に選択し、どこから始めるべきかを検討します。 UI.table は データドック を分割します キャンバスの下部にある 3 つすべてに答えることができます。つまり、並べ替え可能で選択可能なグラフの行です。
ループは 検索するテーブル、理解するキャンバス、読むためのサイドバー:
- テーブルはリクエストごとにソートされて開くため、最もビジーなサービスが最初の行になります。
- 再並べ替えするには、見出しをクリックします。もう一度クリックすると元に戻ります。
- 行をクリックして選択するか、
Ctrl+Clickを押して行を追加します。またはShift+Clickを範囲に示されている順序で — 次に動作します サイドバーの一括アクションを使用してロットにアクセスします。 - 代わりにキャンバス上のグループをラバーバンドで結ぶと、一致する行が点灯します。
- ヘッダーから行を絞り込みます — コントロールは列の後に続きます: と入力します。 サービス、種類から選択、リクエスト/日に制限を設定します。それは決して触れない キャンバス: グラフ自体のフィルターはフィルター パネルに残るため、この 2 つは争うことができません。
- ノード / エッジ リストされる内容を切り替えます。 CSV と JSON を正確に書き出してください が画面上にあります - このタブ、これらの列、この並べ替え、このフィルター。
ドックには、グラフが現在 非表示 になっているノードも Visibility 列とともにリストされます。 フィルタまたは手動の非表示が原因であるかどうかを示しています。つまり、「23 ノードが非表示になっている」ということになります。 信頼するのではなく検査できるもの。
仕切りをドラッグしてサイズを変更するか、山形の付いたヘッダー バーに折り曲げます。どちらでもない グラフを移動します。シミュレーションはキャンバスではなくコンテナに対して自動的に調整するため、 クロムの開閉ではレイアウトが変更されることはありません。
完全なオプションセットについては、データテーブルを参照してください。
js
// import { ColorPaletteMapper, tableColumns } from 'pivotick'
//
// The data dock comes with `mode: 'full'`, folded to its header bar — click the chevron
// or press Shift+T. `open: true` below starts it expanded instead. Everything here is
// optional; `UI: { mode: 'full' }` alone gets you a dock.
//
// Columns are derived when you don't declare any: the graph-aware ones lead (Label,
// Degree, Visibility) and the data keys follow, ordered by how many nodes carry them.
// They are declared here instead, to put `requests` on the right and give three columns
// a row filter — one of each kind, since the control follows the column's `type`.
// `tableColumns` holds the graph-aware ones — clone one to relabel it.
const options = {
UI: {
mode: 'full',
// Full mode's minimap would sit in the corner this card wants for the dock,
// and the dock is the subject — see the Minimap card for that one.
minimap: false,
// Top-left, because this embed is 560px tall and the dock takes 42% of it: the
// canvas that's left is shorter than the mode rail, so the bottom-left corner has
// no column to give. A bottom-left legend would shrink to its header here.
legend: { position: 'top-left' },
table: {
open: true,
height: 0.42,
// Busiest first — the question you actually arrive with.
sort: { key: 'requests', direction: 'desc' },
columns: [
{ ...tableColumns.label, label: 'Service', filterable: true },
{ key: 'kind', label: 'Kind', type: 'select', filterable: true },
{ key: 'owner', label: 'Owner', type: 'select' },
{ key: 'tier', label: 'Tier', type: 'select' },
{ key: 'requests', label: 'Requests / day', type: 'numberRange', align: 'right', filterable: true },
{ ...tableColumns.degree, label: 'Links' },
],
},
},
// Colour by the same `kind` the table shows, so a row and a dot can be matched by
// eye. Declaring `nodeTypeAccessor` is also what earns the canvas its legend.
render: {
nodeTypeAccessor: (node) => node.getData().kind,
defaultNodeStyle: {
color: (node) => palette.getColor(node.getData().kind),
},
},
}js
const data = {
nodes: [
{ id: 'api', data: { label: 'api-gateway', kind: 'service', owner: 'Platform', requests: 48200, tier: 'edge' } },
{ id: 'auth', data: { label: 'auth-service', kind: 'service', owner: 'Identity', requests: 31400, tier: 'core' } },
{ id: 'billing', data: { label: 'billing-service', kind: 'service', owner: 'Payments', requests: 8600, tier: 'core' } },
{ id: 'search', data: { label: 'search-service', kind: 'service', owner: 'Discovery', requests: 22750, tier: 'core' } },
{ id: 'users-db', data: { label: 'users-db', kind: 'datastore', owner: 'Identity', requests: 39900, tier: 'data' } },
{ id: 'orders-db', data: { label: 'orders-db', kind: 'datastore', owner: 'Payments', requests: 12300, tier: 'data' } },
{ id: 'index', data: { label: 'search-index', kind: 'datastore', owner: 'Discovery', requests: 20100, tier: 'data' } },
{ id: 'cache', data: { label: 'edge-cache', kind: 'datastore', owner: 'Platform', requests: 51000, tier: 'edge' } },
{ id: 'mailer', data: { label: 'mailer', kind: 'worker', owner: 'Payments', requests: 1450, tier: 'async' } },
{ id: 'reindexer', data: { label: 'reindexer', kind: 'worker', owner: 'Discovery', requests: 980, tier: 'async' } },
],
edges: [
{ from: 'api', to: 'auth', data: { label: 'authenticates' } },
{ from: 'api', to: 'search', data: { label: 'queries' } },
{ from: 'api', to: 'billing', data: { label: 'charges' } },
{ from: 'api', to: 'cache', data: { label: 'reads' } },
{ from: 'auth', to: 'users-db', data: { label: 'reads' } },
{ from: 'billing', to: 'orders-db', data: { label: 'writes' } },
{ from: 'billing', to: 'mailer', data: { label: 'enqueues' } },
{ from: 'search', to: 'index', data: { label: 'reads' } },
{ from: 'reindexer', to: 'index', data: { label: 'writes' } },
{ from: 'reindexer', to: 'orders-db', data: { label: 'reads' } },
],
}