-
Notifications
You must be signed in to change notification settings - Fork 6
automatic zoom to all components #325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
5ab6d78
5a058dd
78fa0ec
c1fde63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| /*jshint esversion: 8 */ | ||
| /*jshint sub:true*/ | ||
|
|
||
| // Constants | ||
| const ASSET_TYPE_NAME = 'asset_type_name'; | ||
| const BUS = "bus"; | ||
|
|
@@ -16,7 +19,7 @@ if(copCollapseDOM){ | |
| if(tHighDOM){tHighDOM.dispatchEvent(new Event('change'));} | ||
| tLowDOM = guiModalDOM.querySelector('input[name="temperature_low_scalar"]'); | ||
| if(tLowDOM){tLowDOM.dispatchEvent(new Event('change'));} | ||
| }) | ||
| }); | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -62,9 +65,9 @@ editor.on('connectionCreated', function (connection) { | |
| var nodeOut = editor.getNodeFromId(connection['output_id']); | ||
| if ((nodeIn['name'] !== BUS && nodeOut['name'] !== BUS) || (nodeIn['name'] === BUS && nodeOut['name'] === BUS)) { | ||
| editor.removeSingleConnection(connection['output_id'], connection['input_id'], connection['output_class'], connection['input_class']); | ||
| Swal.fire('Unexpected Connection', 'Please connect assets to each other\n only through a bus node. Interconnecting busses is also not allowed.', 'error') | ||
| Swal.fire('Unexpected Connection', 'Please connect assets to each other\n only through a bus node. Interconnecting busses is also not allowed.', 'error'); | ||
| } | ||
| }) | ||
| }); | ||
|
|
||
| // might be redundant | ||
| editor.on('nodeCreated', function (nodeID) { | ||
|
|
@@ -86,20 +89,20 @@ editor.on('nodeCreated', function (nodeID) { | |
| // nodeIdInstalledCapInput.closest("#FormGroup").querySelector("input[name='age_installed']").readOnly = true; | ||
| // } | ||
| // endregion | ||
| }) | ||
| }); | ||
|
|
||
| editor.on('nodeRemoved', function (nodeID) { | ||
| // remove nodeID from nodesToDB | ||
| nodesToDB.delete('node-'+nodeID); | ||
| }) | ||
| }); | ||
|
|
||
|
|
||
| async function addNodeToDrawFlow(name, pos_x, pos_y, nodeInputs = 1, nodeOutputs = 1, nodeData = {}) { | ||
| if (editor.editor_mode === 'fixed') | ||
| return false; | ||
| 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); | ||
| } | ||
|
|
||
| // TODO potentially remove this function | ||
|
|
@@ -147,7 +150,7 @@ function getInputOutputMapping(nodeId){ | |
| guiModalDOM.querySelector('form .modal-addendum').innerHTML = formContent; | ||
| //make this invisible then | ||
| }, | ||
| }) | ||
| }); | ||
| } | ||
|
|
||
| // function to compute the COP of a heat pump linked with the button of id="btn-computeCOP" in templates/scenario//scenario_step2.html | ||
|
|
@@ -158,12 +161,12 @@ function getInputOutputMapping(nodeId){ | |
| const topologyNodeId = guiModalDOM.getAttribute("data-node-topo-id"); // e.g. 'node-2' | ||
|
|
||
| const copForm = event.target.closest('.modal-content').querySelector('#copForm'); | ||
| console.log(assetForm) | ||
| console.log(assetForm); | ||
| const formData = new FormData(copForm); | ||
|
|
||
| // copPostUrl is defined in scenario_step2.html | ||
| const postUrl = copPostUrl + assetTypeName | ||
| + (nodesToDB.has(topologyNodeId) ? "/" + nodesToDB.get(topologyNodeId).uid : ""); | ||
| const postUrl = copPostUrl + assetTypeName + | ||
| (nodesToDB.has(topologyNodeId) ? "/" + nodesToDB.get(topologyNodeId).uid : ""); | ||
|
|
||
| // send the form of the asset to be saved in database (projects/views.py::asset_cops_create_or_update) | ||
| $.ajax({ | ||
|
|
@@ -187,7 +190,7 @@ function getInputOutputMapping(nodeId){ | |
| } | ||
| copDOM = guiModalDOM.querySelector('input[name="copId"]'); | ||
| if(copDOM){ | ||
| copDOM.value = jsonRes.cop_id | ||
| copDOM.value = jsonRes.cop_id; | ||
| } | ||
|
|
||
| } else { | ||
|
|
@@ -198,7 +201,7 @@ function getInputOutputMapping(nodeId){ | |
| }, | ||
| error: function (err) { | ||
| guiModalDOM.querySelector('form .modal-body').innerHTML = err.responseJSON.form_html;}, //err => {alert("Modal form JS Error: " + err);console.log(err);} | ||
| }) | ||
| }); | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -235,15 +238,15 @@ const dblClick = (e) => { | |
| guiModalDOM.setAttribute("data-node-df-id", topologyNodeId.split("-").pop()); | ||
| editor.editor_mode = "fixed"; | ||
|
|
||
| updateInputTimeseries() | ||
| updateInputTimeseries(); | ||
|
|
||
| guiModal.show(); | ||
| if(copCollapseDOM){ | ||
| copCollapse.hide(); | ||
| } | ||
| $('[data-bs-toggle="tooltip"]').tooltip() | ||
| $('[data-bs-toggle="tooltip"]').tooltip(); | ||
| }, | ||
| }) | ||
| }); | ||
| } | ||
| }; | ||
| // endregion | ||
|
|
@@ -265,15 +268,15 @@ const submitForm = (e) => { | |
| const formData = new FormData(assetForm); | ||
|
|
||
| // add the XY position of the node to the form data | ||
| const nodePosX = editor.drawflow.drawflow.Home.data[drawflowNodeId].pos_x | ||
| const nodePosY = editor.drawflow.drawflow.Home.data[drawflowNodeId].pos_y | ||
| const nodePosX = editor.drawflow.drawflow.Home.data[drawflowNodeId].pos_x; | ||
| const nodePosY = editor.drawflow.drawflow.Home.data[drawflowNodeId].pos_y; | ||
| formData.set('pos_x', nodePosX); | ||
| formData.set('pos_y', nodePosY); | ||
|
|
||
| // if the asset is a bus, add the input and output ports to the form data | ||
| if (assetTypeName === BUS) { | ||
| const nodeInputs = Object.keys(editor.drawflow.drawflow.Home.data[drawflowNodeId].inputs).length | ||
| const nodeOutputs = Object.keys(editor.drawflow.drawflow.Home.data[drawflowNodeId].outputs).length | ||
| const nodeInputs = Object.keys(editor.drawflow.drawflow.Home.data[drawflowNodeId].inputs).length; | ||
| const nodeOutputs = Object.keys(editor.drawflow.drawflow.Home.data[drawflowNodeId].outputs).length; | ||
| formData.set('input_ports', nodeInputs); | ||
| formData.set('output_ports', nodeOutputs); | ||
| } | ||
|
|
@@ -285,8 +288,8 @@ const submitForm = (e) => { | |
| } | ||
|
|
||
| // formPostUrl is defined in scenario_step2.html | ||
| const postUrl = formPostUrl + assetTypeName | ||
| + (nodesToDB.has(topologyNodeId) ? "/" + nodesToDB.get(topologyNodeId).uid : ""); | ||
| const postUrl = formPostUrl + assetTypeName + | ||
| (nodesToDB.has(topologyNodeId) ? "/" + nodesToDB.get(topologyNodeId).uid : ""); | ||
|
|
||
| // send the form of the asset to be saved in database (projects/views.py::asset_create_or_update) | ||
| $.ajax({ | ||
|
|
@@ -319,8 +322,8 @@ const submitForm = (e) => { | |
| }, | ||
| error: function (err) { | ||
| guiModalDOM.querySelector('form .modal-body').innerHTML = err.responseJSON.form_html;}, //err => {alert("Modal form JS Error: " + err);console.log(err);} | ||
| }) | ||
| } | ||
| }); | ||
| }; | ||
|
|
||
|
|
||
|
|
||
|
|
@@ -341,43 +344,43 @@ $("#guiModal").on('shown.bs.modal', function (event) { | |
| // look only for the form with the provided class to be extra safe | ||
| document.querySelectorAll("input[name$='_scalar']").forEach(node => { node.dispatchEvent(evt); }); | ||
|
|
||
| }) | ||
| }); | ||
|
|
||
| /* Triggered before the modal opens */ | ||
| $("#guiModal").on('show.bs.modal', function (event) { | ||
| var modal = $(event.target) | ||
| var modal = $(event.target); | ||
| // rename the node on the fly (to avoid the need of refreshing the page) | ||
| const nodeName = guiModalDOM.querySelector('input[df-name]'); | ||
| if(nodeName){ | ||
| modal.find('.modal-title').text(nodeName.value.replaceAll("_", " ")); | ||
| } | ||
| }) | ||
| }); | ||
|
|
||
| /* Triggered before the modal hides */ | ||
| $("#guiModal").on('hide.bs.modal', function (event) { | ||
| // reset the modal form to empty | ||
| guiModalDOM.querySelector('form .modal-body').innerHTML = ""; | ||
| editor.editor_mode = "edit"; | ||
| }) | ||
| }); | ||
|
|
||
|
|
||
| /* 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 = {}) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is important |
||
|
|
||
| // automate the naming of assets to avoid name duplicates | ||
| const editorData = editor.export().drawflow.Home.data; | ||
| const node_list = Object.values(editorData); | ||
| const node_classes = node_list.map(obj => obj.class); | ||
| let existing_items = 0; | ||
| node_classes.map(name => {if(name.includes(nodeName)){++existing_items}}); | ||
| node_classes.map(name => {if(name.includes(nodeName)){++existing_items;}}); | ||
|
|
||
| let shownName; | ||
| if(typeof nodeData.name === "undefined"){ | ||
| if(existing_items == 0){ | ||
| shownName = nodeName + "-0" | ||
| shownName = nodeName + "-0"; | ||
| } | ||
| else{ | ||
| shownName = nodeName + "-" + existing_items | ||
| shownName = nodeName + "-" + existing_items; | ||
| } | ||
| nodeData.name = shownName; | ||
| } | ||
|
|
@@ -406,13 +409,13 @@ async function createNodeObject(nodeName, connectionInputs = 1, connectionOutput | |
| /* Html of asset modification is provided in grid_model_topology.js:createNodeObject function */ | ||
| const addBusses = async (data) => | ||
| await Promise.all(data.map(async nodeData => { | ||
| const result = await createNodeObject(nodeData.name, nodeData.input_ports, nodeData.output_ports, nodeData.data, nodeData.pos_x, nodeData.pos_y); | ||
| 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); | ||
|
Comment on lines
+412
to
+418
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is important |
||
| nodesToDB.set(`node-${result.editorNodeId}`, {uid:nodeData.data.unique_id, assetTypeName: nodeData.name }); | ||
| })); | ||
|
|
||
|
|
@@ -422,5 +425,42 @@ const addLinks = async (data) => data.map(async linkData => { | |
| const assetNodeId = [...nodesToDB.entries()].filter(([key,val])=>val.uid===linkData.asset_id).map(([k,v])=>k)[0].split("-").pop(); | ||
| (linkData.flow_direction === "B2A") ? | ||
| editor.addConnection(busNodeId, assetNodeId, linkData.bus_connection_port, 'input_1') | ||
| : editor.addConnection(assetNodeId, busNodeId, 'output_1', linkData.bus_connection_port); | ||
| : editor.addConnection(assetNodeId, busNodeId, 'output_1', linkData.bus_connection_port); // jshint ignore:line | ||
| }); | ||
|
|
||
|
|
||
| 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})`; | ||
|
|
||
|
Comment on lines
+430
to
+465
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is important |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -167,6 +167,7 @@ <h3>{{ group_names|get_item:group_name|title }}</h3> | |
| const data = JSON.parse(`{{topology_data_list| escapejs }}`); | ||
| Promise.all([addBusses(data['busses']), addAssets(data['assets'])]) | ||
| .then(async () => addLinks(data['links'])) | ||
| .then(() => zoomToFit()) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The changes below are important |
||
| .catch(err=>Swal.fire('Grid Model Error', 'Could not retrieve grid nodes.', 'error')); | ||
| }); | ||
| </script> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is important