frontend: expand cosmos runtime tuning and diagnostics
This commit is contained in:
62
.env.example
62
.env.example
@@ -21,8 +21,18 @@ COMBINE_OUTPUT_LOCATION=/data/vkg_full.ttl
|
|||||||
COMBINE_FORCE=true
|
COMBINE_FORCE=true
|
||||||
|
|
||||||
# AnzoGraph / SPARQL endpoint settings
|
# AnzoGraph / SPARQL endpoint settings
|
||||||
|
# Use `local` for the Docker Compose AnzoGraph container, or `external` for the
|
||||||
|
# remote endpoint below using a runtime-generated bearer token.
|
||||||
|
SPARQL_SOURCE_MODE=local
|
||||||
SPARQL_HOST=http://anzograph:8080
|
SPARQL_HOST=http://anzograph:8080
|
||||||
# SPARQL_ENDPOINT=http://anzograph:8080/sparql
|
# SPARQL_ENDPOINT=http://anzograph:8080/sparql
|
||||||
|
EXTERNAL_SPARQL_ENDPOINT=https://anzograph.k8s.inf.ufrgs.br/sparql
|
||||||
|
KEYCLOAK_TOKEN_ENDPOINT=https://keycloak.k8s.inf.ufrgs.br/realms/INF/protocol/openid-connect/token
|
||||||
|
KEYCLOAK_CLIENT_ID=anzograph
|
||||||
|
KEYCLOAK_USERNAME=
|
||||||
|
KEYCLOAK_PASSWORD=
|
||||||
|
KEYCLOAK_SCOPE=openid
|
||||||
|
ACCESS_TOKEN=
|
||||||
SPARQL_USER=admin
|
SPARQL_USER=admin
|
||||||
SPARQL_PASS=Passw0rd1
|
SPARQL_PASS=Passw0rd1
|
||||||
|
|
||||||
@@ -32,7 +42,6 @@ SPARQL_DATA_FILE=file:///opt/shared-files/o3po.ttl # Currently not used.
|
|||||||
|
|
||||||
# Startup behavior for AnzoGraph mode
|
# Startup behavior for AnzoGraph mode
|
||||||
SPARQL_LOAD_ON_START=false
|
SPARQL_LOAD_ON_START=false
|
||||||
SPARQL_CLEAR_ON_START=false
|
|
||||||
SPARQL_READY_TIMEOUT_S=10
|
SPARQL_READY_TIMEOUT_S=10
|
||||||
|
|
||||||
# Dev UX
|
# Dev UX
|
||||||
@@ -40,18 +49,69 @@ CORS_ORIGINS=http://localhost:5173
|
|||||||
VITE_BACKEND_URL=http://backend:8000
|
VITE_BACKEND_URL=http://backend:8000
|
||||||
|
|
||||||
# Frontend right-pane cosmos.gl layout
|
# Frontend right-pane cosmos.gl layout
|
||||||
|
# Colors accept CSS strings or RGBA tuples like [53,214,255,255].
|
||||||
|
# Ranges accept comma-separated values like 50,150.
|
||||||
VITE_COSMOS_ENABLE_SIMULATION=true
|
VITE_COSMOS_ENABLE_SIMULATION=true
|
||||||
VITE_COSMOS_DEBUG_LAYOUT=false
|
VITE_COSMOS_DEBUG_LAYOUT=false
|
||||||
|
VITE_COSMOS_BACKGROUND_COLOR="#05070a"
|
||||||
VITE_COSMOS_SPACE_SIZE=4096
|
VITE_COSMOS_SPACE_SIZE=4096
|
||||||
|
VITE_COSMOS_POINT_DEFAULT_COLOR="#b3b3b3"
|
||||||
|
VITE_COSMOS_POINT_GREYOUT_COLOR=
|
||||||
|
VITE_COSMOS_POINT_GREYOUT_OPACITY=
|
||||||
|
VITE_COSMOS_POINT_DEFAULT_SIZE=4
|
||||||
|
VITE_COSMOS_POINT_OPACITY=1
|
||||||
|
VITE_COSMOS_POINT_SIZE_SCALE=1
|
||||||
|
VITE_COSMOS_HOVERED_POINT_CURSOR=pointer
|
||||||
|
VITE_COSMOS_HOVERED_LINK_CURSOR=pointer
|
||||||
|
VITE_COSMOS_RENDER_HOVERED_POINT_RING=true
|
||||||
|
VITE_COSMOS_HOVERED_POINT_RING_COLOR="#35d6ff"
|
||||||
|
VITE_COSMOS_FOCUSED_POINT_RING_COLOR=white
|
||||||
|
VITE_COSMOS_RENDER_LINKS=true
|
||||||
|
VITE_COSMOS_LINK_DEFAULT_COLOR="#666666"
|
||||||
|
VITE_COSMOS_LINK_OPACITY=1
|
||||||
|
VITE_COSMOS_LINK_GREYOUT_OPACITY=0.1
|
||||||
|
VITE_COSMOS_LINK_DEFAULT_WIDTH=1
|
||||||
|
VITE_COSMOS_HOVERED_LINK_COLOR="#ffd166"
|
||||||
|
VITE_COSMOS_HOVERED_LINK_WIDTH_INCREASE=2.5
|
||||||
|
VITE_COSMOS_LINK_WIDTH_SCALE=1
|
||||||
|
VITE_COSMOS_SCALE_LINKS_ON_ZOOM=false
|
||||||
VITE_COSMOS_CURVED_LINKS=true
|
VITE_COSMOS_CURVED_LINKS=true
|
||||||
|
VITE_COSMOS_CURVED_LINK_SEGMENTS=19
|
||||||
|
VITE_COSMOS_CURVED_LINK_WEIGHT=0.8
|
||||||
|
VITE_COSMOS_CURVED_LINK_CONTROL_POINT_DISTANCE=0.5
|
||||||
|
VITE_COSMOS_LINK_DEFAULT_ARROWS=false
|
||||||
|
VITE_COSMOS_LINK_ARROWS_SIZE_SCALE=1
|
||||||
|
VITE_COSMOS_LINK_VISIBILITY_DISTANCE_RANGE=50,150
|
||||||
|
VITE_COSMOS_LINK_VISIBILITY_MIN_TRANSPARENCY=0.25
|
||||||
|
VITE_COSMOS_USE_CLASSIC_QUADTREE=false
|
||||||
VITE_COSMOS_FIT_VIEW_PADDING=0.12
|
VITE_COSMOS_FIT_VIEW_PADDING=0.12
|
||||||
|
VITE_COSMOS_FIT_VIEW_ON_INIT=false
|
||||||
|
VITE_COSMOS_FIT_VIEW_DELAY=250
|
||||||
|
VITE_COSMOS_FIT_VIEW_DURATION=250
|
||||||
VITE_COSMOS_SIMULATION_DECAY=5000
|
VITE_COSMOS_SIMULATION_DECAY=5000
|
||||||
VITE_COSMOS_SIMULATION_GRAVITY=0
|
VITE_COSMOS_SIMULATION_GRAVITY=0
|
||||||
VITE_COSMOS_SIMULATION_CENTER=0.05
|
VITE_COSMOS_SIMULATION_CENTER=0.05
|
||||||
VITE_COSMOS_SIMULATION_REPULSION=0.5
|
VITE_COSMOS_SIMULATION_REPULSION=0.5
|
||||||
|
VITE_COSMOS_SIMULATION_REPULSION_THETA=1.15
|
||||||
|
VITE_COSMOS_SIMULATION_REPULSION_QUADTREE_LEVELS=12
|
||||||
VITE_COSMOS_SIMULATION_LINK_SPRING=1
|
VITE_COSMOS_SIMULATION_LINK_SPRING=1
|
||||||
VITE_COSMOS_SIMULATION_LINK_DISTANCE=10
|
VITE_COSMOS_SIMULATION_LINK_DISTANCE=10
|
||||||
|
VITE_COSMOS_SIMULATION_LINK_DISTANCE_RANDOM_VARIATION_RANGE=1,1.2
|
||||||
|
VITE_COSMOS_SIMULATION_REPULSION_FROM_MOUSE=2
|
||||||
|
VITE_COSMOS_ENABLE_RIGHT_CLICK_REPULSION=false
|
||||||
VITE_COSMOS_SIMULATION_FRICTION=0.1
|
VITE_COSMOS_SIMULATION_FRICTION=0.1
|
||||||
|
VITE_COSMOS_SIMULATION_CLUSTER=0.1
|
||||||
|
VITE_COSMOS_SHOW_FPS_MONITOR=false
|
||||||
|
VITE_COSMOS_PIXEL_RATIO=2
|
||||||
|
VITE_COSMOS_SCALE_POINTS_ON_ZOOM=false
|
||||||
|
VITE_COSMOS_INITIAL_ZOOM_LEVEL=
|
||||||
|
VITE_COSMOS_ENABLE_ZOOM=true
|
||||||
|
VITE_COSMOS_ENABLE_SIMULATION_DURING_ZOOM=false
|
||||||
|
VITE_COSMOS_ENABLE_DRAG=true
|
||||||
|
VITE_COSMOS_RANDOM_SEED=
|
||||||
|
VITE_COSMOS_POINT_SAMPLING_DISTANCE=150
|
||||||
|
VITE_COSMOS_RESCALE_POSITIONS=false
|
||||||
|
VITE_COSMOS_ATTRIBUTION=
|
||||||
|
|
||||||
# Debugging
|
# Debugging
|
||||||
LOG_SNAPSHOT_TIMINGS=false
|
LOG_SNAPSHOT_TIMINGS=false
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { memo, useEffect, useMemo, useRef, useState } from "react";
|
import { memo, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { Graph, type GraphConfig } from "@cosmos.gl/graph";
|
import { Graph, type GraphConfig } from "@cosmos.gl/graph";
|
||||||
import { cosmosRuntimeConfig } from "./cosmos_config";
|
import { cosmosBackgroundCss, cosmosRuntimeConfig } from "./cosmos_config";
|
||||||
import {
|
import {
|
||||||
computeLayoutMetrics,
|
computeLayoutMetrics,
|
||||||
type GraphLayoutMetrics,
|
type GraphLayoutMetrics,
|
||||||
@@ -194,28 +194,68 @@ export const TripleGraphView = memo(function TripleGraphView({ model }: TripleGr
|
|||||||
};
|
};
|
||||||
|
|
||||||
const config: GraphConfig = {
|
const config: GraphConfig = {
|
||||||
backgroundColor: "#05070a",
|
backgroundColor: cosmosRuntimeConfig.backgroundColor,
|
||||||
spaceSize: cosmosRuntimeConfig.spaceSize,
|
spaceSize: cosmosRuntimeConfig.spaceSize,
|
||||||
enableSimulation: cosmosRuntimeConfig.enableSimulation,
|
enableSimulation: cosmosRuntimeConfig.enableSimulation,
|
||||||
enableDrag: true,
|
pointDefaultColor: cosmosRuntimeConfig.pointDefaultColor,
|
||||||
enableZoom: true,
|
pointGreyoutColor: cosmosRuntimeConfig.pointGreyoutColor,
|
||||||
fitViewOnInit: false,
|
pointGreyoutOpacity: cosmosRuntimeConfig.pointGreyoutOpacity,
|
||||||
|
pointDefaultSize: cosmosRuntimeConfig.pointDefaultSize,
|
||||||
|
pointOpacity: cosmosRuntimeConfig.pointOpacity,
|
||||||
|
pointSizeScale: cosmosRuntimeConfig.pointSizeScale,
|
||||||
|
hoveredPointCursor: cosmosRuntimeConfig.hoveredPointCursor,
|
||||||
|
hoveredLinkCursor: cosmosRuntimeConfig.hoveredLinkCursor,
|
||||||
|
renderHoveredPointRing: cosmosRuntimeConfig.renderHoveredPointRing,
|
||||||
|
hoveredPointRingColor: cosmosRuntimeConfig.hoveredPointRingColor,
|
||||||
|
focusedPointRingColor: cosmosRuntimeConfig.focusedPointRingColor,
|
||||||
|
renderLinks: cosmosRuntimeConfig.renderLinks,
|
||||||
|
linkDefaultColor: cosmosRuntimeConfig.linkDefaultColor,
|
||||||
|
linkOpacity: cosmosRuntimeConfig.linkOpacity,
|
||||||
|
linkGreyoutOpacity: cosmosRuntimeConfig.linkGreyoutOpacity,
|
||||||
|
linkDefaultWidth: cosmosRuntimeConfig.linkDefaultWidth,
|
||||||
|
hoveredLinkColor: cosmosRuntimeConfig.hoveredLinkColor,
|
||||||
|
hoveredLinkWidthIncrease: cosmosRuntimeConfig.hoveredLinkWidthIncrease,
|
||||||
|
linkWidthScale: cosmosRuntimeConfig.linkWidthScale,
|
||||||
|
scaleLinksOnZoom: cosmosRuntimeConfig.scaleLinksOnZoom,
|
||||||
|
enableDrag: cosmosRuntimeConfig.enableDrag,
|
||||||
|
enableZoom: cosmosRuntimeConfig.enableZoom,
|
||||||
|
enableSimulationDuringZoom: cosmosRuntimeConfig.enableSimulationDuringZoom,
|
||||||
|
fitViewOnInit: cosmosRuntimeConfig.fitViewOnInit,
|
||||||
|
fitViewDelay: cosmosRuntimeConfig.fitViewDelay,
|
||||||
fitViewPadding: cosmosRuntimeConfig.fitViewPadding,
|
fitViewPadding: cosmosRuntimeConfig.fitViewPadding,
|
||||||
rescalePositions: false,
|
fitViewDuration: cosmosRuntimeConfig.fitViewDuration,
|
||||||
|
initialZoomLevel: cosmosRuntimeConfig.initialZoomLevel,
|
||||||
|
pointSamplingDistance: cosmosRuntimeConfig.pointSamplingDistance,
|
||||||
|
rescalePositions: cosmosRuntimeConfig.rescalePositions,
|
||||||
curvedLinks: cosmosRuntimeConfig.curvedLinks,
|
curvedLinks: cosmosRuntimeConfig.curvedLinks,
|
||||||
|
curvedLinkSegments: cosmosRuntimeConfig.curvedLinkSegments,
|
||||||
|
curvedLinkWeight: cosmosRuntimeConfig.curvedLinkWeight,
|
||||||
|
curvedLinkControlPointDistance: cosmosRuntimeConfig.curvedLinkControlPointDistance,
|
||||||
|
linkDefaultArrows: cosmosRuntimeConfig.linkDefaultArrows,
|
||||||
|
linkArrowsSizeScale: cosmosRuntimeConfig.linkArrowsSizeScale,
|
||||||
|
linkVisibilityDistanceRange: cosmosRuntimeConfig.linkVisibilityDistanceRange,
|
||||||
|
linkVisibilityMinTransparency: cosmosRuntimeConfig.linkVisibilityMinTransparency,
|
||||||
|
useClassicQuadtree: cosmosRuntimeConfig.useClassicQuadtree,
|
||||||
simulationDecay: cosmosRuntimeConfig.simulationDecay,
|
simulationDecay: cosmosRuntimeConfig.simulationDecay,
|
||||||
simulationGravity: cosmosRuntimeConfig.simulationGravity,
|
simulationGravity: cosmosRuntimeConfig.simulationGravity,
|
||||||
simulationCenter: cosmosRuntimeConfig.simulationCenter,
|
simulationCenter: cosmosRuntimeConfig.simulationCenter,
|
||||||
simulationRepulsion: cosmosRuntimeConfig.simulationRepulsion,
|
simulationRepulsion: cosmosRuntimeConfig.simulationRepulsion,
|
||||||
|
simulationRepulsionTheta: cosmosRuntimeConfig.simulationRepulsionTheta,
|
||||||
|
simulationRepulsionQuadtreeLevels:
|
||||||
|
cosmosRuntimeConfig.simulationRepulsionQuadtreeLevels,
|
||||||
simulationLinkSpring: cosmosRuntimeConfig.simulationLinkSpring,
|
simulationLinkSpring: cosmosRuntimeConfig.simulationLinkSpring,
|
||||||
simulationLinkDistance: cosmosRuntimeConfig.simulationLinkDistance,
|
simulationLinkDistance: cosmosRuntimeConfig.simulationLinkDistance,
|
||||||
|
simulationLinkDistRandomVariationRange:
|
||||||
|
cosmosRuntimeConfig.simulationLinkDistRandomVariationRange,
|
||||||
|
simulationRepulsionFromMouse: cosmosRuntimeConfig.simulationRepulsionFromMouse,
|
||||||
|
enableRightClickRepulsion: cosmosRuntimeConfig.enableRightClickRepulsion,
|
||||||
simulationFriction: cosmosRuntimeConfig.simulationFriction,
|
simulationFriction: cosmosRuntimeConfig.simulationFriction,
|
||||||
renderHoveredPointRing: true,
|
simulationCluster: cosmosRuntimeConfig.simulationCluster,
|
||||||
hoveredPointRingColor: "#35d6ff",
|
randomSeed: cosmosRuntimeConfig.randomSeed,
|
||||||
hoveredPointCursor: "pointer",
|
showFPSMonitor: cosmosRuntimeConfig.showFPSMonitor,
|
||||||
hoveredLinkCursor: "pointer",
|
pixelRatio: cosmosRuntimeConfig.pixelRatio,
|
||||||
hoveredLinkColor: "#ffd166",
|
scalePointsOnZoom: cosmosRuntimeConfig.scalePointsOnZoom,
|
||||||
hoveredLinkWidthIncrease: 2.5,
|
attribution: cosmosRuntimeConfig.attribution,
|
||||||
onSimulationStart: () => {
|
onSimulationStart: () => {
|
||||||
reportLayout("simulation-start", "running", 1);
|
reportLayout("simulation-start", "running", 1);
|
||||||
},
|
},
|
||||||
@@ -320,7 +360,14 @@ export const TripleGraphView = memo(function TripleGraphView({ model }: TripleGr
|
|||||||
}, [activeDetail]);
|
}, [activeDetail]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ position: "relative", flex: 1, minHeight: 0, background: "#05070a" }}>
|
<div
|
||||||
|
style={{
|
||||||
|
position: "relative",
|
||||||
|
flex: 1,
|
||||||
|
minHeight: 0,
|
||||||
|
background: cosmosBackgroundCss,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}
|
style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}
|
||||||
@@ -468,7 +515,18 @@ function applyGraphModel(graph: Graph, model: TripleGraphModel): void {
|
|||||||
graph.setLinkWidths(model.linkWidths);
|
graph.setLinkWidths(model.linkWidths);
|
||||||
graph.render(0);
|
graph.render(0);
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
graph.fitViewByPointPositions(Array.from(model.pointPositions), 0, cosmosRuntimeConfig.fitViewPadding);
|
if (typeof cosmosRuntimeConfig.initialZoomLevel === "number") {
|
||||||
|
graph.setZoomLevel(
|
||||||
|
cosmosRuntimeConfig.initialZoomLevel,
|
||||||
|
cosmosRuntimeConfig.fitViewDuration,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
graph.fitViewByPointPositions(
|
||||||
|
Array.from(model.pointPositions),
|
||||||
|
cosmosRuntimeConfig.fitViewDuration,
|
||||||
|
cosmosRuntimeConfig.fitViewPadding,
|
||||||
|
);
|
||||||
|
}
|
||||||
if (cosmosRuntimeConfig.enableSimulation) {
|
if (cosmosRuntimeConfig.enableSimulation) {
|
||||||
graph.start(1);
|
graph.start(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
type CosmosColor = string | [number, number, number, number];
|
||||||
|
|
||||||
function parseBoolean(value: string | undefined, fallback: boolean): boolean {
|
function parseBoolean(value: string | undefined, fallback: boolean): boolean {
|
||||||
if (value === undefined) return fallback;
|
if (value === undefined) return fallback;
|
||||||
const normalized = value.trim().toLowerCase();
|
const normalized = value.trim().toLowerCase();
|
||||||
@@ -12,17 +14,167 @@ function parseNumber(value: string | undefined, fallback: number): number {
|
|||||||
return Number.isFinite(parsed) ? parsed : fallback;
|
return Number.isFinite(parsed) ? parsed : fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseOptionalNumber(value: string | undefined): number | undefined {
|
||||||
|
if (value === undefined) return undefined;
|
||||||
|
const trimmed = value.trim();
|
||||||
|
if (trimmed.length === 0) return undefined;
|
||||||
|
const parsed = Number(trimmed);
|
||||||
|
return Number.isFinite(parsed) ? parsed : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOptionalString(value: string | undefined): string | undefined {
|
||||||
|
if (value === undefined) return undefined;
|
||||||
|
const trimmed = value.trim();
|
||||||
|
return trimmed.length > 0 ? trimmed : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseNumberList(value: string | undefined, fallback: number[]): number[] {
|
||||||
|
return parseOptionalNumberList(value) ?? fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOptionalNumberList(value: string | undefined): number[] | undefined {
|
||||||
|
const raw = parseOptionalString(value);
|
||||||
|
if (!raw) return undefined;
|
||||||
|
const normalized = raw.startsWith("[") && raw.endsWith("]") ? raw.slice(1, -1) : raw;
|
||||||
|
const parts = normalized
|
||||||
|
.split(",")
|
||||||
|
.map((entry) => entry.trim())
|
||||||
|
.filter((entry) => entry.length > 0);
|
||||||
|
if (parts.length === 0) return undefined;
|
||||||
|
const parsed = parts.map((entry) => Number(entry));
|
||||||
|
return parsed.every((entry) => Number.isFinite(entry)) ? parsed : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseColor(value: string | undefined, fallback: CosmosColor): CosmosColor {
|
||||||
|
return parseOptionalColor(value) ?? fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOptionalColor(value: string | undefined): CosmosColor | undefined {
|
||||||
|
const raw = parseOptionalString(value);
|
||||||
|
if (!raw) return undefined;
|
||||||
|
const rgba = parseOptionalNumberList(raw);
|
||||||
|
if (rgba && rgba.length === 4) {
|
||||||
|
return [rgba[0], rgba[1], rgba[2], rgba[3]];
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOptionalSeed(value: string | undefined): number | string | undefined {
|
||||||
|
const raw = parseOptionalString(value);
|
||||||
|
if (!raw) return undefined;
|
||||||
|
const numeric = Number(raw);
|
||||||
|
return Number.isFinite(numeric) ? numeric : raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toCssColor(color: CosmosColor): string {
|
||||||
|
if (typeof color === "string") return color;
|
||||||
|
return `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3] / 255})`;
|
||||||
|
}
|
||||||
|
|
||||||
export const cosmosRuntimeConfig = {
|
export const cosmosRuntimeConfig = {
|
||||||
enableSimulation: parseBoolean(import.meta.env.VITE_COSMOS_ENABLE_SIMULATION, true),
|
enableSimulation: parseBoolean(import.meta.env.VITE_COSMOS_ENABLE_SIMULATION, true),
|
||||||
debugLayout: parseBoolean(import.meta.env.VITE_COSMOS_DEBUG_LAYOUT, false),
|
debugLayout: parseBoolean(import.meta.env.VITE_COSMOS_DEBUG_LAYOUT, false),
|
||||||
|
backgroundColor: parseColor(import.meta.env.VITE_COSMOS_BACKGROUND_COLOR, "#05070a"),
|
||||||
spaceSize: parseNumber(import.meta.env.VITE_COSMOS_SPACE_SIZE, 4096),
|
spaceSize: parseNumber(import.meta.env.VITE_COSMOS_SPACE_SIZE, 4096),
|
||||||
|
pointDefaultColor: parseOptionalColor(import.meta.env.VITE_COSMOS_POINT_DEFAULT_COLOR),
|
||||||
|
pointGreyoutColor: parseOptionalColor(import.meta.env.VITE_COSMOS_POINT_GREYOUT_COLOR),
|
||||||
|
pointGreyoutOpacity: parseOptionalNumber(import.meta.env.VITE_COSMOS_POINT_GREYOUT_OPACITY),
|
||||||
|
pointDefaultSize: parseNumber(import.meta.env.VITE_COSMOS_POINT_DEFAULT_SIZE, 4),
|
||||||
|
pointOpacity: parseNumber(import.meta.env.VITE_COSMOS_POINT_OPACITY, 1),
|
||||||
|
pointSizeScale: parseNumber(import.meta.env.VITE_COSMOS_POINT_SIZE_SCALE, 1),
|
||||||
|
hoveredPointCursor: parseOptionalString(import.meta.env.VITE_COSMOS_HOVERED_POINT_CURSOR) ?? "pointer",
|
||||||
|
hoveredLinkCursor: parseOptionalString(import.meta.env.VITE_COSMOS_HOVERED_LINK_CURSOR) ?? "pointer",
|
||||||
|
renderHoveredPointRing: parseBoolean(
|
||||||
|
import.meta.env.VITE_COSMOS_RENDER_HOVERED_POINT_RING,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
hoveredPointRingColor: parseColor(
|
||||||
|
import.meta.env.VITE_COSMOS_HOVERED_POINT_RING_COLOR,
|
||||||
|
"#35d6ff",
|
||||||
|
),
|
||||||
|
focusedPointRingColor: parseColor(
|
||||||
|
import.meta.env.VITE_COSMOS_FOCUSED_POINT_RING_COLOR,
|
||||||
|
"white",
|
||||||
|
),
|
||||||
|
renderLinks: parseBoolean(import.meta.env.VITE_COSMOS_RENDER_LINKS, true),
|
||||||
|
linkDefaultColor: parseOptionalColor(import.meta.env.VITE_COSMOS_LINK_DEFAULT_COLOR),
|
||||||
|
linkOpacity: parseNumber(import.meta.env.VITE_COSMOS_LINK_OPACITY, 1),
|
||||||
|
linkGreyoutOpacity: parseNumber(import.meta.env.VITE_COSMOS_LINK_GREYOUT_OPACITY, 0.1),
|
||||||
|
linkDefaultWidth: parseNumber(import.meta.env.VITE_COSMOS_LINK_DEFAULT_WIDTH, 1),
|
||||||
|
hoveredLinkColor: parseColor(import.meta.env.VITE_COSMOS_HOVERED_LINK_COLOR, "#ffd166"),
|
||||||
|
hoveredLinkWidthIncrease: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_HOVERED_LINK_WIDTH_INCREASE,
|
||||||
|
2.5,
|
||||||
|
),
|
||||||
|
linkWidthScale: parseNumber(import.meta.env.VITE_COSMOS_LINK_WIDTH_SCALE, 1),
|
||||||
|
scaleLinksOnZoom: parseBoolean(import.meta.env.VITE_COSMOS_SCALE_LINKS_ON_ZOOM, false),
|
||||||
curvedLinks: parseBoolean(import.meta.env.VITE_COSMOS_CURVED_LINKS, true),
|
curvedLinks: parseBoolean(import.meta.env.VITE_COSMOS_CURVED_LINKS, true),
|
||||||
fitViewPadding: parseNumber(import.meta.env.VITE_COSMOS_FIT_VIEW_PADDING, 0.12),
|
curvedLinkSegments: parseNumber(import.meta.env.VITE_COSMOS_CURVED_LINK_SEGMENTS, 19),
|
||||||
|
curvedLinkWeight: parseNumber(import.meta.env.VITE_COSMOS_CURVED_LINK_WEIGHT, 0.8),
|
||||||
|
curvedLinkControlPointDistance: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_CURVED_LINK_CONTROL_POINT_DISTANCE,
|
||||||
|
0.5,
|
||||||
|
),
|
||||||
|
linkDefaultArrows: parseBoolean(import.meta.env.VITE_COSMOS_LINK_DEFAULT_ARROWS, false),
|
||||||
|
linkArrowsSizeScale: parseNumber(import.meta.env.VITE_COSMOS_LINK_ARROWS_SIZE_SCALE, 1),
|
||||||
|
linkVisibilityDistanceRange: parseNumberList(
|
||||||
|
import.meta.env.VITE_COSMOS_LINK_VISIBILITY_DISTANCE_RANGE,
|
||||||
|
[50, 150],
|
||||||
|
),
|
||||||
|
linkVisibilityMinTransparency: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_LINK_VISIBILITY_MIN_TRANSPARENCY,
|
||||||
|
0.25,
|
||||||
|
),
|
||||||
|
useClassicQuadtree: parseBoolean(import.meta.env.VITE_COSMOS_USE_CLASSIC_QUADTREE, false),
|
||||||
simulationDecay: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_DECAY, 5000),
|
simulationDecay: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_DECAY, 5000),
|
||||||
simulationGravity: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_GRAVITY, 0),
|
simulationGravity: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_GRAVITY, 0),
|
||||||
simulationCenter: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_CENTER, 0.05),
|
simulationCenter: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_CENTER, 0.05),
|
||||||
simulationRepulsion: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_REPULSION, 0.5),
|
simulationRepulsion: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_REPULSION, 0.5),
|
||||||
|
simulationRepulsionTheta: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_SIMULATION_REPULSION_THETA,
|
||||||
|
1.15,
|
||||||
|
),
|
||||||
|
simulationRepulsionQuadtreeLevels: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_SIMULATION_REPULSION_QUADTREE_LEVELS,
|
||||||
|
12,
|
||||||
|
),
|
||||||
simulationLinkSpring: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_LINK_SPRING, 1),
|
simulationLinkSpring: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_LINK_SPRING, 1),
|
||||||
simulationLinkDistance: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_LINK_DISTANCE, 10),
|
simulationLinkDistance: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_LINK_DISTANCE, 10),
|
||||||
|
simulationLinkDistRandomVariationRange: parseNumberList(
|
||||||
|
import.meta.env.VITE_COSMOS_SIMULATION_LINK_DISTANCE_RANDOM_VARIATION_RANGE,
|
||||||
|
[1, 1.2],
|
||||||
|
),
|
||||||
|
simulationRepulsionFromMouse: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_SIMULATION_REPULSION_FROM_MOUSE,
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
enableRightClickRepulsion: parseBoolean(
|
||||||
|
import.meta.env.VITE_COSMOS_ENABLE_RIGHT_CLICK_REPULSION,
|
||||||
|
false,
|
||||||
|
),
|
||||||
simulationFriction: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_FRICTION, 0.1),
|
simulationFriction: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_FRICTION, 0.1),
|
||||||
} as const;
|
simulationCluster: parseNumber(import.meta.env.VITE_COSMOS_SIMULATION_CLUSTER, 0.1),
|
||||||
|
showFPSMonitor: parseBoolean(import.meta.env.VITE_COSMOS_SHOW_FPS_MONITOR, false),
|
||||||
|
pixelRatio: parseNumber(import.meta.env.VITE_COSMOS_PIXEL_RATIO, 2),
|
||||||
|
scalePointsOnZoom: parseBoolean(import.meta.env.VITE_COSMOS_SCALE_POINTS_ON_ZOOM, false),
|
||||||
|
initialZoomLevel: parseOptionalNumber(import.meta.env.VITE_COSMOS_INITIAL_ZOOM_LEVEL),
|
||||||
|
enableZoom: parseBoolean(import.meta.env.VITE_COSMOS_ENABLE_ZOOM, true),
|
||||||
|
enableSimulationDuringZoom: parseBoolean(
|
||||||
|
import.meta.env.VITE_COSMOS_ENABLE_SIMULATION_DURING_ZOOM,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
enableDrag: parseBoolean(import.meta.env.VITE_COSMOS_ENABLE_DRAG, true),
|
||||||
|
fitViewOnInit: parseBoolean(import.meta.env.VITE_COSMOS_FIT_VIEW_ON_INIT, false),
|
||||||
|
fitViewDelay: parseNumber(import.meta.env.VITE_COSMOS_FIT_VIEW_DELAY, 250),
|
||||||
|
fitViewPadding: parseNumber(import.meta.env.VITE_COSMOS_FIT_VIEW_PADDING, 0.12),
|
||||||
|
fitViewDuration: parseNumber(import.meta.env.VITE_COSMOS_FIT_VIEW_DURATION, 250),
|
||||||
|
randomSeed: parseOptionalSeed(import.meta.env.VITE_COSMOS_RANDOM_SEED),
|
||||||
|
pointSamplingDistance: parseNumber(
|
||||||
|
import.meta.env.VITE_COSMOS_POINT_SAMPLING_DISTANCE,
|
||||||
|
150,
|
||||||
|
),
|
||||||
|
rescalePositions: parseBoolean(import.meta.env.VITE_COSMOS_RESCALE_POSITIONS, false),
|
||||||
|
attribution: parseOptionalString(import.meta.env.VITE_COSMOS_ATTRIBUTION),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const cosmosBackgroundCss = toCssColor(cosmosRuntimeConfig.backgroundColor);
|
||||||
|
|||||||
@@ -213,12 +213,23 @@ export class Renderer {
|
|||||||
const count = xs.length;
|
const count = xs.length;
|
||||||
const edgeCount = edges.length / 2;
|
const edgeCount = edges.length / 2;
|
||||||
this.nodeCount = count;
|
this.nodeCount = count;
|
||||||
|
console.log("[renderer.init] start", {
|
||||||
|
nodes: count,
|
||||||
|
edges: edgeCount,
|
||||||
|
route_line_vertices: routeLineVertices ? routeLineVertices.length / 2 : 0,
|
||||||
|
});
|
||||||
|
|
||||||
// Build quadtree (spatially sorts the array)
|
// Build quadtree (spatially sorts the array)
|
||||||
|
const spatialStart = performance.now();
|
||||||
const { sorted, leaves, order } = buildSpatialIndex(xs, ys);
|
const { sorted, leaves, order } = buildSpatialIndex(xs, ys);
|
||||||
this.leaves = leaves;
|
this.leaves = leaves;
|
||||||
this.sorted = sorted;
|
this.sorted = sorted;
|
||||||
this.sortedToOriginal = order;
|
this.sortedToOriginal = order;
|
||||||
|
console.log("[renderer.init] spatial index built", {
|
||||||
|
nodes: count,
|
||||||
|
leaves: leaves.length,
|
||||||
|
spatial_ms: Math.round(performance.now() - spatialStart),
|
||||||
|
});
|
||||||
|
|
||||||
// Pre-allocate arrays for render loop (zero-allocation rendering)
|
// Pre-allocate arrays for render loop (zero-allocation rendering)
|
||||||
this.visibleLeafIndices = new Uint32Array(leaves.length);
|
this.visibleLeafIndices = new Uint32Array(leaves.length);
|
||||||
@@ -226,12 +237,18 @@ export class Renderer {
|
|||||||
this.countsArray = new Int32Array(leaves.length);
|
this.countsArray = new Int32Array(leaves.length);
|
||||||
|
|
||||||
// Upload sorted particles to GPU as STATIC VBO (never changes)
|
// Upload sorted particles to GPU as STATIC VBO (never changes)
|
||||||
|
const uploadNodesStart = performance.now();
|
||||||
gl.bindVertexArray(this.vao);
|
gl.bindVertexArray(this.vao);
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.nodeVbo);
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.nodeVbo);
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, sorted, gl.STATIC_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, sorted, gl.STATIC_DRAW);
|
||||||
gl.bindVertexArray(null);
|
gl.bindVertexArray(null);
|
||||||
|
console.log("[renderer.init] node buffer uploaded", {
|
||||||
|
upload_ms: Math.round(performance.now() - uploadNodesStart),
|
||||||
|
sorted_bytes: sorted.byteLength,
|
||||||
|
});
|
||||||
|
|
||||||
// Build vertex ID → original input index mapping
|
// Build vertex ID → original input index mapping
|
||||||
|
const mapsStart = performance.now();
|
||||||
const vertexIdToOriginal = new Map<number, number>();
|
const vertexIdToOriginal = new Map<number, number>();
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
vertexIdToOriginal.set(vertexIds[i], i);
|
vertexIdToOriginal.set(vertexIds[i], i);
|
||||||
@@ -250,6 +267,10 @@ export class Renderer {
|
|||||||
vertexIdToSortedIndex.set(vertexIds[i], originalToSorted[i]);
|
vertexIdToSortedIndex.set(vertexIds[i], originalToSorted[i]);
|
||||||
}
|
}
|
||||||
this.vertexIdToSortedIndex = vertexIdToSortedIndex;
|
this.vertexIdToSortedIndex = vertexIdToSortedIndex;
|
||||||
|
console.log("[renderer.init] index maps built", {
|
||||||
|
maps_ms: Math.round(performance.now() - mapsStart),
|
||||||
|
vertex_id_map_size: vertexIdToSortedIndex.size,
|
||||||
|
});
|
||||||
|
|
||||||
this.useRawLineSegments = routeLineVertices !== null && routeLineVertices.length > 0;
|
this.useRawLineSegments = routeLineVertices !== null && routeLineVertices.length > 0;
|
||||||
this.rawLineVertexCount = this.useRawLineSegments && routeLineVertices ? routeLineVertices.length / 2 : 0;
|
this.rawLineVertexCount = this.useRawLineSegments && routeLineVertices ? routeLineVertices.length / 2 : 0;
|
||||||
@@ -257,14 +278,20 @@ export class Renderer {
|
|||||||
this.edgeCount = edgeCount;
|
this.edgeCount = edgeCount;
|
||||||
this.leafEdgeStarts = new Uint32Array(0);
|
this.leafEdgeStarts = new Uint32Array(0);
|
||||||
this.leafEdgeCounts = new Uint32Array(0);
|
this.leafEdgeCounts = new Uint32Array(0);
|
||||||
|
const uploadRoutesStart = performance.now();
|
||||||
gl.bindVertexArray(this.lineVao);
|
gl.bindVertexArray(this.lineVao);
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.lineVbo);
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.lineVbo);
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, routeLineVertices, gl.STATIC_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, routeLineVertices, gl.STATIC_DRAW);
|
||||||
gl.bindVertexArray(null);
|
gl.bindVertexArray(null);
|
||||||
|
console.log("[renderer.init] raw line segments uploaded", {
|
||||||
|
upload_ms: Math.round(performance.now() - uploadRoutesStart),
|
||||||
|
total_ms: Math.round(performance.now() - t0),
|
||||||
|
});
|
||||||
return performance.now() - t0;
|
return performance.now() - t0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remap edges from vertex IDs to sorted indices
|
// Remap edges from vertex IDs to sorted indices
|
||||||
|
const remapEdgesStart = performance.now();
|
||||||
const lineIndices = new Uint32Array(edgeCount * 2);
|
const lineIndices = new Uint32Array(edgeCount * 2);
|
||||||
let validEdges = 0;
|
let validEdges = 0;
|
||||||
for (let i = 0; i < edgeCount; i++) {
|
for (let i = 0; i < edgeCount; i++) {
|
||||||
@@ -278,9 +305,15 @@ export class Renderer {
|
|||||||
validEdges++;
|
validEdges++;
|
||||||
}
|
}
|
||||||
this.edgeCount = validEdges;
|
this.edgeCount = validEdges;
|
||||||
|
console.log("[renderer.init] edges remapped", {
|
||||||
|
remap_ms: Math.round(performance.now() - remapEdgesStart),
|
||||||
|
valid_edges: validEdges,
|
||||||
|
line_indices_bytes: lineIndices.byteLength,
|
||||||
|
});
|
||||||
|
|
||||||
// Build per-leaf edge index for efficient visible-only edge drawing
|
// Build per-leaf edge index for efficient visible-only edge drawing
|
||||||
// Find which leaf each sorted index belongs to
|
// Find which leaf each sorted index belongs to
|
||||||
|
const edgeIndexStart = performance.now();
|
||||||
const nodeToLeaf = new Uint32Array(count);
|
const nodeToLeaf = new Uint32Array(count);
|
||||||
for (let li = 0; li < leaves.length; li++) {
|
for (let li = 0; li < leaves.length; li++) {
|
||||||
const lf = leaves[li];
|
const lf = leaves[li];
|
||||||
@@ -314,11 +347,22 @@ export class Renderer {
|
|||||||
|
|
||||||
this.leafEdgeStarts = leafEdgeOffsets;
|
this.leafEdgeStarts = leafEdgeOffsets;
|
||||||
this.leafEdgeCounts = leafEdgeCounts;
|
this.leafEdgeCounts = leafEdgeCounts;
|
||||||
|
console.log("[renderer.init] leaf edge index built", {
|
||||||
|
leaf_index_ms: Math.round(performance.now() - edgeIndexStart),
|
||||||
|
leaves: leaves.length,
|
||||||
|
sorted_edge_indices_bytes: sortedEdgeIndices.byteLength,
|
||||||
|
});
|
||||||
|
|
||||||
// Upload sorted edges to GPU
|
// Upload sorted edges to GPU
|
||||||
|
const uploadEdgesStart = performance.now();
|
||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.linesIbo);
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.linesIbo);
|
||||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sortedEdgeIndices, gl.STATIC_DRAW);
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sortedEdgeIndices, gl.STATIC_DRAW);
|
||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
||||||
|
console.log("[renderer.init] edge buffer uploaded", {
|
||||||
|
upload_ms: Math.round(performance.now() - uploadEdgesStart),
|
||||||
|
total_ms: Math.round(performance.now() - t0),
|
||||||
|
valid_edges: validEdges,
|
||||||
|
});
|
||||||
|
|
||||||
return performance.now() - t0;
|
return performance.now() - t0;
|
||||||
}
|
}
|
||||||
|
|||||||
49
frontend/src/vite-env.d.ts
vendored
49
frontend/src/vite-env.d.ts
vendored
@@ -4,16 +4,65 @@ interface ImportMetaEnv {
|
|||||||
readonly VITE_BACKEND_URL?: string;
|
readonly VITE_BACKEND_URL?: string;
|
||||||
readonly VITE_COSMOS_ENABLE_SIMULATION?: string;
|
readonly VITE_COSMOS_ENABLE_SIMULATION?: string;
|
||||||
readonly VITE_COSMOS_DEBUG_LAYOUT?: string;
|
readonly VITE_COSMOS_DEBUG_LAYOUT?: string;
|
||||||
|
readonly VITE_COSMOS_BACKGROUND_COLOR?: string;
|
||||||
readonly VITE_COSMOS_SPACE_SIZE?: string;
|
readonly VITE_COSMOS_SPACE_SIZE?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_DEFAULT_COLOR?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_GREYOUT_COLOR?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_GREYOUT_OPACITY?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_DEFAULT_SIZE?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_OPACITY?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_SIZE_SCALE?: string;
|
||||||
|
readonly VITE_COSMOS_HOVERED_POINT_CURSOR?: string;
|
||||||
|
readonly VITE_COSMOS_HOVERED_LINK_CURSOR?: string;
|
||||||
|
readonly VITE_COSMOS_RENDER_HOVERED_POINT_RING?: string;
|
||||||
|
readonly VITE_COSMOS_HOVERED_POINT_RING_COLOR?: string;
|
||||||
|
readonly VITE_COSMOS_FOCUSED_POINT_RING_COLOR?: string;
|
||||||
|
readonly VITE_COSMOS_RENDER_LINKS?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_DEFAULT_COLOR?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_OPACITY?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_GREYOUT_OPACITY?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_DEFAULT_WIDTH?: string;
|
||||||
|
readonly VITE_COSMOS_HOVERED_LINK_COLOR?: string;
|
||||||
|
readonly VITE_COSMOS_HOVERED_LINK_WIDTH_INCREASE?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_WIDTH_SCALE?: string;
|
||||||
|
readonly VITE_COSMOS_SCALE_LINKS_ON_ZOOM?: string;
|
||||||
readonly VITE_COSMOS_CURVED_LINKS?: string;
|
readonly VITE_COSMOS_CURVED_LINKS?: string;
|
||||||
|
readonly VITE_COSMOS_CURVED_LINK_SEGMENTS?: string;
|
||||||
|
readonly VITE_COSMOS_CURVED_LINK_WEIGHT?: string;
|
||||||
|
readonly VITE_COSMOS_CURVED_LINK_CONTROL_POINT_DISTANCE?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_DEFAULT_ARROWS?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_ARROWS_SIZE_SCALE?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_VISIBILITY_DISTANCE_RANGE?: string;
|
||||||
|
readonly VITE_COSMOS_LINK_VISIBILITY_MIN_TRANSPARENCY?: string;
|
||||||
|
readonly VITE_COSMOS_USE_CLASSIC_QUADTREE?: string;
|
||||||
readonly VITE_COSMOS_FIT_VIEW_PADDING?: string;
|
readonly VITE_COSMOS_FIT_VIEW_PADDING?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_DECAY?: string;
|
readonly VITE_COSMOS_SIMULATION_DECAY?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_GRAVITY?: string;
|
readonly VITE_COSMOS_SIMULATION_GRAVITY?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_CENTER?: string;
|
readonly VITE_COSMOS_SIMULATION_CENTER?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_REPULSION?: string;
|
readonly VITE_COSMOS_SIMULATION_REPULSION?: string;
|
||||||
|
readonly VITE_COSMOS_SIMULATION_REPULSION_THETA?: string;
|
||||||
|
readonly VITE_COSMOS_SIMULATION_REPULSION_QUADTREE_LEVELS?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_LINK_SPRING?: string;
|
readonly VITE_COSMOS_SIMULATION_LINK_SPRING?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_LINK_DISTANCE?: string;
|
readonly VITE_COSMOS_SIMULATION_LINK_DISTANCE?: string;
|
||||||
|
readonly VITE_COSMOS_SIMULATION_LINK_DISTANCE_RANDOM_VARIATION_RANGE?: string;
|
||||||
|
readonly VITE_COSMOS_SIMULATION_REPULSION_FROM_MOUSE?: string;
|
||||||
|
readonly VITE_COSMOS_ENABLE_RIGHT_CLICK_REPULSION?: string;
|
||||||
readonly VITE_COSMOS_SIMULATION_FRICTION?: string;
|
readonly VITE_COSMOS_SIMULATION_FRICTION?: string;
|
||||||
|
readonly VITE_COSMOS_SIMULATION_CLUSTER?: string;
|
||||||
|
readonly VITE_COSMOS_SHOW_FPS_MONITOR?: string;
|
||||||
|
readonly VITE_COSMOS_PIXEL_RATIO?: string;
|
||||||
|
readonly VITE_COSMOS_SCALE_POINTS_ON_ZOOM?: string;
|
||||||
|
readonly VITE_COSMOS_INITIAL_ZOOM_LEVEL?: string;
|
||||||
|
readonly VITE_COSMOS_ENABLE_ZOOM?: string;
|
||||||
|
readonly VITE_COSMOS_ENABLE_SIMULATION_DURING_ZOOM?: string;
|
||||||
|
readonly VITE_COSMOS_ENABLE_DRAG?: string;
|
||||||
|
readonly VITE_COSMOS_FIT_VIEW_ON_INIT?: string;
|
||||||
|
readonly VITE_COSMOS_FIT_VIEW_DELAY?: string;
|
||||||
|
readonly VITE_COSMOS_FIT_VIEW_DURATION?: string;
|
||||||
|
readonly VITE_COSMOS_RANDOM_SEED?: string;
|
||||||
|
readonly VITE_COSMOS_POINT_SAMPLING_DISTANCE?: string;
|
||||||
|
readonly VITE_COSMOS_RESCALE_POSITIONS?: string;
|
||||||
|
readonly VITE_COSMOS_ATTRIBUTION?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
|
|||||||
Reference in New Issue
Block a user