feat: improve performance panel
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 1m54s
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 1m54s
This commit is contained in:
parent
66ae9e6c72
commit
bd359fbaf7
@ -17,9 +17,6 @@
|
|||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
{#if !activeUser}
|
{#if !activeUser}
|
||||||
<div class="header">
|
|
||||||
<h3>Users</h3>
|
|
||||||
</div>
|
|
||||||
{#await registry.fetchUsers()}
|
{#await registry.fetchUsers()}
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
{:then users}
|
{:then users}
|
||||||
@ -37,15 +34,6 @@
|
|||||||
{#await registry.fetchUser(activeUser)}
|
{#await registry.fetchUser(activeUser)}
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
{:then user}
|
{:then user}
|
||||||
<div class="header">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
$activeId = "";
|
|
||||||
}}
|
|
||||||
class="i-tabler-arrow-back"
|
|
||||||
></button>
|
|
||||||
<h3>Collections</h3>
|
|
||||||
</div>
|
|
||||||
{#each user.collections as collection}
|
{#each user.collections as collection}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
@ -59,15 +47,6 @@
|
|||||||
<div>{error.message}</div>
|
<div>{error.message}</div>
|
||||||
{/await}
|
{/await}
|
||||||
{:else if !activeNode}
|
{:else if !activeNode}
|
||||||
<div class="header">
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
$activeId = activeUser;
|
|
||||||
}}
|
|
||||||
class="i-tabler-arrow-back"
|
|
||||||
></button>
|
|
||||||
<h3>Nodes</h3>
|
|
||||||
</div>
|
|
||||||
{#await registry.fetchCollection(`${activeUser}/${activeCollection}`)}
|
{#await registry.fetchCollection(`${activeUser}/${activeCollection}`)}
|
||||||
<div>Loading...</div>
|
<div>Loading...</div>
|
||||||
{:then collection}
|
{:then collection}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import { browser } from "$app/environment";
|
import { browser } from "$app/environment";
|
||||||
import Monitor from "./Monitor.svelte";
|
import Monitor from "./Monitor.svelte";
|
||||||
import { humanizeNumber } from "$lib/helpers";
|
import { humanizeNumber } from "$lib/helpers";
|
||||||
|
import { Checkbox } from "@nodes/ui";
|
||||||
|
|
||||||
type PerformanceData = {
|
type PerformanceData = {
|
||||||
total: Record<string, number>;
|
total: Record<string, number>;
|
||||||
@ -10,44 +11,105 @@
|
|||||||
|
|
||||||
export let data: PerformanceData;
|
export let data: PerformanceData;
|
||||||
export let viewer: PerformanceData;
|
export let viewer: PerformanceData;
|
||||||
|
let lastRunOnly = true;
|
||||||
|
|
||||||
function getPerformanceData() {
|
function getTotalPerformance(onlyLast = false) {
|
||||||
return Object.entries(data.total)
|
if (onlyLast) {
|
||||||
.sort((a, b) => b[1] - a[1])
|
return (
|
||||||
.filter(([key]) => !key.startsWith("node/"));
|
data.runs.at(-1).runtime[0] + viewer.runs.at(-1)["create-geometries"][0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return data.total.runtime + viewer.total["create-geometries"];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNodePerformanceData() {
|
function count(input?: number | number[]) {
|
||||||
|
if (!input) return 0;
|
||||||
|
if (Array.isArray(input))
|
||||||
|
return input.reduce((acc, val) => acc + val, 0) / input.length;
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCacheRatio(onlyLast = false) {
|
||||||
|
let ratio = onlyLast
|
||||||
|
? count(data.runs.at(-1)?.["cache-hit"])
|
||||||
|
: count(data.total["cache-hit"]);
|
||||||
|
|
||||||
|
return `${Math.floor(ratio * 100)}%`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPerformanceData(onlyLast: boolean = false) {
|
||||||
|
if (onlyLast) {
|
||||||
|
return Object.entries(data.runs.at(-1))
|
||||||
|
.map(([key, value]) => [key, value[0]])
|
||||||
|
.filter(
|
||||||
|
([key]) =>
|
||||||
|
!key.startsWith("node/") &&
|
||||||
|
key !== "total" &&
|
||||||
|
!key.includes("cache"),
|
||||||
|
)
|
||||||
|
.sort((a, b) => b[1] - a[1]);
|
||||||
|
}
|
||||||
|
return Object.entries(data.total)
|
||||||
|
.sort((a, b) => b[1] - a[1])
|
||||||
|
.filter(
|
||||||
|
([key]) =>
|
||||||
|
!key.startsWith("node/") && key !== "total" && !key.includes("cache"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodePerformanceData(onlyLast: boolean = false) {
|
||||||
|
if (onlyLast) {
|
||||||
|
return Object.entries(data.runs.at(-1))
|
||||||
|
.map(([key, value]) => [key, value[0]])
|
||||||
|
.filter(([key]) => key.startsWith("node/"))
|
||||||
|
.sort((a, b) => b[1] - a[1]);
|
||||||
|
}
|
||||||
return Object.entries(data.total)
|
return Object.entries(data.total)
|
||||||
.filter(([key]) => key.startsWith("node/"))
|
.filter(([key]) => key.startsWith("node/"))
|
||||||
.sort((a, b) => b[1] - a[1]);
|
.sort((a, b) => b[1] - a[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getViewerPerformanceData() {
|
function getViewerPerformanceData(onlyLast: boolean = false) {
|
||||||
|
if (onlyLast) {
|
||||||
|
return Object.entries(viewer.runs.at(-1))
|
||||||
|
.map(([key, value]) => [key, value[0]])
|
||||||
|
.filter(([key]) => key !== "total-vertices" && key !== "total-faces")
|
||||||
|
.sort((a, b) => b[1] - a[1]);
|
||||||
|
}
|
||||||
return Object.entries(viewer.total)
|
return Object.entries(viewer.total)
|
||||||
.filter(([key]) => key !== "total-vertices" && key !== "total-faces")
|
.filter(([key]) => key !== "total-vertices" && key !== "total-faces")
|
||||||
.sort((a, b) => b[1] - a[1]);
|
.sort((a, b) => b[1] - a[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function constructPoints(key: keyof (typeof data.runs)[0]) {
|
function constructPoints(key: keyof (typeof data.runs)[0]) {
|
||||||
return data.runs
|
return data.runs.map((run, i) => {
|
||||||
.map((run, i) => {
|
|
||||||
return run[key][0];
|
return run[key][0];
|
||||||
})
|
});
|
||||||
.slice(-100);
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#key data}
|
{#key data}
|
||||||
{#if browser}
|
{#if browser}
|
||||||
<Monitor points={constructPoints("total")} />
|
<Monitor points={constructPoints("runtime")} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="px-4">
|
<div class="p-4">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<Checkbox id="show-total" bind:value={lastRunOnly} />
|
||||||
|
<label for="show-total">Show Average</label>
|
||||||
|
</div>
|
||||||
{#if data.runs.length !== 0}
|
{#if data.runs.length !== 0}
|
||||||
<h3>General</h3>
|
<h3>General</h3>
|
||||||
<table>
|
<table>
|
||||||
{#each getPerformanceData() as [key, value]}
|
<tr>
|
||||||
|
<td>
|
||||||
|
{Math.floor(getTotalPerformance(!lastRunOnly) * 100) / 100}<span
|
||||||
|
>ms</span
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td>total</td>
|
||||||
|
</tr>
|
||||||
|
{#each getPerformanceData(!lastRunOnly) as [key, value]}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{Math.floor(value * 100) / 100}<span>ms</span>
|
{Math.floor(value * 100) / 100}<span>ms</span>
|
||||||
@ -58,8 +120,18 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td> {getCacheRatio(!lastRunOnly)} </td>
|
||||||
|
<td>cache hit</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>{data.runs.length}</td>
|
||||||
|
<td>Samples</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<h3>Nodes</h3>
|
<h3>Nodes</h3>
|
||||||
{#each getNodePerformanceData() as [key, value]}
|
{#each getNodePerformanceData(!lastRunOnly) as [key, value]}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{Math.floor(value * 100) / 100}<span>ms</span>
|
{Math.floor(value * 100) / 100}<span>ms</span>
|
||||||
@ -80,7 +152,7 @@
|
|||||||
<td>{humanizeNumber(viewer.runs.at(-1)?.["total-faces"])}</td>
|
<td>{humanizeNumber(viewer.runs.at(-1)?.["total-faces"])}</td>
|
||||||
<td>Faces</td>
|
<td>Faces</td>
|
||||||
</tr>
|
</tr>
|
||||||
{#each getViewerPerformanceData() as [key, value]}
|
{#each getViewerPerformanceData(!lastRunOnly) as [key, value]}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{Math.floor(value * 100) / 100}<span>ms</span>
|
{Math.floor(value * 100) / 100}<span>ms</span>
|
||||||
|
@ -42,6 +42,7 @@ export function createPerformanceStore(): PerformanceStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
data.runs.push(currentRun);
|
data.runs.push(currentRun);
|
||||||
|
data.runs = data.runs.slice(-100);
|
||||||
currentRun = undefined;
|
currentRun = undefined;
|
||||||
if (set) set(data);
|
if (set) set(data);
|
||||||
}
|
}
|
||||||
|
@ -154,8 +154,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: if (result) {
|
$: if (result) {
|
||||||
perf?.startRun();
|
|
||||||
|
|
||||||
let a = performance.now();
|
let a = performance.now();
|
||||||
const inputs = parse_args(result);
|
const inputs = parse_args(result);
|
||||||
let b = performance.now();
|
let b = performance.now();
|
||||||
@ -194,8 +192,6 @@
|
|||||||
|
|
||||||
perf?.addPoint("total-vertices", totalVertices);
|
perf?.addPoint("total-vertices", totalVertices);
|
||||||
perf?.addPoint("total-faces", totalFaces);
|
perf?.addPoint("total-faces", totalFaces);
|
||||||
|
|
||||||
perf?.stopRun();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -213,15 +213,22 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
let cachedValue = this.cache?.get(inputHash);
|
let cachedValue = this.cache?.get(inputHash);
|
||||||
if (cachedValue !== undefined) {
|
if (cachedValue !== undefined) {
|
||||||
log.log(`Using cached value for ${node_type.id || node.id}`);
|
log.log(`Using cached value for ${node_type.id || node.id}`);
|
||||||
|
this.perf?.addPoint("cache-hit", 1);
|
||||||
results[node.id] = cachedValue as Int32Array;
|
results[node.id] = cachedValue as Int32Array;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
this.perf?.addPoint("cache-hit", 0);
|
||||||
|
|
||||||
log.group(`executing ${node_type.id || node.id}`);
|
log.group(`executing ${node_type.id || node.id}`);
|
||||||
log.log(`Inputs:`, inputs);
|
log.log(`Inputs:`, inputs);
|
||||||
a = performance.now();
|
a = performance.now();
|
||||||
results[node.id] = node_type.execute(encoded_inputs);
|
results[node.id] = node_type.execute(encoded_inputs);
|
||||||
b = performance.now();
|
b = performance.now();
|
||||||
|
|
||||||
|
if (this.cache) {
|
||||||
|
this.cache.set(inputHash, results[node.id]);
|
||||||
|
}
|
||||||
|
|
||||||
this.perf?.addPoint("node/" + node_type.id, b - a);
|
this.perf?.addPoint("node/" + node_type.id, b - a);
|
||||||
log.log("Result:", results[node.id]);
|
log.log("Result:", results[node.id]);
|
||||||
log.groupEnd();
|
log.groupEnd();
|
||||||
@ -237,7 +244,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
|
|||||||
// return the result of the parent of the output node
|
// return the result of the parent of the output node
|
||||||
const res = results[outputNode.id];
|
const res = results[outputNode.id];
|
||||||
|
|
||||||
this.perf?.addPoint("total", performance.now() - a0);
|
this.perf?.addPoint("runtime", performance.now() - a0);
|
||||||
|
|
||||||
this.perf?.stopRun();
|
this.perf?.stopRun();
|
||||||
|
|
||||||
|
@ -5,17 +5,27 @@
|
|||||||
export let id: string;
|
export let id: string;
|
||||||
export let icon: string = "";
|
export let icon: string = "";
|
||||||
export let title = "";
|
export let title = "";
|
||||||
|
export let classes = "";
|
||||||
|
export let hidden: boolean;
|
||||||
|
|
||||||
|
const setVisibility =
|
||||||
|
getContext<(id: string, visible: boolean) => void>("setVisibility");
|
||||||
|
|
||||||
|
$: if (typeof hidden === "boolean") {
|
||||||
|
setVisibility(id, !hidden);
|
||||||
|
}
|
||||||
|
|
||||||
const registerPanel =
|
const registerPanel =
|
||||||
getContext<(id: string, icon: string) => Readable<boolean>>(
|
getContext<
|
||||||
"registerPanel",
|
(id: string, icon: string, classes: string) => Readable<boolean>
|
||||||
);
|
>("registerPanel");
|
||||||
|
|
||||||
let visible = registerPanel(id, icon);
|
let visible = registerPanel(id, icon, classes);
|
||||||
|
console.log(id, $visible, hidden);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $visible}
|
{#if $visible}
|
||||||
<div class="wrapper">
|
<div class="wrapper" class:hidden>
|
||||||
{#if title}
|
{#if title}
|
||||||
<header>
|
<header>
|
||||||
<h3>{title}</h3>
|
<h3>{title}</h3>
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
{
|
{
|
||||||
icon: string;
|
icon: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
classes: string;
|
||||||
|
visible?: boolean;
|
||||||
}
|
}
|
||||||
> = {};
|
> = {};
|
||||||
|
|
||||||
@ -22,8 +24,13 @@
|
|||||||
)
|
)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
setContext("registerPanel", (id: string, icon: string) => {
|
setContext("setVisibility", (id: string, visible: boolean) => {
|
||||||
panels[id] = { id, icon };
|
panels[id].visible = visible;
|
||||||
|
panels = { ...panels };
|
||||||
|
});
|
||||||
|
|
||||||
|
setContext("registerPanel", (id: string, icon: string, classes: string) => {
|
||||||
|
panels[id] = { id, icon, classes };
|
||||||
return derived(activePanel, ($activePanel) => {
|
return derived(activePanel, ($activePanel) => {
|
||||||
return $activePanel === id;
|
return $activePanel === id;
|
||||||
});
|
});
|
||||||
@ -50,13 +57,15 @@
|
|||||||
<span class="absolute i-tabler-chevron-left w-6 h-6 block"></span>
|
<span class="absolute i-tabler-chevron-left w-6 h-6 block"></span>
|
||||||
</button>
|
</button>
|
||||||
{#each keys as panel (panels[panel].id)}
|
{#each keys as panel (panels[panel].id)}
|
||||||
|
{#if panels[panel].visible !== false}
|
||||||
<button
|
<button
|
||||||
class="tab"
|
class="tab {panels[panel].classes}"
|
||||||
class:active={panel === $activePanel}
|
class:active={panel === $activePanel}
|
||||||
on:click={() => setActivePanel(panel)}
|
on:click={() => setActivePanel(panel)}
|
||||||
>
|
>
|
||||||
<i class={`block w-6 h-6 ${panels[panel].icon}`} />
|
<span class={`block w-6 h-6 ${panels[panel].icon}`} />
|
||||||
</button>
|
</button>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -81,12 +90,6 @@
|
|||||||
min-width: 350px;
|
min-width: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
|
||||||
border-bottom: solid thin var(--outline);
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
background: var(--layer-1);
|
background: var(--layer-1);
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -103,35 +106,35 @@
|
|||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
background: none;
|
background: none;
|
||||||
color: var(--outline);
|
|
||||||
border: none;
|
border: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-bottom: solid thin var(--outline);
|
border-bottom: solid thin var(--outline);
|
||||||
border-left: solid thin var(--outline);
|
border-left: solid thin var(--outline);
|
||||||
|
background: var(--layer-0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs > button > span {
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs > button.active {
|
.tabs > button.active {
|
||||||
color: var(--layer-3);
|
|
||||||
background: var(--layer-1);
|
background: var(--layer-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.visible .tabs > button {
|
.tabs > button.active span {
|
||||||
border-left: none;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.visible .tabs {
|
.visible .tabs {
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
border-left: solid thin var(--outline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.visible > .tabs button:first-child {
|
.visible > .tabs button:first-child > span {
|
||||||
transform: scaleX(-1);
|
transform: scaleX(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.visible {
|
.visible {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
border-left: solid thin var(--outline);
|
|
||||||
background: var(--layer-0);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,6 +8,7 @@ export const AppSettings = localStore("node-settings", {
|
|||||||
wireframe: false,
|
wireframe: false,
|
||||||
showIndices: false,
|
showIndices: false,
|
||||||
showVertices: false,
|
showVertices: false,
|
||||||
|
showPerformancePanel: false,
|
||||||
centerCamera: true,
|
centerCamera: true,
|
||||||
showStemLines: false,
|
showStemLines: false,
|
||||||
amount: 5
|
amount: 5
|
||||||
@ -67,6 +68,11 @@ export const AppSettingTypes = {
|
|||||||
label: "Show Indices",
|
label: "Show Indices",
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
|
showPerformancePanel: {
|
||||||
|
type: "boolean",
|
||||||
|
label: "Show Performance Panel",
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
showVertices: {
|
showVertices: {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
label: "Show Vertices",
|
label: "Show Vertices",
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { MemoryRuntimeExecutor } from "./runtime-executor";
|
import { MemoryRuntimeExecutor, MemoryRuntimeCache } from "./runtime-executor";
|
||||||
import { RemoteNodeRegistry } from "./node-registry-client";
|
import { RemoteNodeRegistry } from "./node-registry-client";
|
||||||
import type { Graph } from "@nodes/types";
|
import type { Graph } from "@nodes/types";
|
||||||
import { createPerformanceStore } from "./performance/store";
|
import { createPerformanceStore } from "./performance/store";
|
||||||
|
|
||||||
|
const cache = new MemoryRuntimeCache();
|
||||||
const nodeRegistry = new RemoteNodeRegistry("");
|
const nodeRegistry = new RemoteNodeRegistry("");
|
||||||
const executor = new MemoryRuntimeExecutor(nodeRegistry);
|
const executor = new MemoryRuntimeExecutor(nodeRegistry, cache);
|
||||||
|
|
||||||
const performanceStore = createPerformanceStore();
|
const performanceStore = createPerformanceStore();
|
||||||
executor.perf = performanceStore;
|
executor.perf = performanceStore;
|
||||||
|
@ -74,13 +74,24 @@
|
|||||||
}
|
}
|
||||||
isWorking = true;
|
isWorking = true;
|
||||||
try {
|
try {
|
||||||
|
let a = performance.now();
|
||||||
res = await workerRuntime.execute(_graph, _settings);
|
res = await workerRuntime.execute(_graph, _settings);
|
||||||
performanceData = await workerRuntime.getPerformanceData();
|
let b = performance.now();
|
||||||
|
let perfData = await workerRuntime.getPerformanceData();
|
||||||
|
let lastRun = perfData.runs?.at(-1);
|
||||||
|
if (lastRun) {
|
||||||
|
perfData.total["worker-transfer"] = b - a - lastRun.runtime[0];
|
||||||
|
lastRun["worker-transfer"] = [b - a - lastRun.runtime[0]];
|
||||||
|
}
|
||||||
|
performanceData = perfData;
|
||||||
isWorking = false;
|
isWorking = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("errors", error);
|
console.log("errors", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewerPerformance.stopRun();
|
||||||
|
viewerPerformance.startRun();
|
||||||
|
|
||||||
if (unfinished) {
|
if (unfinished) {
|
||||||
let d = unfinished;
|
let d = unfinished;
|
||||||
unfinished = undefined;
|
unfinished = undefined;
|
||||||
@ -137,21 +148,6 @@
|
|||||||
settings={AppSettingTypes}
|
settings={AppSettingTypes}
|
||||||
/>
|
/>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Panel id="node-store" title="Node Store" icon="i-tabler-database">
|
|
||||||
<NodeStore registry={nodeRegistry} />
|
|
||||||
</Panel>
|
|
||||||
<Panel
|
|
||||||
id="performance"
|
|
||||||
title="Performance"
|
|
||||||
icon="i-tabler-brand-speedtest"
|
|
||||||
>
|
|
||||||
{#if performanceData}
|
|
||||||
<PerformanceViewer
|
|
||||||
data={performanceData}
|
|
||||||
viewer={$viewerPerformance}
|
|
||||||
/>
|
|
||||||
{/if}
|
|
||||||
</Panel>
|
|
||||||
<Panel
|
<Panel
|
||||||
id="shortcuts"
|
id="shortcuts"
|
||||||
title="Keyboard Shortcuts"
|
title="Keyboard Shortcuts"
|
||||||
@ -161,9 +157,32 @@
|
|||||||
<Keymap {keymap} />
|
<Keymap {keymap} />
|
||||||
{/if}
|
{/if}
|
||||||
</Panel>
|
</Panel>
|
||||||
|
<Panel
|
||||||
|
id="node-store"
|
||||||
|
classes="text-green-400"
|
||||||
|
title="Node Store"
|
||||||
|
icon="i-tabler-database"
|
||||||
|
>
|
||||||
|
<NodeStore registry={nodeRegistry} />
|
||||||
|
</Panel>
|
||||||
|
<Panel
|
||||||
|
id="performance"
|
||||||
|
title="Performance"
|
||||||
|
classes="text-red-400"
|
||||||
|
hidden={!$AppSettings.showPerformancePanel}
|
||||||
|
icon="i-tabler-brand-speedtest"
|
||||||
|
>
|
||||||
|
{#if performanceData}
|
||||||
|
<PerformanceViewer
|
||||||
|
data={performanceData}
|
||||||
|
viewer={$viewerPerformance}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</Panel>
|
||||||
<Panel
|
<Panel
|
||||||
id="graph-settings"
|
id="graph-settings"
|
||||||
title="Graph Settings"
|
title="Graph Settings"
|
||||||
|
classes="text-blue-400"
|
||||||
icon="i-tabler-brand-git"
|
icon="i-tabler-brand-git"
|
||||||
>
|
>
|
||||||
{#if Object.keys(graphSettingTypes).length > 0}
|
{#if Object.keys(graphSettingTypes).length > 0}
|
||||||
@ -173,6 +192,7 @@
|
|||||||
<Panel
|
<Panel
|
||||||
id="active-node"
|
id="active-node"
|
||||||
title="Node Settings"
|
title="Node Settings"
|
||||||
|
classes="text-blue-400"
|
||||||
icon="i-tabler-adjustments"
|
icon="i-tabler-adjustments"
|
||||||
>
|
>
|
||||||
<ActiveNodeSettings {manager} node={activeNode} />
|
<ActiveNodeSettings {manager} node={activeNode} />
|
||||||
@ -183,6 +203,8 @@
|
|||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span class="font-red" />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
header {
|
header {
|
||||||
/* border-bottom: solid thin var(--outline); */
|
/* border-bottom: solid thin var(--outline); */
|
||||||
|
Loading…
Reference in New Issue
Block a user