Skip to content

automatic zoom to all components#325

Merged
Bachibouzouk merged 4 commits intomainfrom
fix/zoom_to_all_components
Jun 25, 2025
Merged

automatic zoom to all components#325
Bachibouzouk merged 4 commits intomainfrom
fix/zoom_to_all_components

Conversation

@josihoppe
Copy link
Copy Markdown

added function zoomToFit in grid_model_topology and trying to call it in scenario_step2.html

const data = JSON.parse(`{{topology_data_list| escapejs }}`);
Promise.all([addBusses(data['busses']), addAssets(data['assets'])])
.then(async () => addLinks(data['links']))
.then(() => zoomToFit())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josihoppe - You can comment the line next to this in order to see the traceback into the console:

downloadable font: Glyph bbox was incorrect (glyph ids 10 12 17 18 19) (font-family: "icomoon" style:normal weight:400 stretch:100 src index:1) source: http://127.0.0.1:8000/static/fonts/icomoon.ttf?xke5es
Uncaught (in promise) TypeError: canvas.getBoundingClientRect is not a function
    zoomToFit http://127.0.0.1:8000/static/js/grid_model_topology.js:438
    <anonymous> http://127.0.0.1:8000/en/project/41/scenario/67/edit/step/2:754
    promise callback* http://127.0.0.1:8000/en/project/41/scenario/67/edit/step/2:754
    jQuery 8
    <anonymous> https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js:6
    <anonymous> https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js:6
grid_model_topology.js:438:32

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes below are important

@josihoppe josihoppe marked this pull request as ready for review June 10, 2025 11:48
@josihoppe josihoppe requested a review from paulapreuss June 10, 2025 11:48
Copy link
Copy Markdown

@Bachibouzouk Bachibouzouk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it with a larger energy system and it seems that it is not well centered.

On another topic: I noticed this "transform" function applying to the style seem to be at the origin of the draggable zone of the canevas issue (#317) .

Maybe we could solve both issues at once?

Somehow when I zoom in and out again, I cannot reach the same zoom depth as if I just refresh the page. The Editor.Width seem to always be the same value. We should have a way to change it dynamically as well.

@Bachibouzouk
Copy link
Copy Markdown

@josihoppe -

Maybe the html structure is not correct, could you check it and try with this one?

<div id="drawflow" class="drawflow">             <!-- Your container -->
  <div class="parent-drawflow">                  <!-- For panning -->
    <div class="drawflow">                       <!-- The actual canvas -->
      <div id="node-1" class="drawflow-node">    <!-- Nodes -->
        <!-- Node content here -->
      </div>
      <!-- More nodes -->
    </div>
  </div>
</div>

@josihoppe
Copy link
Copy Markdown
Author

@josihoppe -

Maybe the html structure is not correct, could you check it and try with this one?

<div id="drawflow" class="drawflow">             <!-- Your container -->
  <div class="parent-drawflow">                  <!-- For panning -->
    <div class="drawflow">                       <!-- The actual canvas -->
      <div id="node-1" class="drawflow-node">    <!-- Nodes -->
        <!-- Node content here -->
      </div>
      <!-- More nodes -->
    </div>
  </div>
</div>

What do you mean by trying this structure? The structure should be created by editor.start() if I see that correctly and I didn't see if if is being changed at some point in the code?

@Bachibouzouk
Copy link
Copy Markdown

What do you mean by trying this structure?

I meant comparing it with the structure rendered within our DOM, it seemed to me that it was different, and thus could be a reason why we are facing problems with panning (not be able to drag the canevas anywhere on the page, like one can do in a miro board)

@josihoppe
Copy link
Copy Markdown
Author

What do you mean by trying this structure?

I meant comparing it with the structure rendered within our DOM, it seemed to me that it was different, and thus could be a reason why we are facing problems with panning (not be able to drag the canevas anywhere on the page, like one can do in a miro board)

A I see! I think the strutuce in the DOM looks correct, I compared it to the code of Drawflow and it seems to be rendered fine. From my research, I think that others also had a problem with panning. Like here: jerosoler/Drawflow#141 or here: jerosoler/Drawflow#199

@josihoppe
Copy link
Copy Markdown
Author

@Bachibouzouk I think I fixed the panning problem with this solution: jerosoler/Drawflow#199 . But I am struggling to get the big energy systems centered.

And I tried to recreate this

Somehow when I zoom in and out again, I cannot reach the same zoom depth as if I just refresh the page. The Editor.Width seem to always be the same value. We should have a way to change it dynamically as well.

But for me when Zooming with strg+mouse wheel it always zooms in +1/-1 increments. So it can indeed go back to the original Zoom level. (When I tested I did not move the canvas/did not change the translation)

@Bachibouzouk
Copy link
Copy Markdown

@Bachibouzouk I think I fixed the panning problem with this solution: jerosoler/Drawflow#199 . But I am struggling to get the big energy systems centered.

Great, I will find time to review tonight or tomorrow

But for me when Zooming with strg+mouse wheel it always zooms in +1/-1 increments. So it can indeed go back to the original Zoom level. (When I tested I did not move the canvas/did not change the translation)

Maybe now this will also be fixed for me, no need to worry more, I will try it and let you know

Copy link
Copy Markdown

@Bachibouzouk Bachibouzouk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works already better than before, I suggest we implement this and improve it further in subsequent PRs.

A conflict will happen with #337 as there the grid_model_topology.js get indented and suffled around. I suggest we merge this one first and struggle with conflicts in #337, I will highlight the lines which are not just js linting in this PR

Copy link
Copy Markdown

@Bachibouzouk Bachibouzouk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I marked the lines with the important code (other changes are just linting) to ease conflict resolution in #337

pos_x = pos_x * (editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)) - (editor.precanvas.getBoundingClientRect().x * (editor.precanvas.clientWidth / (editor.precanvas.clientWidth * editor.zoom)));
pos_y = pos_y * (editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)) - (editor.precanvas.getBoundingClientRect().y * (editor.precanvas.clientHeight / (editor.precanvas.clientHeight * editor.zoom)));
return createNodeObject(name, nodeInputs, nodeOutputs, nodeData, pos_x, pos_y);
return createNodeObject(name, pos_x, pos_y, nodeInputs, nodeOutputs, nodeData);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is important


/* Create node on the gui */
async function createNodeObject(nodeName, connectionInputs = 1, connectionOutputs = 1, nodeData = {}, pos_x, pos_y) {
async function createNodeObject(nodeName, pos_x, pos_y, connectionInputs = 1, connectionOutputs = 1, nodeData = {}) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is important

Comment on lines +412 to +418
const result = await createNodeObject(nodeData.name, nodeData.pos_x, nodeData.pos_y, nodeData.input_ports, nodeData.output_ports, nodeData.data);
nodesToDB.set(`node-${result.editorNodeId}`, {uid:nodeData.data.databaseId, assetTypeName: "bus" });
}));

const addAssets = async (data) =>
await Promise.all(data.map(async nodeData => {
const result = await createNodeObject(nodeData.name, 1, 1, nodeData.data, nodeData.pos_x, nodeData.pos_y);
const result = await createNodeObject(nodeData.name, nodeData.pos_x, nodeData.pos_y, 1, 1, nodeData.data);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is important

Comment on lines +430 to +465


function zoomToFit() {
const nodeWidth = 152;
const nodeHeight = 128;

const nodes = Object.values(editor.drawflow.drawflow.Home.data); // Array with all nodes

let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;

// get outer most node bounding box edges
nodes.forEach(node => {
minX = Math.min(minX, node.pos_x);
minY = Math.min(minY, node.pos_y);
maxX = Math.max(maxX, node.pos_x + nodeWidth);
maxY = Math.max(maxY, node.pos_y + nodeHeight);
});
const nodesWidth = maxX - minX;
const nodesHeight = maxY - minY;

// get space of editor
const editorElem = document.querySelector('.drawflow');
const editorWidth = editorElem.clientWidth;
const editorHeight = editorElem.clientHeight;

// calculate zoom
const zoomX = editorWidth / (nodesWidth + 2);
const zoomY = editorHeight / (nodesHeight + 2);
const zoom = Math.min(zoomX, zoomY, 1); // Maximal 1 (kein Hineinzoomen)
editor.zoom = zoom;

// center editor
const offsetX = (editorWidth - nodesWidth * zoom) / 2 - minX * zoom;
const offsetY = (editorHeight - nodesHeight * zoom) / 2 - minY * zoom;
editor.precanvas.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${zoom})`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is important

const data = JSON.parse(`{{topology_data_list| escapejs }}`);
Promise.all([addBusses(data['busses']), addAssets(data['assets'])])
.then(async () => addLinks(data['links']))
.then(() => zoomToFit())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes below are important

@Bachibouzouk Bachibouzouk merged commit ac33b54 into main Jun 25, 2025
4 checks passed
@Bachibouzouk Bachibouzouk deleted the fix/zoom_to_all_components branch June 25, 2025 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The energy system sould zoom out/in automatically so that all components are visible

2 participants