Skip to content
Open
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
229 changes: 152 additions & 77 deletions src/drawflow.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default class Drawflow {
Export default class Drawflow {
constructor(container, render = null, parent = null) {
this.events = {};
this.container = container;
Expand Down Expand Up @@ -241,6 +241,20 @@ export default class Drawflow {
}
this.drawConnection(e.target);
break;
case 'input':
this.connection = true;
if(this.node_selected != null) {
this.node_selected.classList.remove("selected");
this.node_selected = null;
this.dispatch('nodeUnselected', true);
}
if(this.connection_selected != null) {
this.connection_selected.classList.remove("selected");
this.removeReouteConnectionSelected();
this.connection_selected = null;
}
this.drawConnection(e.target);
break;
case 'parent-drawflow':
if(this.node_selected != null) {
this.node_selected.classList.remove("selected");
Expand Down Expand Up @@ -428,96 +442,122 @@ export default class Drawflow {
var e_pos_y = e.clientY;
var ele_last = e.target;
}

if(this.drag) {
if(this.pos_x_start != e_pos_x || this.pos_y_start != e_pos_y) {
this.dispatch('nodeMoved', this.ele_selected.id.slice(5));
}
}

if(this.drag_point) {
this.ele_selected.classList.remove("selected");
if(this.pos_x_start != e_pos_x || this.pos_y_start != e_pos_y) {
this.dispatch('rerouteMoved', this.ele_selected.parentElement.classList[2].slice(14));
}
if(this.pos_x_start != e_pos_x || this.pos_y_start != e_pos_y) {
this.dispatch('rerouteMoved', this.ele_selected.parentElement.classList[2].slice(14));
}
}

if(this.editor_selected) {
this.canvas_x = this.canvas_x + (-(this.pos_x - e_pos_x));
this.canvas_y = this.canvas_y + (-(this.pos_y - e_pos_y));
this.editor_selected = false;
}

if(this.connection === true) {
if(ele_last.classList[0] === 'input' || (this.force_first_input && (ele_last.closest(".drawflow_content_node") != null || ele_last.classList[0] === 'drawflow-node'))) {

if(this.force_first_input && (ele_last.closest(".drawflow_content_node") != null || ele_last.classList[0] === 'drawflow-node')) {
if(ele_last.closest(".drawflow_content_node") != null) {
var input_id = ele_last.closest(".drawflow_content_node").parentElement.id;
const targetIsOutput = ele_last.classList[0] === 'output';
const targetIsInput = ele_last.classList[0] === 'input';
const sourceIsInput = this.ele_selected.classList.contains('input');

if(targetIsInput || targetIsOutput || ele_last.closest(".drawflow_content_node") != null || ele_last.classList[0] === 'drawflow-node') {
let input_id, input_class, output_id, output_class;

if(sourceIsInput && targetIsOutput) {
// Input to Output connection
input_id = this.ele_selected.parentElement.parentElement.id;
input_class = this.ele_selected.classList[1];
output_id = ele_last.parentElement.parentElement.id;
output_class = ele_last.classList[1];
} else if(!sourceIsInput && (targetIsInput || ele_last.closest(".drawflow_content_node"))) {
// Output to Input connection
input_id = ele_last.closest(".drawflow_content_node") ?
ele_last.closest(".drawflow_content_node").parentElement.id :
ele_last.parentElement.parentElement.id;
input_class = targetIsInput ? ele_last.classList[1] : "input_1";
output_id = this.ele_selected.parentElement.parentElement.id;
output_class = this.ele_selected.classList[1];
}

if(input_id && output_id && input_id !== output_id) {
// Validate connection doesn't already exist
const outputNode = this.drawflow.drawflow[this.module].data[output_id.slice(5)];
const inputNode = this.drawflow.drawflow[this.module].data[input_id.slice(5)];

let connectionExists = false;

if(outputNode && outputNode.outputs[output_class]) {
connectionExists = outputNode.outputs[output_class].connections.some(conn =>
conn.node === input_id.slice(5) && conn.output === input_class
);
}

if(!connectionExists && inputNode && inputNode.inputs[input_class]) {
connectionExists = inputNode.inputs[input_class].connections.some(conn =>
conn.node === output_id.slice(5) && conn.input === output_class
);
}

if(!connectionExists) {
this.connection_ele.classList.add("node_in_"+input_id);
this.connection_ele.classList.add("node_out_"+output_id);
this.connection_ele.classList.add(output_class);
this.connection_ele.classList.add(input_class);

this.drawflow.drawflow[this.module].data[output_id.slice(5)].outputs[output_class].connections.push({
"node": input_id.slice(5),
"output": input_class
});

this.drawflow.drawflow[this.module].data[input_id.slice(5)].inputs[input_class].connections.push({
"node": output_id.slice(5),
"input": output_class
});

this.updateConnectionNodes('node-'+output_id.slice(5));
this.updateConnectionNodes('node-'+input_id.slice(5));

this.dispatch('connectionCreated', {
output_id: output_id.slice(5),
input_id: input_id.slice(5),
output_class: output_class,
input_class: input_class
});
} else {
var input_id = ele_last.id;
this.dispatch('connectionCancel', true);
this.connection_ele.remove();
}
if(Object.keys(this.getNodeFromId(input_id.slice(5)).inputs).length === 0) {
var input_class = false;
} else {
var input_class = "input_1";
}


} else {
// Fix connection;
var input_id = ele_last.parentElement.parentElement.id;
var input_class = ele_last.classList[1];
}
var output_id = this.ele_selected.parentElement.parentElement.id;
var output_class = this.ele_selected.classList[1];

if(output_id !== input_id && input_class !== false) {

if(this.container.querySelectorAll('.connection.node_in_'+input_id+'.node_out_'+output_id+'.'+output_class+'.'+input_class).length === 0) {
// Conection no exist save connection

this.connection_ele.classList.add("node_in_"+input_id);
this.connection_ele.classList.add("node_out_"+output_id);
this.connection_ele.classList.add(output_class);
this.connection_ele.classList.add(input_class);
var id_input = input_id.slice(5);
var id_output = output_id.slice(5);

this.drawflow.drawflow[this.module].data[id_output].outputs[output_class].connections.push( {"node": id_input, "output": input_class});
this.drawflow.drawflow[this.module].data[id_input].inputs[input_class].connections.push( {"node": id_output, "input": output_class});
this.updateConnectionNodes('node-'+id_output);
this.updateConnectionNodes('node-'+id_input);
this.dispatch('connectionCreated', { output_id: id_output, input_id: id_input, output_class: output_class, input_class: input_class});

} else {
this.dispatch('connectionCancel', true);
this.connection_ele.remove();
}

this.connection_ele = null;
} else {
// Connection exists Remove Connection;
this.dispatch('connectionCancel', true);
this.connection_ele.remove();
this.connection_ele = null;
}

} else {
// Remove Connection;
this.dispatch('connectionCancel', true);
this.connection_ele.remove();
this.connection_ele = null;
}
this.connection_ele = null;
}

this.drag = false;
this.drag_point = false;
this.connection = false;
this.ele_selected = null;
this.editor_selected = false;

this.dispatch('mouseUp', e);
}





contextmenu(e) {
this.dispatch('contextmenu', e);
e.preventDefault();
Expand Down Expand Up @@ -662,15 +702,22 @@ export default class Drawflow {
var path = document.createElementNS('http://www.w3.org/2000/svg',"path");
path.classList.add("main-path");
path.setAttributeNS(null, 'd', '');
// path.innerHTML = 'a';
connection.classList.add("connection");
connection.appendChild(path);
this.precanvas.appendChild(connection);
var id_output = ele.parentElement.parentElement.id.slice(5);
var output_class = ele.classList[1];
this.dispatch('connectionStart', { output_id: id_output, output_class: output_class });


if(ele.classList.contains('input')) {
var id_input = ele.parentElement.parentElement.id.slice(5);
var input_class = ele.classList[1];
this.dispatch('connectionStart', { input_id: id_input, input_class: input_class });
} else {
var id_output = ele.parentElement.parentElement.id.slice(5);
var output_class = ele.classList[1];
this.dispatch('connectionStart', { output_id: id_output, output_class: output_class });
}
}



updateConnection(eX, eY) {
const precanvas = this.precanvas;
Expand All @@ -680,18 +727,27 @@ export default class Drawflow {
let precanvasHeightZoom = precanvas.clientHeight / (precanvas.clientHeight * zoom);
precanvasHeightZoom = precanvasHeightZoom || 0;
var path = this.connection_ele.children[0];

var line_x = this.ele_selected.offsetWidth/2 + (this.ele_selected.getBoundingClientRect().x - precanvas.getBoundingClientRect().x ) * precanvasWitdhZoom;
var line_y = this.ele_selected.offsetHeight/2 + (this.ele_selected.getBoundingClientRect().y - precanvas.getBoundingClientRect().y ) * precanvasHeightZoom;

var x = eX * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) - (this.precanvas.getBoundingClientRect().x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) );
var y = eY * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) - (this.precanvas.getBoundingClientRect().y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) );

var x = eX * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) - (this.precanvas.getBoundingClientRect().x * ( this.precanvas.clientWidth / (this.precanvas.clientWidth * this.zoom)) );
var y = eY * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) - (this.precanvas.getBoundingClientRect().y * ( this.precanvas.clientHeight / (this.precanvas.clientHeight * this.zoom)) );
var curvature = this.curvature;
var lineCurve = this.createCurvature(line_x, line_y, x, y, curvature, 'openclose');
var lineCurve;

if(this.ele_selected.classList.contains('input')) {
// Invert curve for input-initiated connections
lineCurve = this.createCurvature(x, y, line_x, line_y, curvature, 'close');
} else {
lineCurve = this.createCurvature(line_x, line_y, x, y, curvature, 'openclose');
}

path.setAttributeNS(null, 'd', lineCurve);

}



addConnection(id_output, id_input, output_class, input_class) {
var nodeOneModule = this.getModuleFromNodeId(id_output);
Expand All @@ -700,12 +756,25 @@ export default class Drawflow {

var dataNode = this.getNodeFromId(id_output);
var exist = false;
for(var checkOutput in dataNode.outputs[output_class].connections){
var connectionSearch = dataNode.outputs[output_class].connections[checkOutput]
for(var checkOutput in dataNode.outputs[output_class].connections) {
var connectionSearch = dataNode.outputs[output_class].connections[checkOutput];
if(connectionSearch.node == id_input && connectionSearch.output == input_class) {
exist = true;
break;
}
}
}

// Check input to output connections
if (!exist) {
var targetNode = this.getNodeFromId(id_input);
for(var checkInput in targetNode.inputs[input_class].connections) {
var connectionSearch = targetNode.inputs[input_class].connections[checkInput];
if(connectionSearch.node == id_output && connectionSearch.input == output_class) {
exist = true;
break;
}
}
}
// Check connection exist
if(exist === false) {
//Create Connection
Expand Down Expand Up @@ -1164,9 +1233,13 @@ export default class Drawflow {
}

getNodeFromId(id) {
var moduleName = this.getModuleFromNodeId(id)
return JSON.parse(JSON.stringify(this.drawflow.drawflow[moduleName].data[id]));
}
var moduleName = this.getModuleFromNodeId(id);
if (moduleName && this.drawflow.drawflow[moduleName] && this.drawflow.drawflow[moduleName].data[id]) {
return JSON.parse(JSON.stringify(this.drawflow.drawflow[moduleName].data[id]));
}
return null;
}

getNodesFromName(name) {
var nodes = [];
const editor = this.drawflow.drawflow
Expand Down Expand Up @@ -1951,3 +2024,5 @@ export default class Drawflow {
return uuid;
}
}
window.Drawflow = Drawflow;