mirror of
https://github.com/jcreek/OpenNetworkDiagram.git
synced 2026-07-14 03:23:44 +00:00
feat(*): Add ports and lines
This commit is contained in:
@@ -2,34 +2,137 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { networkStore, loadNetworkData } from '../../stores/networkStore';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
import MachineCard from './MachineCard.svelte';
|
||||
import DeviceCard from './DeviceCard.svelte';
|
||||
|
||||
// Optionally pass in a JSON path as a prop
|
||||
import type { NetworkData, Port } from '../../lib/types';
|
||||
|
||||
export let jsonPath: string = '/data/network.json';
|
||||
|
||||
// Local state
|
||||
let data: any;
|
||||
let data: NetworkData;
|
||||
|
||||
// We'll store all port references in one big map for easy access
|
||||
let lines: any[] = [];
|
||||
|
||||
onMount(async () => {
|
||||
// Load data into the store
|
||||
await loadNetworkData(jsonPath);
|
||||
|
||||
// Subscribe once or use the $ syntax in markup
|
||||
data = get(networkStore);
|
||||
|
||||
// Wait for DOM to render fully
|
||||
setTimeout(() => {
|
||||
createLines();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
/**
|
||||
* Called after child components have rendered.
|
||||
* We gather all port references and draw lines using global LeaderLine
|
||||
*/
|
||||
async function createLines() {
|
||||
// Use global UMD version from window
|
||||
const LeaderLine = (window as any).LeaderLine;
|
||||
if (!LeaderLine) {
|
||||
console.error('LeaderLine is not loaded.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear any previous lines
|
||||
for (const ln of lines) {
|
||||
ln.remove();
|
||||
}
|
||||
lines = [];
|
||||
|
||||
type PortInfo = {
|
||||
parentName: string;
|
||||
port: Port;
|
||||
element: HTMLDivElement;
|
||||
};
|
||||
|
||||
const portDataMap: Map<string, PortInfo> = new Map();
|
||||
|
||||
// GATHER MACHINE PORTS
|
||||
for (const machine of data.machines) {
|
||||
if (machine.ports) {
|
||||
for (const p of machine.ports) {
|
||||
const key = `${machine.machineName}-${p.portName}`;
|
||||
const elem = document.querySelector(`[data-port-key="${key}"]`) as HTMLDivElement;
|
||||
if (elem) {
|
||||
portDataMap.set(key, {
|
||||
parentName: machine.machineName,
|
||||
port: p,
|
||||
element: elem
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GATHER DEVICE PORTS
|
||||
for (const dev of data.devices) {
|
||||
if (dev.ports) {
|
||||
for (const p of dev.ports) {
|
||||
const key = `${dev.name}-${p.portName}`;
|
||||
const elem = document.querySelector(`[data-port-key="${key}"]`) as HTMLDivElement;
|
||||
if (elem) {
|
||||
portDataMap.set(key, {
|
||||
parentName: dev.name,
|
||||
port: p,
|
||||
element: elem
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DRAW CONNECTIONS
|
||||
for (const [key, info] of portDataMap.entries()) {
|
||||
const localPort = info.port;
|
||||
if (!localPort.connectedTo) continue;
|
||||
|
||||
const remoteKey = localPort.connectedTo;
|
||||
const remoteInfo = portDataMap.get(remoteKey);
|
||||
if (!remoteInfo) continue;
|
||||
|
||||
if (key > remoteKey) continue; // Avoid duplicates
|
||||
|
||||
const localSpeed = localPort.speedGbps ?? 1;
|
||||
const remoteSpeed = remoteInfo.port.speedGbps ?? 1;
|
||||
const cableSpeed = Math.min(localSpeed, remoteSpeed);
|
||||
const color = getLineColor(cableSpeed);
|
||||
|
||||
const line = new LeaderLine(info.element, remoteInfo.element, {
|
||||
path: 'straight',
|
||||
startPlug: 'behind',
|
||||
endPlug: 'behind',
|
||||
color,
|
||||
size: 4,
|
||||
middleLabel: LeaderLine.captionLabel({
|
||||
text: `${cableSpeed}GbE`,
|
||||
fontSize: 12,
|
||||
color: 'white',
|
||||
outlineColor: 'black',
|
||||
outlineSize: 2
|
||||
})
|
||||
});
|
||||
|
||||
lines.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
function getLineColor(speed: number): string {
|
||||
if (speed >= 10) return 'orange';
|
||||
if (speed >= 2.5) return 'green';
|
||||
if (speed >= 1) return 'blue';
|
||||
return 'gray';
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
{#if data}
|
||||
<div class="diagram-container">
|
||||
<!-- Render Machines -->
|
||||
{#each data.machines as machine}
|
||||
<MachineCard {machine} />
|
||||
{/each}
|
||||
|
||||
<!-- Render Other Devices -->
|
||||
{#each data.devices as device}
|
||||
<DeviceCard {device} />
|
||||
{/each}
|
||||
@@ -39,10 +142,10 @@
|
||||
|
||||
<style>
|
||||
.diagram-container {
|
||||
/* Example layout style - customize as needed */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
position: relative; /* required for leader-line positioning */
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user