circuit-to-svg 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -976,14 +976,184 @@ var colorMap = {
976
976
  }
977
977
  };
978
978
 
979
+ // lib/sch/get-schematic-bounds-from-circuit-json.ts
980
+ function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
981
+ let minX = Number.POSITIVE_INFINITY;
982
+ let minY = Number.POSITIVE_INFINITY;
983
+ let maxX = Number.NEGATIVE_INFINITY;
984
+ let maxY = Number.NEGATIVE_INFINITY;
985
+ const portSize = 0.2;
986
+ for (const item of soup) {
987
+ if (item.type === "schematic_component") {
988
+ updateBounds(item.center, item.size, item.rotation || 0);
989
+ } else if (item.type === "schematic_port") {
990
+ updateBounds(item.center, { width: portSize, height: portSize }, 0);
991
+ } else if (item.type === "schematic_debug_object") {
992
+ if (item.shape === "rect") {
993
+ updateBounds(item.center, item.size, 0);
994
+ } else if (item.shape === "line") {
995
+ updateBounds(item.start, { width: 0.1, height: 0.1 }, 0);
996
+ updateBounds(item.end, { width: 0.1, height: 0.1 }, 0);
997
+ }
998
+ }
999
+ }
1000
+ minX -= padding;
1001
+ minY -= padding;
1002
+ maxX += padding;
1003
+ maxY += padding;
1004
+ return { minX, minY, maxX, maxY };
1005
+ function updateBounds(center, size, rotation) {
1006
+ const corners = [
1007
+ { x: -size.width / 2, y: -size.height / 2 },
1008
+ { x: size.width / 2, y: -size.height / 2 },
1009
+ { x: size.width / 2, y: size.height / 2 },
1010
+ { x: -size.width / 2, y: size.height / 2 }
1011
+ ];
1012
+ for (const corner of corners) {
1013
+ const rotatedX = corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x;
1014
+ const rotatedY = corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y;
1015
+ minX = Math.min(minX, rotatedX);
1016
+ minY = Math.min(minY, rotatedY);
1017
+ maxX = Math.max(maxX, rotatedX);
1018
+ maxY = Math.max(maxY, rotatedY);
1019
+ }
1020
+ }
1021
+ }
1022
+
1023
+ // lib/sch/draw-schematic-grid.ts
1024
+ function drawSchematicGrid(params) {
1025
+ const { minX, minY, maxX, maxY } = params.bounds;
1026
+ const cellSize = params.cellSize ?? 1;
1027
+ const labelCells = params.labelCells ?? false;
1028
+ const gridLines = [];
1029
+ for (let x = Math.ceil(minX); x <= Math.floor(maxX); x += cellSize) {
1030
+ gridLines.push({
1031
+ name: "line",
1032
+ type: "element",
1033
+ attributes: {
1034
+ x1: x.toString(),
1035
+ y1: minY.toString(),
1036
+ x2: x.toString(),
1037
+ y2: maxY.toString(),
1038
+ stroke: colorMap.schematic.grid,
1039
+ "stroke-width": "0.01",
1040
+ "stroke-opacity": "0.5"
1041
+ }
1042
+ });
1043
+ }
1044
+ for (let y = Math.ceil(minY); y <= Math.floor(maxY); y += cellSize) {
1045
+ gridLines.push({
1046
+ name: "line",
1047
+ type: "element",
1048
+ attributes: {
1049
+ x1: minX.toString(),
1050
+ y1: y.toString(),
1051
+ x2: maxX.toString(),
1052
+ y2: y.toString(),
1053
+ stroke: colorMap.schematic.grid,
1054
+ "stroke-width": "0.01",
1055
+ "stroke-opacity": "0.5"
1056
+ }
1057
+ });
1058
+ }
1059
+ if (labelCells) {
1060
+ for (let x = Math.ceil(minX); x <= Math.floor(maxX); x += cellSize) {
1061
+ for (let y = Math.ceil(minY); y <= Math.floor(maxY); y += cellSize) {
1062
+ gridLines.push({
1063
+ name: "text",
1064
+ type: "element",
1065
+ attributes: {
1066
+ x: x.toString(),
1067
+ y: y.toString(),
1068
+ fill: colorMap.schematic.grid,
1069
+ "font-size": (cellSize / 6).toString(),
1070
+ "fill-opacity": "0.5"
1071
+ },
1072
+ children: [
1073
+ {
1074
+ type: "text",
1075
+ value: `${x},${y}`,
1076
+ name: "",
1077
+ attributes: {},
1078
+ children: []
1079
+ }
1080
+ ]
1081
+ });
1082
+ }
1083
+ }
1084
+ }
1085
+ return {
1086
+ name: "g",
1087
+ value: "",
1088
+ type: "element",
1089
+ attributes: { class: "grid" },
1090
+ children: gridLines
1091
+ };
1092
+ }
1093
+
1094
+ // lib/sch/draw-schematic-labeled-points.ts
1095
+ function drawSchematicLabeledPoints(params) {
1096
+ const { points, transform } = params;
1097
+ const labeledPointsGroup = [];
1098
+ for (const point of points) {
1099
+ labeledPointsGroup.push({
1100
+ name: "path",
1101
+ type: "element",
1102
+ attributes: {
1103
+ d: `M${point.x - 0.1},${point.y - 0.1} L${point.x + 0.1},${point.y + 0.1} M${point.x - 0.1},${point.y + 0.1} L${point.x + 0.1},${point.y - 0.1}`,
1104
+ stroke: colorMap.schematic.grid,
1105
+ "stroke-width": "0.02",
1106
+ "stroke-opacity": "0.7"
1107
+ }
1108
+ });
1109
+ labeledPointsGroup.push({
1110
+ name: "text",
1111
+ type: "element",
1112
+ attributes: {
1113
+ x: (point.x + 0.15).toString(),
1114
+ y: (point.y - 0.15).toString(),
1115
+ fill: colorMap.schematic.grid,
1116
+ "font-size": "0.15",
1117
+ "fill-opacity": "0.7"
1118
+ },
1119
+ children: [
1120
+ {
1121
+ type: "text",
1122
+ value: point.label || `(${point.x},${point.y})`,
1123
+ name: "",
1124
+ attributes: {},
1125
+ children: []
1126
+ }
1127
+ ]
1128
+ });
1129
+ }
1130
+ return {
1131
+ name: "g",
1132
+ value: "",
1133
+ type: "element",
1134
+ attributes: { class: "labeled-points" },
1135
+ children: labeledPointsGroup
1136
+ };
1137
+ }
1138
+
979
1139
  // lib/sch/convert-circuit-json-to-schematic-svg.ts
980
1140
  import { stringify as stringify2 } from "svgson";
981
1141
 
982
1142
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-component.ts
983
1143
  import { getSvg, symbols } from "schematic-symbols";
984
1144
  import { parseSync } from "svgson";
985
- function createSchematicComponent(center, size, rotation, symbolName, portLabels, sourceComponentId, schematicComponentId, circuitJson) {
986
- const transform = `translate(${center.x}, ${center.y}) rotate(${rotation * 180 / Math.PI})`;
1145
+ function createSchematicComponent({
1146
+ component,
1147
+ circuitJson
1148
+ }) {
1149
+ const center = component.center;
1150
+ const size = component.size;
1151
+ const rotation = component.rotation;
1152
+ const symbolName = component.symbol_name;
1153
+ const portLabels = component.port_labels;
1154
+ const sourceComponentId = component.source_component_id;
1155
+ const schematicComponentId = component.schematic_component_id;
1156
+ const transformString = `translate(${center.x}, ${center.y}) rotate(${rotation * 180 / Math.PI})`;
987
1157
  let children = [];
988
1158
  const sourceComponent = circuitJson?.find(
989
1159
  (item) => item.type === "source_component" && item.source_component_id === sourceComponentId
@@ -1025,13 +1195,15 @@ function createSchematicComponent(center, size, rotation, symbolName, portLabels
1025
1195
  children.push({
1026
1196
  name: "rect",
1027
1197
  type: "element",
1198
+ value: "",
1028
1199
  attributes: {
1029
1200
  class: "component chip",
1030
- x: -size.width / 2,
1031
- y: -size.height / 2,
1032
- width: size.width,
1033
- height: size.height
1034
- }
1201
+ x: (-size.width / 2).toString(),
1202
+ y: (-size.height / 2).toString(),
1203
+ width: size.width.toString(),
1204
+ height: size.height.toString()
1205
+ },
1206
+ children: []
1035
1207
  });
1036
1208
  if (manufacturerNumber) {
1037
1209
  children.push({
@@ -1039,24 +1211,42 @@ function createSchematicComponent(center, size, rotation, symbolName, portLabels
1039
1211
  type: "element",
1040
1212
  attributes: {
1041
1213
  class: "component-name",
1042
- x: 1.2,
1043
- y: -size.height / 2 - 0.5,
1214
+ x: 1.2.toString(),
1215
+ y: (-size.height / 2 - 0.5).toString(),
1044
1216
  "text-anchor": "right",
1045
1217
  "dominant-baseline": "auto"
1046
1218
  },
1047
- children: [{ type: "text", value: manufacturerNumber }]
1219
+ children: [
1220
+ {
1221
+ type: "text",
1222
+ value: manufacturerNumber,
1223
+ name: "",
1224
+ attributes: {},
1225
+ children: []
1226
+ }
1227
+ ],
1228
+ value: ""
1048
1229
  });
1049
1230
  children.push({
1050
1231
  name: "text",
1051
1232
  type: "element",
1052
1233
  attributes: {
1053
1234
  class: "component-name",
1054
- x: 1.2,
1055
- y: -size.height / 2 - 0.7,
1235
+ x: 1.2.toString(),
1236
+ y: (-size.height / 2 - 0.7).toString(),
1056
1237
  "text-anchor": "right",
1057
1238
  "dominant-baseline": "auto"
1058
1239
  },
1059
- children: [{ type: "text", value: componentName }]
1240
+ children: [
1241
+ {
1242
+ type: "text",
1243
+ value: componentName || "",
1244
+ name: "",
1245
+ attributes: {},
1246
+ children: []
1247
+ }
1248
+ ],
1249
+ value: ""
1060
1250
  });
1061
1251
  }
1062
1252
  const schematicPorts = circuitJson?.filter(
@@ -1101,21 +1291,25 @@ function createSchematicComponent(center, size, rotation, symbolName, portLabels
1101
1291
  type: "element",
1102
1292
  attributes: {
1103
1293
  class: "component-pin",
1104
- x1: x,
1105
- y1: y,
1106
- x2: endX,
1107
- y2: endY
1108
- }
1294
+ x1: x.toString(),
1295
+ y1: y.toString(),
1296
+ x2: endX.toString(),
1297
+ y2: endY.toString()
1298
+ },
1299
+ value: "",
1300
+ children: []
1109
1301
  });
1110
1302
  children.push({
1111
1303
  name: "circle",
1112
1304
  type: "element",
1113
1305
  attributes: {
1114
1306
  class: "component-pin",
1115
- cx: endX,
1116
- cy: endY,
1117
- r: circleRadius
1118
- }
1307
+ cx: endX.toString(),
1308
+ cy: endY.toString(),
1309
+ r: circleRadius.toString()
1310
+ },
1311
+ value: "",
1312
+ children: []
1119
1313
  });
1120
1314
  const labelKey = `pin${pinNumber}`;
1121
1315
  if (portLabels && labelKey in portLabels) {
@@ -1124,13 +1318,22 @@ function createSchematicComponent(center, size, rotation, symbolName, portLabels
1124
1318
  type: "element",
1125
1319
  attributes: {
1126
1320
  class: "port-label",
1127
- x: labelX,
1128
- y: labelY,
1321
+ x: labelX.toString(),
1322
+ y: labelY.toString(),
1129
1323
  "text-anchor": textAnchor,
1130
1324
  "dominant-baseline": dominantBaseline,
1131
1325
  "font-size": "0.2"
1132
1326
  },
1133
- children: [{ type: "text", value: portLabels[labelKey] }]
1327
+ children: [
1328
+ {
1329
+ type: "text",
1330
+ value: portLabels[labelKey],
1331
+ name: "",
1332
+ attributes: {},
1333
+ children: []
1334
+ }
1335
+ ],
1336
+ value: ""
1134
1337
  });
1135
1338
  }
1136
1339
  const pinNumberX = endX;
@@ -1156,13 +1359,22 @@ function createSchematicComponent(center, size, rotation, symbolName, portLabels
1156
1359
  type: "element",
1157
1360
  attributes: {
1158
1361
  class: "pin-number",
1159
- x: pinNumberX,
1160
- y: pinNumberY,
1362
+ x: pinNumberX.toString(),
1363
+ y: pinNumberY.toString(),
1161
1364
  "text-anchor": pinNumberAnchor,
1162
1365
  "dominant-baseline": pinNumberBaseline,
1163
1366
  "font-size": "0.15"
1164
1367
  },
1165
- children: [{ type: "text", value: pinNumber }]
1368
+ value: "",
1369
+ children: [
1370
+ {
1371
+ type: "text",
1372
+ value: pinNumber.toString(),
1373
+ name: "",
1374
+ attributes: {},
1375
+ children: []
1376
+ }
1377
+ ]
1166
1378
  });
1167
1379
  }
1168
1380
  }
@@ -1172,262 +1384,237 @@ function createSchematicComponent(center, size, rotation, symbolName, portLabels
1172
1384
  type: "element",
1173
1385
  attributes: {
1174
1386
  class: "component-name",
1175
- x: 0,
1176
- y: -size.height / 2 - 0.2,
1387
+ x: "0",
1388
+ y: (-size.height / 2 - 0.2).toString(),
1177
1389
  "text-anchor": "middle",
1178
1390
  "dominant-baseline": "auto"
1179
1391
  },
1180
- children: [{ type: "text", value: resistance || capacitance }]
1392
+ value: "",
1393
+ children: [
1394
+ {
1395
+ type: "text",
1396
+ value: (resistance || capacitance || "").toString(),
1397
+ name: "",
1398
+ attributes: {},
1399
+ children: []
1400
+ }
1401
+ ]
1181
1402
  });
1182
1403
  children.push({
1183
1404
  name: "text",
1184
1405
  type: "element",
1185
1406
  attributes: {
1186
1407
  class: "component-name",
1187
- x: 0,
1188
- y: -size.height / 2 - 0.5,
1408
+ x: "0",
1409
+ y: (-size.height / 2 - 0.5).toString(),
1189
1410
  "text-anchor": "middle",
1190
1411
  "dominant-baseline": "auto"
1191
1412
  },
1192
- children: [{ type: "text", value: componentName }]
1413
+ value: "",
1414
+ children: [
1415
+ {
1416
+ type: "text",
1417
+ value: componentName || "",
1418
+ name: "",
1419
+ attributes: {},
1420
+ children: []
1421
+ }
1422
+ ]
1193
1423
  });
1194
1424
  }
1195
- return {
1196
- name: "g",
1197
- type: "element",
1198
- attributes: { transform },
1199
- children
1200
- };
1425
+ return [
1426
+ {
1427
+ name: "g",
1428
+ value: "",
1429
+ type: "element",
1430
+ attributes: { transform: transformString },
1431
+ children
1432
+ }
1433
+ ];
1201
1434
  }
1202
1435
 
1203
1436
  // lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
1204
1437
  function createSvgObjectsFromSchDebugObject(debugObject) {
1205
1438
  if (debugObject.shape === "rect") {
1206
- return [{
1207
- name: "rect",
1208
- type: "element",
1209
- value: "",
1210
- attributes: {
1211
- x: (debugObject.center.x - debugObject.size.width / 2).toString(),
1212
- y: (debugObject.center.y - debugObject.size.height / 2).toString(),
1213
- width: debugObject.size.width.toString(),
1214
- height: debugObject.size.height.toString(),
1215
- fill: "none",
1216
- stroke: "red",
1217
- "stroke-width": "0.02",
1218
- "stroke-dasharray": "0.1,0.1"
1219
- },
1220
- children: debugObject.label ? [{
1221
- name: "text",
1439
+ return [
1440
+ {
1441
+ name: "rect",
1222
1442
  type: "element",
1223
1443
  value: "",
1224
1444
  attributes: {
1225
- x: debugObject.center.x.toString(),
1226
- y: (debugObject.center.y - debugObject.size.height / 2 - 0.1).toString(),
1227
- "text-anchor": "middle",
1228
- "font-size": "0.2",
1229
- fill: "red"
1445
+ x: (debugObject.center.x - debugObject.size.width / 2).toString(),
1446
+ y: (debugObject.center.y - debugObject.size.height / 2).toString(),
1447
+ width: debugObject.size.width.toString(),
1448
+ height: debugObject.size.height.toString(),
1449
+ fill: "none",
1450
+ stroke: "red",
1451
+ "stroke-width": "0.02",
1452
+ "stroke-dasharray": "0.1,0.1"
1230
1453
  },
1231
- children: [{
1232
- type: "text",
1233
- value: debugObject.label,
1234
- name: "",
1235
- attributes: {},
1236
- children: []
1237
- }]
1238
- }] : []
1239
- }];
1454
+ children: debugObject.label ? [
1455
+ {
1456
+ name: "text",
1457
+ type: "element",
1458
+ value: "",
1459
+ attributes: {
1460
+ x: debugObject.center.x.toString(),
1461
+ y: (debugObject.center.y - debugObject.size.height / 2 - 0.1).toString(),
1462
+ "text-anchor": "middle",
1463
+ "font-size": "0.2",
1464
+ fill: "red"
1465
+ },
1466
+ children: [
1467
+ {
1468
+ type: "text",
1469
+ value: debugObject.label,
1470
+ name: "",
1471
+ attributes: {},
1472
+ children: []
1473
+ }
1474
+ ]
1475
+ }
1476
+ ] : []
1477
+ }
1478
+ ];
1240
1479
  }
1241
1480
  if (debugObject.shape === "line") {
1242
- return [{
1243
- name: "line",
1244
- type: "element",
1245
- value: "",
1246
- attributes: {
1247
- x1: debugObject.start.x.toString(),
1248
- y1: debugObject.start.y.toString(),
1249
- x2: debugObject.end.x.toString(),
1250
- y2: debugObject.end.y.toString(),
1251
- stroke: "red",
1252
- "stroke-width": "0.02",
1253
- "stroke-dasharray": "0.1,0.1"
1254
- },
1255
- children: debugObject.label ? [{
1256
- name: "text",
1481
+ return [
1482
+ {
1483
+ name: "line",
1257
1484
  type: "element",
1258
1485
  value: "",
1259
1486
  attributes: {
1260
- x: ((debugObject.start.x + debugObject.end.x) / 2).toString(),
1261
- y: ((debugObject.start.y + debugObject.end.y) / 2 - 0.1).toString(),
1262
- "text-anchor": "middle",
1263
- "font-size": "0.2",
1264
- fill: "red"
1487
+ x1: debugObject.start.x.toString(),
1488
+ y1: debugObject.start.y.toString(),
1489
+ x2: debugObject.end.x.toString(),
1490
+ y2: debugObject.end.y.toString(),
1491
+ stroke: "red",
1492
+ "stroke-width": "0.02",
1493
+ "stroke-dasharray": "0.1,0.1"
1265
1494
  },
1266
- children: [{
1267
- type: "text",
1268
- value: debugObject.label,
1269
- name: "",
1270
- attributes: {},
1271
- children: []
1272
- }]
1273
- }] : []
1274
- }];
1495
+ children: debugObject.label ? [
1496
+ {
1497
+ name: "text",
1498
+ type: "element",
1499
+ value: "",
1500
+ attributes: {
1501
+ x: ((debugObject.start.x + debugObject.end.x) / 2).toString(),
1502
+ y: ((debugObject.start.y + debugObject.end.y) / 2 - 0.1).toString(),
1503
+ "text-anchor": "middle",
1504
+ "font-size": "0.2",
1505
+ fill: "red"
1506
+ },
1507
+ children: [
1508
+ {
1509
+ type: "text",
1510
+ value: debugObject.label,
1511
+ name: "",
1512
+ attributes: {},
1513
+ children: []
1514
+ }
1515
+ ]
1516
+ }
1517
+ ] : []
1518
+ }
1519
+ ];
1275
1520
  }
1276
1521
  return [];
1277
1522
  }
1278
1523
 
1524
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
1525
+ function createSchematicTrace(trace, flipY, portPositions) {
1526
+ const edges = trace.edges;
1527
+ if (edges.length === 0) return [];
1528
+ let path = "";
1529
+ edges.forEach((edge, index) => {
1530
+ const fromPoint = edge.from.ti !== void 0 ? portPositions.get(edge.from.ti) : edge.from;
1531
+ const toPoint = edge.to.ti !== void 0 ? portPositions.get(edge.to.ti) : edge.to;
1532
+ if (!fromPoint || !toPoint) {
1533
+ return;
1534
+ }
1535
+ const fromCoord = `${fromPoint.x - 0.15} ${flipY(fromPoint.y)}`;
1536
+ const toCoord = `${toPoint.x + 0.15} ${flipY(toPoint.y)}`;
1537
+ if (index === 0) {
1538
+ path += `M ${fromCoord} L ${toCoord}`;
1539
+ } else {
1540
+ path += ` L ${toCoord}`;
1541
+ }
1542
+ });
1543
+ return path ? [
1544
+ {
1545
+ name: "path",
1546
+ type: "element",
1547
+ attributes: {
1548
+ class: "trace",
1549
+ d: path
1550
+ },
1551
+ value: "",
1552
+ children: []
1553
+ }
1554
+ ] : [];
1555
+ }
1556
+
1279
1557
  // lib/sch/convert-circuit-json-to-schematic-svg.ts
1280
- function convertCircuitJsonToSchematicSvg(soup, options) {
1281
- let minX = Number.POSITIVE_INFINITY;
1282
- let minY = Number.POSITIVE_INFINITY;
1283
- let maxX = Number.NEGATIVE_INFINITY;
1284
- let maxY = Number.NEGATIVE_INFINITY;
1285
- const portSize = 0.2;
1558
+ import { identity } from "transformation-matrix";
1559
+ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
1286
1560
  const portPositions = /* @__PURE__ */ new Map();
1287
- for (const item of soup) {
1288
- if (item.type === "schematic_component") {
1289
- updateBounds(item.center, item.size, item.rotation || 0);
1290
- } else if (item.type === "schematic_port") {
1291
- updateBounds(item.center, { width: portSize, height: portSize }, 0);
1561
+ for (const item of circuitJson) {
1562
+ if (item.type === "schematic_port") {
1292
1563
  portPositions.set(item.schematic_port_id, item.center);
1293
- } else if (item.type === "schematic_debug_object") {
1294
- if (item.shape === "rect") {
1295
- updateBounds(item.center, item.size, 0);
1296
- } else if (item.shape === "line") {
1297
- updateBounds(item.start, { width: 0.1, height: 0.1 }, 0);
1298
- updateBounds(item.end, { width: 0.1, height: 0.1 }, 0);
1299
- }
1300
1564
  }
1301
1565
  }
1302
- const padding = 0.5;
1303
- minX -= padding;
1304
- minY -= padding;
1305
- maxX += padding;
1306
- maxY += padding;
1566
+ const bounds = getSchematicBoundsFromCircuitJson(circuitJson);
1567
+ const { minX, minY, maxX, maxY } = bounds;
1568
+ const viewBoxPadding = 0.5;
1569
+ const width = maxX - minX + 2 * viewBoxPadding;
1307
1570
  const height = maxY - minY;
1571
+ const viewBox = `${minX - viewBoxPadding} ${minY - viewBoxPadding} ${width} ${height + 2 * viewBoxPadding}`;
1308
1572
  const flipY = (y) => height - (y - minY) + minY;
1573
+ const transform = identity();
1309
1574
  const svgChildren = [];
1310
1575
  if (options?.grid) {
1311
- const cellSize = typeof options.grid === "object" ? options.grid.cellSize : 1;
1312
- const gridLines = [];
1313
- for (let x = Math.ceil(minX); x <= Math.floor(maxX); x += cellSize) {
1314
- gridLines.push({
1315
- name: "line",
1316
- type: "element",
1317
- attributes: {
1318
- x1: x.toString(),
1319
- y1: minY.toString(),
1320
- x2: x.toString(),
1321
- y2: maxY.toString(),
1322
- stroke: colorMap.schematic.grid,
1323
- "stroke-width": "0.01",
1324
- "stroke-opacity": "0.5"
1325
- }
1326
- });
1327
- }
1328
- for (let y = Math.ceil(minY); y <= Math.floor(maxY); y += cellSize) {
1329
- gridLines.push({
1330
- name: "line",
1331
- type: "element",
1332
- attributes: {
1333
- x1: minX.toString(),
1334
- y1: y.toString(),
1335
- x2: maxX.toString(),
1336
- y2: y.toString(),
1337
- stroke: colorMap.schematic.grid,
1338
- "stroke-width": "0.01",
1339
- "stroke-opacity": "0.5"
1340
- }
1341
- });
1342
- }
1343
- svgChildren.push({
1344
- name: "g",
1345
- type: "element",
1346
- attributes: { class: "grid" },
1347
- children: gridLines
1348
- });
1576
+ const gridConfig = typeof options.grid === "object" ? options.grid : {};
1577
+ svgChildren.push(drawSchematicGrid({ bounds, transform, ...gridConfig }));
1349
1578
  }
1350
1579
  if (options?.labeledPoints) {
1351
- const labeledPointsGroup = [];
1352
- for (const point of options.labeledPoints) {
1353
- labeledPointsGroup.push({
1354
- name: "path",
1355
- type: "element",
1356
- attributes: {
1357
- d: `M${point.x - 0.1},${point.y - 0.1} L${point.x + 0.1},${point.y + 0.1} M${point.x - 0.1},${point.y + 0.1} L${point.x + 0.1},${point.y - 0.1}`,
1358
- stroke: colorMap.schematic.grid,
1359
- "stroke-width": "0.02",
1360
- "stroke-opacity": "0.7"
1361
- }
1362
- });
1363
- labeledPointsGroup.push({
1364
- name: "text",
1365
- type: "element",
1366
- attributes: {
1367
- x: (point.x + 0.15).toString(),
1368
- y: (point.y - 0.15).toString(),
1369
- fill: colorMap.schematic.grid,
1370
- "font-size": "0.15",
1371
- "fill-opacity": "0.7"
1372
- },
1373
- children: [{
1374
- type: "text",
1375
- value: point.label || `(${point.x},${point.y})`,
1376
- name: "",
1377
- attributes: {},
1378
- children: []
1379
- }]
1380
- });
1381
- }
1382
- svgChildren.push({
1383
- name: "g",
1384
- type: "element",
1385
- attributes: { class: "labeled-points" },
1386
- children: labeledPointsGroup
1387
- });
1388
- }
1389
- for (const debugObj of soup.filter(
1390
- (item) => item.type === "schematic_debug_object"
1391
- )) {
1392
- const svg = createSvgObjectsFromSchDebugObject(debugObj);
1393
- svgChildren.push(...svg);
1394
- }
1395
- const componentMap = /* @__PURE__ */ new Map();
1396
- for (const component of soup.filter(
1397
- (item) => item.type === "schematic_component"
1398
- )) {
1399
- const flippedCenter = {
1400
- x: component.center.x,
1401
- y: flipY(component.center.y)
1402
- };
1403
- const svg = createSchematicComponent(
1404
- flippedCenter,
1405
- component.size,
1406
- component.rotation || 0,
1407
- component.symbol_name,
1408
- component.port_labels,
1409
- component.source_component_id,
1410
- component.schematic_component_id,
1411
- soup
1580
+ svgChildren.push(
1581
+ drawSchematicLabeledPoints({
1582
+ points: options.labeledPoints,
1583
+ transform
1584
+ })
1412
1585
  );
1413
- svgChildren.push(svg);
1414
- componentMap.set(component.schematic_component_id, component);
1415
1586
  }
1416
- for (const trace of soup.filter((item) => item.type === "schematic_trace")) {
1417
- const svg = createSchematicTrace(trace, flipY, portPositions);
1418
- if (svg) svgChildren.push(svg);
1587
+ const schDebugObjectSvgs = [];
1588
+ const schComponentSvgs = [];
1589
+ const schTraceSvgs = [];
1590
+ for (const elm of circuitJson) {
1591
+ if (elm.type === "schematic_debug_object") {
1592
+ schDebugObjectSvgs.push(...createSvgObjectsFromSchDebugObject(elm));
1593
+ } else if (elm.type === "schematic_component") {
1594
+ schComponentSvgs.push(
1595
+ ...createSchematicComponent({
1596
+ component: {
1597
+ ...elm,
1598
+ center: { x: elm.center.x, y: flipY(elm.center.y) }
1599
+ },
1600
+ transform,
1601
+ // Add the missing transform property
1602
+ circuitJson
1603
+ })
1604
+ );
1605
+ } else if (elm.type === "schematic_trace") {
1606
+ schTraceSvgs.push(...createSchematicTrace(elm, flipY, portPositions));
1607
+ }
1419
1608
  }
1420
- const viewBoxPadding = 1;
1421
- const width = maxX - minX + 2 * padding;
1422
- const viewBox = `${minX - padding} ${minY - padding} ${width} ${height + 2 * padding}`;
1609
+ svgChildren.push(...schDebugObjectSvgs, ...schComponentSvgs, ...schTraceSvgs);
1423
1610
  const svgObject = {
1424
1611
  name: "svg",
1425
1612
  type: "element",
1426
1613
  attributes: {
1427
1614
  xmlns: "http://www.w3.org/2000/svg",
1428
1615
  viewBox,
1429
- width: options?.width ?? "1200",
1430
- height: options?.height ?? "600",
1616
+ width: (options?.width ?? 1200).toString(),
1617
+ height: (options?.height ?? 600).toString(),
1431
1618
  style: `background-color: ${colorMap.schematic.background}`
1432
1619
  },
1433
1620
  children: [
@@ -1446,77 +1633,27 @@ function convertCircuitJsonToSchematicSvg(soup, options) {
1446
1633
  .pin-number { font-size: 0.15px; fill: ${colorMap.schematic.pin_number}; }
1447
1634
  .port-label { fill: ${colorMap.schematic.reference}; }
1448
1635
  .component-name { font-size: 0.25px; fill: ${colorMap.schematic.reference}; }
1449
- `
1636
+ `,
1637
+ name: "",
1638
+ attributes: {},
1639
+ children: []
1450
1640
  }
1451
- ]
1641
+ ],
1642
+ value: "",
1643
+ attributes: {}
1452
1644
  },
1453
1645
  ...svgChildren
1454
- ]
1646
+ ],
1647
+ value: ""
1455
1648
  };
1456
1649
  return stringify2({
1457
- value: "",
1458
1650
  ...svgObject,
1459
1651
  attributes: {
1460
1652
  ...svgObject.attributes,
1461
- width: svgObject.attributes.width.toString(),
1462
- height: svgObject.attributes.height.toString()
1653
+ width: svgObject.attributes.width?.toString(),
1654
+ height: svgObject.attributes.height?.toString()
1463
1655
  }
1464
1656
  });
1465
- function createSchematicTrace(trace, flipY2, portPositions2) {
1466
- const edges = trace.edges;
1467
- if (edges.length === 0) return null;
1468
- let path = "";
1469
- edges.forEach((edge, index) => {
1470
- const fromPoint = edge.from.ti !== void 0 ? portPositions2.get(edge.from.ti) : edge.from;
1471
- const toPoint = edge.to.ti !== void 0 ? portPositions2.get(edge.to.ti) : edge.to;
1472
- if (!fromPoint || !toPoint) {
1473
- return;
1474
- }
1475
- const fromCoord = `${fromPoint.x - 0.15} ${flipY2(fromPoint.y)}`;
1476
- const toCoord = `${toPoint.x + 0.15} ${flipY2(toPoint.y)}`;
1477
- if (index === 0) {
1478
- path += `M ${fromCoord} L ${toCoord}`;
1479
- } else {
1480
- path += ` L ${toCoord}`;
1481
- }
1482
- });
1483
- if (trace.to_schematic_port_id) {
1484
- const finalPort = portPositions2.get(trace.to_schematic_port_id);
1485
- if (finalPort) {
1486
- const lastFromPoint = path.split("M")[1]?.split("L")[0];
1487
- const lastEdge = edges[edges.length - 1];
1488
- const lastPoint = lastEdge.to.ti !== void 0 ? portPositions2.get(lastEdge.to.ti) : lastEdge.to;
1489
- if (lastPoint.x !== finalPort.x || lastPoint.y !== finalPort.y) {
1490
- const finalCoord = `${finalPort.x} ${flipY2(finalPort.y)}`;
1491
- path += ` M ${lastFromPoint} L ${finalCoord}`;
1492
- }
1493
- }
1494
- }
1495
- return path ? {
1496
- name: "path",
1497
- type: "element",
1498
- attributes: {
1499
- class: "trace",
1500
- d: path
1501
- }
1502
- } : null;
1503
- }
1504
- function updateBounds(center, size, rotation) {
1505
- const corners = [
1506
- { x: -size.width / 2, y: -size.height / 2 },
1507
- { x: size.width / 2, y: -size.height / 2 },
1508
- { x: size.width / 2, y: size.height / 2 },
1509
- { x: -size.width / 2, y: size.height / 2 }
1510
- ];
1511
- for (const corner of corners) {
1512
- const rotatedX = corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x;
1513
- const rotatedY = corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y;
1514
- minX = Math.min(minX, rotatedX);
1515
- minY = Math.min(minY, rotatedY);
1516
- maxX = Math.max(maxX, rotatedX);
1517
- maxY = Math.max(maxY, rotatedY);
1518
- }
1519
- }
1520
1657
  }
1521
1658
  var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
1522
1659
  export {