jerosoler / Drawflow

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

Arrows for vertical connection lines #414

Closed gpack closed 2 years ago

gpack commented 2 years ago

@jerosoler - Is there an updated version of the "editor.createCurvature()" function you listed in #20 , but one that draws arrows for vertical connection lines (up and down)?

I used the vertical version of the "createCurvature()" script, but I'm having trouble adding in the arrows code in there. Because the code for the arrows only works with horizontal connection lines.

jerosoler commented 2 years ago

Past your code for editor.createCurvature. And take a look.

gpack commented 2 years ago

Here's the code I'm using. It's the version that you shared for vertical lines. But as soon as I update the bottom 'default' section, the arrows show up but they're facing horizontal rather than vertical. And the lines also don't work as well as they did in the original vertical version you shared.

Here's the code:

/ Fix vertical lines / editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) { var line_x = start_pos_x; var line_y = start_pos_y; var x = end_pos_x; var y = end_pos_y; var curvature = curvature_value; //type openclose open close other switch (type) { case 'open': if(start_pos_y >= end_pos_y) { var hy1 = line_y + Math.abs(y - line_y) curvature; var hy2 = y - Math.abs(y - line_y) (curvature-1); } else { var hy1 = line_y + Math.abs(y - line_y) curvature; var hy2 = y - Math.abs(y - line_y) * curvature; } return ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +' ' + y;

    break
case 'close':
    if(start_pos_y >= end_pos_y) {
    var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
    var hy2 = y - Math.abs(y - line_y) * curvature;
    } else {
    var hy1 = line_y + Math.abs(y - line_y) * curvature;
    var hy2 = y - Math.abs(y - line_y) * curvature;
    }
    return ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
    break;
case 'other':
    if(start_pos_y >= end_pos_y) {
    var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
    var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
    } else {
    var hy1 = line_y + Math.abs(y - line_y) * curvature;
    var hy2 = y - Math.abs(y - line_y) * curvature;
    }
    return ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
    break;
default:
      var hx1 = line_x + Math.abs(x - line_x) * curvature;
      var hx2 = x - Math.abs(x - line_x) * curvature;

      //return ' M '+ line_x +' '+ line_y +' C '+ hx1 +' '+ line_y +' '+ hx2 +' ' + y +' ' + x +'  ' + y;
      return ' M '+ line_x +' '+ line_y +' C '+ hx1 +' '+ line_y +' '+ hx2 +' ' + y +' ' + x +'  ' + y +' M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-5)+'  L'+(x-20)+' '+ (y+5)+'Z';
}

} / End Fix vertical lines /

jerosoler commented 2 years ago

Test:

editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) {
        const fix_arrow_distance = 15;
        var line_x = start_pos_x;
        var line_y = start_pos_y;
        var x = end_pos_x;
        var y = end_pos_y - fix_arrow_distance;
        var curvature = curvature_value;
        //type openclose open close other
        let line_path = '';
        switch (type) {
        case 'open':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;

            break
        case 'close':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
            var hy2 = y - Math.abs(y - line_y) * curvature;
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
            break;
        case 'other':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
            var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
            break;
        default:
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;

            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;

        }
        const arrow_path = ` M ${x} ${y} L ${x-5} ${y-8} L ${x+5} ${y-8} L ${x} ${y} Z`;
        return line_path + arrow_path;
    }

And Image: image

gpack commented 2 years ago

That works great Jero! thanks. But how did you get the output circle to be on top of the line and the input circle is under the arrow? I changed the .drawflow svg z-index to 3, but both circles are underneath now.

On your image it shows the output circle on top of the line.

jerosoler commented 2 years ago

I have not changed the z-index. Here is the example I used.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"/>
  <script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
</head>
<body>
<div id="drawflow"></div>
  <style>
    #drawflow { 
      position: relative;
      text-align:initial;
      width: 100%;
      height: 800px;
      border: 1px solid red;
    }

    .drawflow .drawflow-node {
        flex-direction: column;
  }

  .drawflow .drawflow-node .inputs, .drawflow .drawflow-node .outputs {
    display: flex;
    width: auto;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .drawflow .drawflow-node .input {
    top: -30px;
    left: 0px;
  }

  .drawflow .drawflow-node .output {
    top: 25px;
    right: 0px;
  }
</style>
<script>
    var id = document.getElementById("drawflow");
    const editor = new Drawflow(id);

    editor.start();

    editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) {
        const fix_arrow_distance = 15;
        var line_x = start_pos_x;
        var line_y = start_pos_y;
        var x = end_pos_x;
        var y = end_pos_y - fix_arrow_distance;
        var curvature = curvature_value;
        //type openclose open close other
        let line_path = '';
        switch (type) {
        case 'open':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;

            break
        case 'close':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
            var hy2 = y - Math.abs(y - line_y) * curvature;
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
            break;
        case 'other':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
            var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
            break;
        default:
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;

            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;

        }
        const arrow_path = ` M ${x} ${y} L ${x-5} ${y-8} L ${x+5} ${y-8} L ${x} ${y} Z`;
        return line_path + arrow_path;
    }

    editor.addNode('aaa', 0, 1, 100, 300, 'aaa', {}, '<input type="text">' );
    editor.addNode('bbb', 1, 0, 350, 650, 'bbb', {}, 'bbb' );
    editor.addNode('ccc', 1, 0, 500, 500, 'ccc', {}, 'ccc' );
    editor.addConnection(1, 2, 'output_1', 'input_1');
    editor.addConnection(1, 3, 'output_1', 'input_1');
</script>
</body>
</html>
gpack commented 2 years ago

Thanks, the example you provided should help.

I think your arrows or the connection line connects right at the very top edge of the circle, but my ones seem to connect a bit below (see image attached). s1

But I'll work it out. It could be my CSS or my circles are too big or in different position. Thanks for your help.

jerosoler commented 2 years ago

Change this line:

        const fix_arrow_distance = 15;

Increment or decrement to adjust.

gpack commented 2 years ago

Ooh yeh! I didn't even see that line at the top.

Beautiful :) thanks again.

HeoYoungHyun commented 1 year ago

테스트:

editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) {
        const fix_arrow_distance = 15;
        var line_x = start_pos_x;
        var line_y = start_pos_y;
        var x = end_pos_x;
        var y = end_pos_y - fix_arrow_distance;
        var curvature = curvature_value;
        //type openclose open close other
        let line_path = '';
        switch (type) {
        case 'open':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;

            break
        case 'close':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
            var hy2 = y - Math.abs(y - line_y) * curvature;
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
            break;
        case 'other':
            if(start_pos_y >= end_pos_y) {
            var hy1 = line_y + Math.abs(y - line_y) * (curvature*-1);
            var hy2 = y - Math.abs(y - line_y) * (curvature*-1);
            } else {
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;
            }
            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;
            break;
        default:
            var hy1 = line_y + Math.abs(y - line_y) * curvature;
            var hy2 = y - Math.abs(y - line_y) * curvature;

            line_path += ' M '+ line_x +' '+ line_y +' C '+ line_x +' '+ hy1 +' '+ x +' ' + hy2 +' ' + x +'  ' + y;

        }
        const arrow_path = ` M ${x} ${y} L ${x-5} ${y-8} L ${x+5} ${y-8} L ${x} ${y} Z`;
        return line_path + arrow_path;
    }

그리고 이미지: 영상

I want to get rid of the curvature here, how do I modify the code?

jerosoler commented 1 year ago

@HeoYoungHyun

View: