broadfield-dev commited on
Commit
ee85fe1
·
verified ·
1 Parent(s): ad85069

Update static/canvas.js

Browse files
Files changed (1) hide show
  1. static/canvas.js +93 -14
static/canvas.js CHANGED
@@ -97,19 +97,60 @@ function clearCanvas() {
97
 
98
  // Create nodes and connections from parsed data
99
  function createNodesFromParsedData(parsedNodes, parsedConnections) {
100
- const scopePositions = {}; // Track x-position per scope
 
 
 
 
 
 
101
  parsedNodes.forEach(nodeData => {
102
- // Fallback for parent_path to prevent undefined error
103
- const parentPath = nodeData.parent_path || 'global';
104
- const scope = parentPath.split(' -> ')[0] || 'global';
105
- if (!scopePositions[scope]) {
106
- scopePositions[scope] = { x: 50, count: 0 };
 
 
107
  }
108
- // Stack left to right: increment x based on level and scope
 
 
 
 
109
  const level = nodeData.level || 0;
110
- const x = 50 + level * 150 + scopePositions[scope].count * 200;
111
- const y = scopePositions[scope].count * 80 + 50; // Slight y offset for readability
112
- scopePositions[scope].count += 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
  const node = createNode(
115
  x,
@@ -126,6 +167,7 @@ function createNodesFromParsedData(parsedNodes, parsedConnections) {
126
  nodes.push(node);
127
  layer.add(node);
128
  });
 
129
  layer.draw();
130
  autoConnect();
131
  saveNodes();
@@ -441,7 +483,7 @@ function autoConnect() {
441
 
442
  const sortedNodes = [...nodes].sort((a, b) => {
443
  if (a.data.level !== b.data.level) return a.data.level - b.data.level;
444
- return a.data.x - b.data.x;
445
  });
446
 
447
  const hierarchy = {};
@@ -539,7 +581,7 @@ function updateProgram() {
539
  function reconstructProgram() {
540
  const sortedNodes = [...nodes].sort((a, b) => {
541
  if (a.data.level !== b.data.level) return a.data.level - b.data.level;
542
- return a.data.x - b.data.x;
543
  });
544
 
545
  let program = '';
@@ -556,8 +598,8 @@ function reconstructProgram() {
556
  // Add a manual node
557
  function addNode() {
558
  const node = createNode(
559
- Math.random() * (stage.width() - 100),
560
- Math.random() * (stage.height() - 100),
561
  'Function',
562
  'function',
563
  ['in1'],
@@ -573,6 +615,43 @@ function addNode() {
573
  saveNodes();
574
  }
575
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  // Update spline connections when nodes move
577
  function updateConnections() {
578
  layer.find('Shape').forEach(shape => {
 
97
 
98
  // Create nodes and connections from parsed data
99
  function createNodesFromParsedData(parsedNodes, parsedConnections) {
100
+ const columns = {
101
+ imports: { x: 50, y: 50, count: 0 }, // Column for imports
102
+ global: { x: 250, y: 50, count: 0 }, // Column for global scope
103
+ functions: {} // Columns for functions
104
+ };
105
+
106
+ // First pass: Assign function nodes to columns
107
  parsedNodes.forEach(nodeData => {
108
+ if (nodeData.type === 'function') {
109
+ const functionId = nodeData.id || `Function_${Object.keys(columns.functions).length + 1}`;
110
+ columns.functions[functionId] = {
111
+ x: 450 + Object.keys(columns.functions).length * 200,
112
+ y: 50,
113
+ count: 0
114
+ };
115
  }
116
+ });
117
+
118
+ // Second pass: Create nodes with column-based positioning
119
+ parsedNodes.forEach(nodeData => {
120
+ const parentPath = nodeData.parent_path || 'global';
121
  const level = nodeData.level || 0;
122
+ let x, y;
123
+
124
+ if (nodeData.type === 'import') {
125
+ // Imports column
126
+ x = columns.imports.x;
127
+ y = columns.imports.y + columns.imports.count * 80;
128
+ columns.imports.count++;
129
+ } else if (nodeData.type === 'function') {
130
+ // Function column
131
+ const functionId = nodeData.id;
132
+ x = columns.functions[functionId].x;
133
+ y = columns.functions[functionId].y + columns.functions[functionId].count * 80;
134
+ columns.functions[functionId].count++;
135
+ } else if (parentPath !== 'global' && parentPath.includes('Function')) {
136
+ // Child of a function
137
+ const functionId = parentPath.split(' -> ')[0];
138
+ if (columns.functions[functionId]) {
139
+ x = columns.functions[functionId].x;
140
+ y = columns.functions[functionId].y + columns.functions[functionId].count * 80;
141
+ columns.functions[functionId].count++;
142
+ } else {
143
+ // Fallback to global if function not found
144
+ x = columns.global.x;
145
+ y = columns.global.y + columns.global.count * 80;
146
+ columns.global.count++;
147
+ }
148
+ } else {
149
+ // Global scope (non-import, non-function)
150
+ x = columns.global.x;
151
+ y = columns.global.y + columns.global.count * 80;
152
+ columns.global.count++;
153
+ }
154
 
155
  const node = createNode(
156
  x,
 
167
  nodes.push(node);
168
  layer.add(node);
169
  });
170
+
171
  layer.draw();
172
  autoConnect();
173
  saveNodes();
 
483
 
484
  const sortedNodes = [...nodes].sort((a, b) => {
485
  if (a.data.level !== b.data.level) return a.data.level - b.data.level;
486
+ return a.data.y - b.data.y; // Sort by y within columns
487
  });
488
 
489
  const hierarchy = {};
 
581
  function reconstructProgram() {
582
  const sortedNodes = [...nodes].sort((a, b) => {
583
  if (a.data.level !== b.data.level) return a.data.level - b.data.level;
584
+ return a.data.y - b.data.y; // Sort by y within columns
585
  });
586
 
587
  let program = '';
 
598
  // Add a manual node
599
  function addNode() {
600
  const node = createNode(
601
+ 250, // Add to global column
602
+ 50 + nodes.filter(n => n.data.parent_path === 'global').length * 80,
603
  'Function',
604
  'function',
605
  ['in1'],
 
615
  saveNodes();
616
  }
617
 
618
+ // Update spline connections when nodes move
619
+ function createSplineConnection(fromNode, fromPortId, toNode, toPortId) {
620
+ const fromPort = fromNode.data.outputs.find(p => p.id === fromPortId);
621
+ const toPort = toNode.data.inputs.find(p => p.id === toPortId);
622
+ if (!fromPort || !toPort) return;
623
+
624
+ const startX = fromNode.x() + fromPort.circle.x();
625
+ const startY = fromNode.y() + fromPort.circle.y();
626
+ const endX = toNode.x() + toPort.circle.x();
627
+ const endY = toNode.y() + toPort.circle.y();
628
+
629
+ const control1X = startX + (endX - startX) / 3;
630
+ const control1Y = startY;
631
+ const control2X = startX + 2 * (endX - startX) / 3;
632
+ const control2Y = endY;
633
+
634
+ const spline = new Konva.Shape({
635
+ sceneFunc: function(context, shape) {
636
+ context.beginPath();
637
+ context.moveTo(startX, startY);
638
+ context.bezierCurveTo(control1X, control1Y, control2X, control2Y, endX, endY);
639
+ context.fillStrokeShape(shape);
640
+ },
641
+ stroke: 'black',
642
+ strokeWidth: 2
643
+ });
644
+
645
+ spline.data = {
646
+ fromNodeId: fromNode.data.id,
647
+ fromPortId: fromPortId,
648
+ toNodeId: toNode.data.id,
649
+ toPortId: toPortId
650
+ };
651
+ layer.add(spline);
652
+ layer.draw();
653
+ }
654
+
655
  // Update spline connections when nodes move
656
  function updateConnections() {
657
  layer.find('Shape').forEach(shape => {