Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions lib/components/SchematicViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { getStoredBoolean, setStoredBoolean } from "lib/hooks/useLocalStorage"
import { MouseTracker } from "./MouseTracker"
import { SchematicComponentMouseTarget } from "./SchematicComponentMouseTarget"
import { SchematicPortMouseTarget } from "./SchematicPortMouseTarget"
import { addSubcircuitConnectivityMapKeysToSchematicTraces } from "lib/utils/add-subcircuit-connectivity-map-keys-to-schematic-traces"

interface Props {
circuitJson: CircuitJson
Expand Down Expand Up @@ -262,18 +263,24 @@ export const SchematicViewer = ({
const svgString = useMemo(() => {
if (!containerWidth || !containerHeight) return ""

return convertCircuitJsonToSchematicSvg(circuitJson as any, {
width: containerWidth,
height: containerHeight || 720,
drawPorts: showSchematicPorts,
grid: !showGrid
? undefined
: {
cellSize: 1,
labelCells: true,
},
colorOverrides,
})
const circuitJsonWithTraceConnectivity =
addSubcircuitConnectivityMapKeysToSchematicTraces(circuitJson)

return convertCircuitJsonToSchematicSvg(
circuitJsonWithTraceConnectivity as any,
{
width: containerWidth,
height: containerHeight || 720,
drawPorts: showSchematicPorts,
grid: !showGrid
? undefined
: {
cellSize: 1,
labelCells: true,
},
colorOverrides,
},
)
}, [
circuitJsonKey,
containerWidth,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { CircuitJson } from "circuit-json"

const normalizePinToken = (token: string | number | undefined | null) => {
if (token === undefined || token === null) return ""
return String(token).replace(/^pin/i, "")
}

export const addSubcircuitConnectivityMapKeysToSchematicTraces = (
circuitJson: CircuitJson,
): CircuitJson => {
const componentNameById = new Map<string, string>()
const sourceTraceKeyById = new Map<string, string>()
const portKeyByComponentAndPin = new Map<string, string>()

for (const elm of circuitJson as any[]) {
if (elm.type === "source_component" && elm.source_component_id) {
componentNameById.set(elm.source_component_id, elm.name)
}
}

for (const elm of circuitJson as any[]) {
if (
elm.type === "source_trace" &&
elm.source_trace_id &&
elm.subcircuit_connectivity_map_key
) {
sourceTraceKeyById.set(
elm.source_trace_id,
elm.subcircuit_connectivity_map_key,
)
}

if (
elm.type === "source_port" &&
elm.source_component_id &&
elm.subcircuit_connectivity_map_key
) {
const componentName = componentNameById.get(elm.source_component_id)
if (!componentName) continue

const pinTokens = new Set<string>()
pinTokens.add(normalizePinToken(elm.pin_number))
pinTokens.add(normalizePinToken(elm.name))
for (const hint of elm.port_hints ?? []) {
pinTokens.add(normalizePinToken(hint))
}

for (const pinToken of pinTokens) {
if (!pinToken) continue
portKeyByComponentAndPin.set(
`${componentName}.${pinToken}`,
elm.subcircuit_connectivity_map_key,
)
}
}
}

const getKeyForSchematicTrace = (schematicTrace: any) => {
if (schematicTrace.subcircuit_connectivity_map_key) {
return schematicTrace.subcircuit_connectivity_map_key
}

const directSourceTraceKey = sourceTraceKeyById.get(
schematicTrace.source_trace_id,
)
if (directSourceTraceKey) return directSourceTraceKey

const solverMatch =
schematicTrace.source_trace_id?.match(/^solver_(.+?)-(.+)$/)
if (!solverMatch) return undefined

for (const endpoint of [solverMatch[1], solverMatch[2]]) {
const endpointMatch = endpoint.match(/^(.+)\.([^.\s]+)$/)
if (!endpointMatch) continue
const key = portKeyByComponentAndPin.get(
`${endpointMatch[1]}.${normalizePinToken(endpointMatch[2])}`,
)
if (key) return key
}

return undefined
}

return (circuitJson as any[]).map((elm) => {
if (elm.type !== "schematic_trace") return elm
const subcircuitConnectivityMapKey = getKeyForSchematicTrace(elm)
if (!subcircuitConnectivityMapKey) return elm
return {
...elm,
subcircuit_connectivity_map_key: subcircuitConnectivityMapKey,
}
}) as CircuitJson
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { expect, test } from "bun:test"
import { addSubcircuitConnectivityMapKeysToSchematicTraces } from "lib/utils/add-subcircuit-connectivity-map-keys-to-schematic-traces"

test("adds subcircuit connectivity keys to solver-generated schematic traces", () => {
const circuitJson = [
{
type: "source_component",
source_component_id: "source_component_0",
name: "R1",
},
{
type: "source_component",
source_component_id: "source_component_1",
name: "C1",
},
{
type: "source_port",
source_port_id: "source_port_0",
source_component_id: "source_component_0",
pin_number: 2,
name: "pin2",
port_hints: ["pin2", "2"],
subcircuit_connectivity_map_key: "net0",
},
{
type: "source_port",
source_port_id: "source_port_1",
source_component_id: "source_component_1",
pin_number: 1,
name: "pin1",
port_hints: ["pin1", "1"],
subcircuit_connectivity_map_key: "net0",
},
{
type: "schematic_trace",
schematic_trace_id: "schematic_trace_0",
source_trace_id: "solver_R1.2-C1.1",
edges: [],
junctions: [],
},
] as any

const nextCircuitJson =
addSubcircuitConnectivityMapKeysToSchematicTraces(circuitJson)

expect((nextCircuitJson as any)[4].subcircuit_connectivity_map_key).toBe(
"net0",
)
})
Loading