jerosoler / Drawflow

Simple flow library 🖥️🖱️
https://jerosoler.github.io/Drawflow/
MIT License
4.42k stars 714 forks source link

Verticle Connected Lines are not showing it will convert in horizontally after saving #806

Open AbhayUpadhyay96 opened 6 months ago

AbhayUpadhyay96 commented 6 months ago

Hi @jerosoler I am using this Library, and I am facing one issue in my node i have the input and output in both directions horizontally and vertically but when I try to connect a node Horizontally and save it shows right, and when I try to connect the node from the bottom and save it after saving its automatically joint from horizontal ports verticle I am unable to show after saving I have the 6 input and 6 output ports.

I have attached a sample picture for your reference.

verticle ports 1 Verticle ports

jerosoler commented 6 months ago

I understand that you have modified the lines with the function: createCurvature.

In the createCurvature function you will have to detect which lines are vertical and horizontal and create a curvature for each of them.

AbhayUpadhyay96 commented 6 months ago

Thanks for your quick support That is my createCurvture function that i am using

editor.createCurvature = function ( start_pos_x: any, start_pos_y: any, end_pos_x: any, end_pos_y: any, curvature_value: any, type: any ) { let angle = 15; const input_distance = 0; const fix_arrow_distance = 10; const min_x_distance = 45;

  const x = start_pos_x + input_distance;
  const y = start_pos_y;
  const end_x = end_pos_x - fix_arrow_distance;
  const end_y = end_pos_y;
  const center_x = (end_x - x) / 2 + x;
  const center_y = (end_y - y) / 2 + y;
  const distance_x = end_x - x;
  const distance_y = end_y - y;
  let minX = false;

  let line = '';

  if (distance_x <= min_x_distance) {
    minX = true;
  }

  if (end_y > y) {
    if (distance_y <= angle * 2) {
      angle = distance_y / 2;
    }
    if (minX) {
      if (distance_y <= angle * 4) {
        angle = distance_y / 4;
      }
      line += `
      M ${x} ${y} 
      L ${x + min_x_distance - angle} ${y} 
      A ${angle} ${angle} 1 0 1 ${x + min_x_distance} ${y + angle}
      L ${x + min_x_distance} ${center_y - angle}
      A ${angle} ${angle} 1 0 1 ${x + min_x_distance - angle} ${center_y}
      L ${end_x - min_x_distance} ${center_y}
      A ${angle} ${angle} 1 0 0 ${end_x - min_x_distance - angle} ${center_y + angle
        }
      L ${end_x - min_x_distance - angle} ${end_y - angle}
      A ${angle} ${angle} 1 0 0 ${end_x - min_x_distance} ${end_y}
      L ${end_x} ${end_y}
      `;
    } else {
      line += `
      M ${x} ${y} 
      L ${center_x - angle} ${y} 
      A ${angle} ${angle} 1 0 1 ${center_x} ${y + angle}
      L ${center_x} ${center_y} 
      L ${center_x} ${end_y - angle} 
      A ${angle} ${angle} 1 0 0 ${center_x + angle} ${end_y}
      L ${end_x} ${end_y}
      `;
    }
  } else {
    if (distance_y * -1 <= angle * 2) {
      angle = (distance_y * -1) / 2;
    }
    if (minX) {
      if (distance_y * -1 <= angle * 4) {
        angle = (distance_y * -1) / 4;
      }
      line += `
      M ${x} ${y} 
      L ${x + min_x_distance - angle} ${y} 
      A ${angle} ${angle} 1 0 0 ${x + min_x_distance} ${y - angle}
      L ${x + min_x_distance} ${center_y + angle}
      A ${angle} ${angle} 1 0 0 ${x + min_x_distance - angle} ${center_y}
      L ${end_x - min_x_distance} ${center_y}
      A ${angle} ${angle} 1 0 1 ${end_x - min_x_distance - angle} ${center_y - angle
        }
      L ${end_x - min_x_distance - angle} ${end_y + angle}
      A ${angle} ${angle} 1 0 1 ${end_x - min_x_distance} ${end_y}
      L ${end_x} ${end_y}
      `;
    } else {
      line += `
      M ${x} ${y} 
      L ${center_x - angle} ${y} 
      A ${angle} ${angle} 1 0 0 ${center_x} ${y - angle}
      L ${center_x} ${center_y} 
      L ${center_x} ${end_y + angle} 
      A ${angle} ${angle} 1 0 1 ${center_x + angle} ${end_y}
      L ${end_x} ${end_y}
      `;
    }
  }

  let arrow = `M ${end_x + 0.5} ${end_y + 0.5} L ${end_x - 10} ${end_y - 10
    }  M ${end_x + 0.5} ${end_y - 0.5} L ${end_x - 10} ${end_y + 10} `;

  switch (type) {
    case 'open':
      return line;
      break;
    case 'close':
      return line + arrow;
      break;
    case 'other':
      return line;
      break;
    default:
      return line + arrow;
  }
  return line + arrow;
};
jerosoler commented 6 months ago

I had not taken into account the issue of two directions.

The problem is that drawflow is only designed for one direction.

The problem with detecting input and output is that they have to have an address.

view this PR:

And issue:

And vertical lines:

AbhayUpadhyay96 commented 6 months ago

Hi @jerosoler its me again y doubt is suppose in a Node I have 2 input port and 2 output port and I connect a output port 2 to the input port 2 and save after save when i will load it will show me to connect to output port 1 to input port 1 but i was connect with different port

Below Method i am using to show the existing Node

getExistingNodes(id: any) { this.utilServices.startLoader(); this.globalApiServices.directusAPICall({}, 'get', constants.projectNode + ?filter[project_functional_flow_id]=${id}).subscribe({ next: (result: any) => { this.flowData = []; if (result?.data?.length > 0) { this.showRules = false

      for (let i = 0; i < result.data.length; i++) {// api to get the config.
        let indexData = result?.data[i]
        this.globalApiServices.directusAPICall({}, 'get', constants.workflow + `?filter={"QiFFNodeID":{"_in":[${indexData.project_node_id}]}}`).subscribe({
          next: (result: any) => {
            if(result && result?.data[0]){
              indexData.config = result?.data[0]?.FlowConfig?.length ? true : false;
            } else {
              indexData.config = false;
            }
          },
          error: (err: any) => {
            this.utilServices.stopLoader();
            this.globalServices.showNotification(`error`, `${this.globalServices.getMiscellaniousMessages()?.error}`,
              `${this.globalServices.getMiscellaniousMessages()?.errorWhileGettingNodeData}`)
          }
        })
      }
      // this.editor.addConnection(2, 1, 'output_1', 'input_1')
      setTimeout(()=>{
        for (let i = 0; i < result.data.length; i++) {
          let indexData2 = result?.data[i]
          let coordinates: any = {
            clientX: indexData2.xcoordinate,
            clientY: indexData2.ycoordinate
          }
          this.createNewNode(indexData2, coordinates, false);
        }
        for (let j = 0; j < result.data.length; j++) {
          let inputConnections: any[] = result.data[j].inputList
          if (inputConnections?.length > 0) {
            for (let connection of inputConnections) {
              // out,input,outputclass,inputclass
              let outputIndex: any = this.flowData.map((e: ProjectNode) => e.project_node_id).indexOf(connection)
              this.editor.addConnection(outputIndex + 1, j + 1, 'output_1', 'input_1')
            }
          }
        }
      },500) 
    }
    else {
      this.flowData = [];
      this.editor.clear();
      let drawId: any = document.getElementById("drawflow");
      drawId.innerHTML = '';
      this.editor.start();
    }
    this.utilServices.stopLoader();
    this.changesMade = false;
  },
  error: (err: any) => {
    this.utilServices.stopLoader();
    this.globalServices.showNotification(`error`, `${this.globalServices.getMiscellaniousMessages()?.error}`,
      `${this.globalServices.getMiscellaniousMessages()?.errorWhileGettingNodeData}`)
  }
})

}

and Below function i am using to create a new Node

this.editor.on("connectionCreated", function (info: any) { let getInputIndex: any = that.flowData.map(function (e: any) { return e.project_node_id; }).indexOf(that.editor.getNodeFromId(info.input_id).data.project_node_id) let getouputIndex: any = that.flowData.map(function (e: any) { return e.project_node_id; }).indexOf(that.editor.getNodeFromId(info.output_id).data.project_node_id) let uniqueIds: any = new Set(that.flowData[getInputIndex].inputList)

  uniqueIds.add(that.flowData[getouputIndex].project_node_id)
  that.flowData[getInputIndex].inputList = [...uniqueIds]
  that.changesMade = true
});
jerosoler commented 6 months ago

Why doesn't the editor load with the "editor.import(you_data)" method? This way you can see the json to import and look for problems.

I see in this line that it is always indicating output 1 and input 1.

 this.editor.addConnection(outputIndex + 1, j + 1, 'output_1', 'input_1')
AbhayUpadhyay96 commented 6 months ago

Thanks @jerosoler for your support but I am a little bit confused about how can we add or show which input port connects to which output port if we have multiple input and output ports. Can you give me one example?

Below I am adding one function by using this i am showing 6 input and 6 output port

nodeCommonCode(temp: any, positions: any, flag: any, config: any, newNodes: any){ this.editor && this.editor.addNode('test', 6, 6, positions?.clientX, flag ? positions.clientY - 200 : positions.clientY, temp?.config ? 'node-main border-green':'node-main', temp, flag ? newNodes : this.getNodetemplates.regularNodeExpandTemplate(temp) ) }

It will be grate help for me.

AbhayUpadhyay96 commented 5 months ago

Hi @jerosoler It's me Again I have solved my previous problem because for your support only now I have one problem in the Editor.createCurvature function I want to change the type of Arrow suppose

I have 6 inputs and output and I want if a line connects to the verticle ports top then the arrow should be the (DOWNWARDS ARROW) and the line is connect to the left side of port then it should be (RIGHTWARDS ARROW)

I am attaching my Create Curvature Function Please have a look once I have try By my own self and i am able create Arrow on dynamic shapes ports

editor.createCurvature = function ( start_pos_x: any, start_pos_y: any, end_pos_x: any, end_pos_y: any, curvature_value: any, type: any ) { let angle = 1; const input_distance = -5; const fix_arrow_distance = 2; const min_x_distance = 0;

  const x = start_pos_x + input_distance;
  const y = start_pos_y;
  const end_x = end_pos_x - fix_arrow_distance;
  const end_y = end_pos_y;
  const center_x = (end_x - x) / 2 + x;
  const center_y = (end_y - y) / 2 + y;
  const distance_x = end_x - x;
  const distance_y = end_y - y;
  let minX = false;

  let line = '';

  if (distance_x <= min_x_distance) {
    minX = true;
  }

  if (end_y > y) {
    if (distance_y <= angle * 2) {
      angle = distance_y / 2;
    }
    if (minX) {
      if (distance_y <= angle * 4) {
        angle = distance_y / 4;
      }
      line += `
      M ${x} ${y} 
      L ${x + min_x_distance - angle} ${y} 
      A ${angle} ${angle} 1 0 1 ${x + min_x_distance} ${y + angle}
      L ${x + min_x_distance} ${center_y - angle}
      A ${angle} ${angle} 1 0 1 ${x + min_x_distance - angle} ${center_y}
      L ${end_x - min_x_distance} ${center_y}
      A ${angle} ${angle} 1 0 0 ${end_x - min_x_distance - angle} ${center_y + angle
        }
      L ${end_x - min_x_distance - angle} ${end_y - angle}
      A ${angle} ${angle} 1 0 0 ${end_x - min_x_distance} ${end_y}
      L ${end_x} ${end_y}
      `;
    } else {
      line += `
      M ${x} ${y} 
      L ${center_x - angle} ${y} 
      A ${angle} ${angle} 1 0 1 ${center_x} ${y + angle}
      L ${center_x} ${center_y} 
      L ${center_x} ${end_y - angle} 
      A ${angle} ${angle} 1 0 0 ${center_x + angle} ${end_y}
      L ${end_x} ${end_y}
      `;
    }
  } else {
    if (distance_y * -1 <= angle * 2) {
      angle = (distance_y * -1) / 2;
    }
    if (minX) {
      if (distance_y * -1 <= angle * 4) {
        angle = (distance_y * -1) / 4;
      }
      line += `
      M ${x} ${y} 
      L ${x + min_x_distance - angle} ${y} 
      A ${angle} ${angle} 1 0 0 ${x + min_x_distance} ${y - angle}
      L ${x + min_x_distance} ${center_y + angle}
      A ${angle} ${angle} 1 0 0 ${x + min_x_distance - angle} ${center_y}
      L ${end_x - min_x_distance} ${center_y}
      A ${angle} ${angle} 1 0 1 ${end_x - min_x_distance - angle} ${center_y - angle
        }
      L ${end_x - min_x_distance - angle} ${end_y + angle}
      A ${angle} ${angle} 1 0 1 ${end_x - min_x_distance} ${end_y}
      L ${end_x} ${end_y}
      `;
    } else {
      line += `
      M ${x} ${y} 
      L ${center_x - angle} ${y} 
      A ${angle} ${angle} 1 0 0 ${center_x} ${y - angle}
      L ${center_x} ${center_y} 
      L ${center_x} ${end_y + angle} 
      A ${angle} ${angle} 1 0 1 ${center_x + angle} ${end_y}
      L ${end_x} ${end_y}
      `;
    }
  }

  let arrow = `M ${end_x + 0.5} ${end_y + 0.5} L ${end_x - 10} ${end_y - 10
    }  M ${end_x + 0.5} ${end_y - 0.5} L ${end_x - 10} ${end_y + 10} `;

  switch (type) {
    case 'open':
      return line;
      break;
    case 'close':
      return line + arrow;
      break;
    case 'other':
      return line;
      break;
    default:
      return line + arrow;
  }
  return line + arrow;
};

Your Support will be Highly appreciated Thanks in Advance.