jerosoler / Drawflow

Simple flow library πŸ–₯οΈπŸ–±οΈ
https://jerosoler.github.io/Drawflow/
MIT License
4.78k stars 741 forks source link

Vertical ports or drawing connections from node edges #20

Open Ataraxy opened 4 years ago

Ataraxy commented 4 years ago

Really like the library!

It would be nice to have an option for inputs/outputs to be on the top/bottom of nodes instead as it appears the logic for drawing connections is hard coded with the assumption that ports are on the sides.

For example:

top-bottom

Similarly, removing a reliance on port elements entirely and instead being able to just draw connections from any of a nodes edges would be nice, though maybe that's too much an impractical change.

For example:

nodes

jerosoler commented 4 years ago

Hello! @Ataraxy

Thanks! πŸ˜‰

Vertical it's possible only modify the CSS.

image

Only add the css:

  .drawflow .drawflow-node {
    display: block;
  }

  .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: -10px;
    left: 0px;
  }

  .drawflow .drawflow-node .output {
    top: 10px;
    right: 0px;
  }

The curvature of the connection vertically is not very good. But maybe add a function to modify the curve. Commented on #12

Maybe everything could be done automatically.

editor.node_style = 'Horitzontal' Or 'Vertical';

The second example is more complicated. I understand that all nodes would only have one input and one output.

Maybe the connection could be made "CTRL + Click".

Ataraxy commented 4 years ago

I suppose the second example could mostly be achieved with CSS as well to a degree. As you pointed out it really comes down to a node technically having only one input and one output so instead of a circle one could just make the port a few pixels along the width (or height) of the edge that the outgoing connection is dragged from.

To do what the example does though would mean that an output or input could come from any side of a node which means it would require a "port container" on each side of it that could act as either port type and the output would merely be determined by whichever node the connection started from. So yeah it might be a bit of an impractica change / option.

As for the curves using something like https://github.com/anseki/leader-line instead to handle drawing connections would offer a lot of flexibility and customization for them but I could also understand not wanting an additional dependency.

jerosoler commented 4 years ago

Right now I was trying a method to overwrite the curve.

image

This example:

    editor.curvature = 0;
    editor.reroute_curvature_start_end = 0;
    editor.reroute_curvature = 0;

    editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value) {
      var center_x = ((end_pos_x - start_pos_x)/2)+start_pos_x;
      return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ center_x +' ' +  start_pos_y  + ' L ' + center_x + ' ' +  end_pos_y  + ' L ' + end_pos_x + ' ' + end_pos_y;
    }
jaspermyrp commented 4 years ago

Hello, it will be great to implement an arrow for the lines to indicate the flow direction. Thank you

jerosoler commented 4 years ago

Hello @jaspermyrp

For the arrow.

You can override the function createCurvature and add arrow.

For example:

image

Code:

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_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * curvature;
            var hx2 = x - Math.abs(x - line_x) * (curvature*-1);
          } else {
            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;

          break
        case 'close':
          if(start_pos_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1);
            var hx2 = x - Math.abs(x - line_x) * curvature;
          } else {
            var hx1 = line_x + Math.abs(x - line_x) * curvature;
            var hx2 = x - Math.abs(x - line_x) * curvature;
          }                                                                                                                  //M0 75H10L5 80L0 75Z

          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';
          break;
        case 'other':
          if(start_pos_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1);
            var hx2 = x - Math.abs(x - line_x) * (curvature*-1);
          } else {
            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;
          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';
      }

    }

Only added at function default:

 M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-5)+'  L'+(x-20)+' '+ (y+5)+'Z';
Ataraxy commented 4 years ago

Heya!

So I was wondering if you had any ideas on how I could do this. I would like to use labels as ports and draw connections from the center of each of them (if horizontal).

For example:

Labeled Ports

Instead of:

Normal Ports

I think my ideal scenario would be that I could define input/output elements within the html of a custom node or maybe a container for where they should be. This way we would probably have the most flexibility to do whatever we like.

Another possible (simpler) solution is being able to pass in labels for inputs/outputs during editor.addNode() which are added to the markup wrappers being used to create the inputs/outputs. Then we could just style the elements with CSS.

mrsherlock88 commented 4 years ago

Hi @jerosoler ,

I tried to make vertical along with arrow at the end. First I used custom CSS for each node to take endpoint to top/bottom of node. Then I realize the line is calculate to center of node instead of direct to the endpoint, because I make an arrow and see it's disappeared.

.drawflow .parent-node .glue-etl .outputs {
  position: absolute;
  bottom: -10px;
  padding-left: 50%;
}
.drawflow .parent-node .s3-raw .inputs {
  position: absolute;
  top: -10px;
  padding-left: 50%;
}

Capture

I was able to put the endpoint to top/bottom of the nodes using custom CSS above, but the arrow is not appear because the line is draw under the node (as I draw 2 ugly red lines). How can I make a custom code or css without modify your base drawflow.js and drawflow.css file?

jerosoler commented 4 years ago

Hello @Ataraxy

Are you looking for this? #18

What comments to do something like this:

editor.addNode ('github', 0, 3, 150, 300, 'github', data, html);

For:

editor.addNode ('github', 0, ['Yes', 'No', 'Other'], 150, 300, 'github', data, html);

If it's about connections use # 18

jerosoler commented 4 years ago

Hi! @mrsherlock88

Add css for view connection end:

.drawflow svg {
    z-index: 3;
}

With the code:

  .drawflow .drawflow-node {
    display: block;
  }

  .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: -10px;
    left: 0px;
  }

  .drawflow .drawflow-node .output {
    top: 10px;
    right: 0px;
  }

image

The arrow example code is only for horitzontal method.

mrsherlock88 commented 4 years ago

Hi @jerosoler ,

I've tried the CSS before but maybe it conflict with my current CSS so I use my own custom CSS, also I want to explicit top/bottom endpoint for particular node, not for all.

Capture2

Also, I upload my image when use you css and the real line. Note that the line comes from Glue ETL to S3 Raw.

jerosoler commented 4 years ago

@mrsherlock88

I will modify so that it goes to find the exact point and not the parent element.

This will make it easier to modify the positions points.

Ataraxy commented 4 years ago

Hi, I wasn't referring to a label on the connection itself, but rather instead of a circular output or input, to instead use a label or text as the point of origin for the connection.

I've sorta got it working this way from a little CSS where each input and output is just a 5px high element that spans across the node like this:

example

The problem is that the labels in this case are within the node which means the point of origin for the connection is offset. (since it is always at the center of whatever the port element is). That's why I was wondering if instead there was approach to adding a label to use within the "port" instead.

I will keep messing around with it.

jaspermyrp commented 4 years ago

Hello @jaspermyrp

For the arrow.

You can override the function createCurvature and add arrow.

For example:

image

Code:

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_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * curvature;
            var hx2 = x - Math.abs(x - line_x) * (curvature*-1);
          } else {
            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;

          break
        case 'close':
          if(start_pos_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1);
            var hx2 = x - Math.abs(x - line_x) * curvature;
          } else {
            var hx1 = line_x + Math.abs(x - line_x) * curvature;
            var hx2 = x - Math.abs(x - line_x) * curvature;
          }                                                                                                                  //M0 75H10L5 80L0 75Z

          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';
          break;
        case 'other':
          if(start_pos_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1);
            var hx2 = x - Math.abs(x - line_x) * (curvature*-1);
          } else {
            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;
          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';
      }

    }

Only added at function default:

 M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-5)+'  L'+(x-20)+' '+ (y+5)+'Z';

Thank you!

jerosoler commented 4 years ago

Hello @mrsherlock88

New update version 0.0.22 with fix search position points.

For example:

editor.addNode('github', 1, 3, 100, 50, 'romb', data, "<b>Hey</b>");
  .drawflow .parent-node .romb {
    transform: rotate(45deg);
    width: 50px;
    height: 50px;
  }
  .drawflow .parent-node .romb .drawflow_content_node {
    transform: rotate(-45deg);
  }
  .drawflow .parent-node .romb .input_1 {
    transform: rotate(-45deg);
    position: relative;
    top: 40px;
    right: 25px;
  }

  .drawflow .parent-node .romb .output_1 {
    transform: rotate(-45deg);
    position: relative;
    top: -5px;
    right: 75px;
  }

  .drawflow .parent-node .romb .output_2 {
    transform: rotate(-45deg);
    position: relative;
    top: -35px;
    right: 0px;
  }

  .drawflow .parent-node .romb .output_3 {
    transform: rotate(-45deg);
    position: relative;
    top: 10px;
    right: 0px;
  }

image

Or points out of node:

image

I have pending review your PR

mrsherlock88 commented 4 years ago

@jerosoler nice to hear that, in my PR, I also fix the direction of line or curve points (in openclose line) base on the position of point with node.

So when I add arrow in the end of line using marker-end, it should appear normally.

PS: nice to see the change logs between updates.

MehbubRashid commented 4 years ago

hi @jerosoler the arrow is not filled..and does not look good..how can i fill it with solid color?

MehbubRashid commented 4 years ago

also the arrow does not stay with the connector line if i move the node so much up or down...the arrow remains in the same place but the connector line gets moved...so they becomes seperated....

do you have any better solution?

jerosoler commented 4 years ago

Hello @MehbubRashid

The example is only a lines. Adding more lines for example:

M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-5)+'  L'+(x-20)+' '+ (y+5)+' Z' +' M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-3)+'  L'+(x-20)+' '+ (y+3)+' Z' +' M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-1)+'  L'+(x-20)+' '+ (y+1)+' Z'

image

Complete line:

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' +' M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-3)+'  L'+(x-20)+' '+ (y+3)+' Z' +' M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-1)+'  L'+(x-20)+' '+ (y+1)+' Z';

For comment: https://github.com/jerosoler/Drawflow/issues/20#issuecomment-685410323

The values of the numbers "11", "20" and "5" would have to be calculated.

MehbubRashid commented 4 years ago

@jerosoler it works..but i was taking about this...the arrow does not stay with the line...how to fix this? disjoint

MehbubRashid commented 4 years ago

hi @jerosoler , instead of overwriting the curvature function, i have overwritten the inputs css and made the round inputs into triangle using css...it works perfectly.. but when there is no connection, the triangle still remains there ccccccccccc

so i want a way to remove this...in simple, i want the inputs to be visible only if the input has a connection.otherwise not.it would be great if you would add a class called "connected" to the input class upon creating a connection...when the connection is removed, the class will also get removed..it will help users to style their inputs and outputs more nicely.can you add this?

NishargShah commented 3 years ago

@jerosoler is there any way that dots behave input and output both simultaneously?

we used your library and it's pretty good but now we need that feature that dot can behave as an input and output both.

jerosoler commented 3 years ago

Hello @NishargShah

It can not.

But a fix could be made.

Try modifying the addConnection function

NishargShah commented 3 years ago

@jerosoler Thanks for the really quick answer, can you please tell me how can I achieve it, I don't know really

jerosoler commented 3 years ago

@NishargShah

I see that you have to touch more things. Many... Wouldn't it help to put a bullet output on top of an input via css?

NishargShah commented 3 years ago

@jerosoler Thanks it's a great idea, let me work on it, thanks again...

NishargShah commented 3 years ago

@jerosoler that's a great idea but if I overlap input into output I can't draw a line or if I overlap output into input I can't attach that line in dot, any suggestion?

jerosoler commented 3 years ago

@NishargShah use event click for change z-index (input/output).

Qucik example

  editor.on("click", function(event) {
    if(event.target.classList[0] == "output") {
      for (const element of document.querySelectorAll(".inputs")) {
        element.style.zIndex = 3
      }
    } else {
      for (const element of document.querySelectorAll(".inputs")) {
        element.style.zIndex = 2;
      }
      for (const element of document.querySelectorAll(".outputs")) {
        element.style.zIndex = 2;
      }
    }
  });
NishargShah commented 3 years ago

@jerosoler yes it's working but it behaves like a toggle thing, not smooth because if I drag a line from the dot after that if I clicked again on that dot it will behave as input because of a z-index, there is any other way?

NishargShah commented 3 years ago

@jerosoler Thanks for the help, I completed with below code

useEffect(() => {
    document.addEventListener('mouseup', event => {
      if(event.target.classList[0] !== "output") {
        for (const element of document.querySelectorAll(".inputs")) {
          element.style.zIndex = 2;
        }
        for (const element of document.querySelectorAll(".outputs")) {
          element.style.zIndex = 2;
        }
      }
    });

    editor.current.on("connectionCreated", () => {
      for (const element of document.querySelectorAll(".inputs")) {
        element.style.zIndex = 2;
      }
      for (const element of document.querySelectorAll(".outputs")) {
        element.style.zIndex = 2;
      }
    })

    editor.current.on("click", event => {
      if(event.target.classList[0] === "output") {
        for (const element of document.querySelectorAll(".inputs")) {
          element.style.zIndex = 3
        }
      }
    });
  }, []);
jerosoler commented 3 years ago

I leave here an arrangement so that the lines are better displayed in vertical format. In case someone can help you.

Fix for vertical lines:

    /* 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 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;

        }

    }

    /* End Fix vertical lines */
dearsina commented 3 years ago

Did anyone figure out how (assuming we only have two outputs) to have one output on the right and one on the bottom of a node box? I've played around with CSS for the past few hours but I'm not good enough to crack this one. Any suggestions? Is it even possible given a variable node size?

jerosoler commented 3 years ago

Hello @dearsina Can you send an image of how you want it?

dearsina commented 3 years ago

@jerosoler Screenshot_20210217-214903_Chrome Sorry for the asinine quality, I stepped away from my desk for the day, but ya nothing too complex, just a second output bit in the middle where the black circle is, if that's possible.

Even better if we combine it with a second input on top, but now I'm just being greedy!

jerosoler commented 3 years ago

@dearsina

use position relatie in output_2 and similar to input.

.output_2 {
    position: relative;
    top: 110px;
    right: 105px;
}

View similar example: https://github.com/jerosoler/Drawflow/issues/20#issuecomment-679976512

dearsina commented 3 years ago

Thanks for the prompt reply. There are unfortunately some issues.

  1. The CSS only works if the height of the node is fixed. Look at the red box in the photo, the output marker is "floating" because the node is not very tall.
  2. The connecting lines are not aligned at all. Not sure why. See the yellow box in the photo.
  3. I've included the CSS I'm using. I don't think it's as straightforward as using top/right unfortunately! I tried for hours to make something work! Untitled
jerosoler commented 3 years ago

Hello @dearsina

View example:

image

Node with styleClass "test"

Style display block node extrac of https://jerosoler.github.io/drawflow-theme-generator/

.drawflow .drawflow-node {
  display: block;
  background: white;
  color: black;
  border: 1px  solid black;
  border-radius: 4px;
  width: auto;
  padding-top: 10px;
  padding-bottom: 10px;

}

.drawflow .drawflow-node .outputs {
  float: right;
}

.drawflow-node.test .input_1 {
  position: absolute;
  left: -12px;
  top: calc(50% - 12px);
}

.drawflow-node.test .input_2 {
  position: absolute;
  left: 45%;
  top: calc(0% - 10px);
}

.drawflow-node.test .output_1 {
  position: absolute;
  left: calc(100% - 12px);
  top: calc(50% - 12px);
}

.drawflow-node.test .output_2 {
  position: absolute;
  left: 45%;
  top: calc(100% - 10px);
}
dearsina commented 3 years ago

@jerosoler I don't know what kind of voodoo CSS magic you just performed, but that works splendidly. Thank you very much! Perhaps it should be incorporated into the library so that others can also use it?

ishpreetkaurwebner commented 3 years ago

Thanks a lot @jerosoler , you are amazing.

nodegin commented 3 years ago

Hello @jerosoler ,

I tried your solution in here

 editor.curvature = 0;
    editor.reroute_curvature_start_end = 0;
    editor.reroute_curvature = 0;

    editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value) {
      var center_x = ((end_pos_x - start_pos_x)/2)+start_pos_x;
      return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ center_x +' ' +  start_pos_y  + ' L ' + center_x + ' ' +  end_pos_y  + ' L ' + end_pos_x + ' ' + end_pos_y;
    }

It looks very good for my application, however there is one problem

It it quite hard to identify the lines if same output contains multiple line since they will overlapping

2021-03-18 1 17 54

Could you give me some advice how to make it looks like having a reroute point below/above the input/output?

So the line will easier for identifying, like this:

2021-03-18 1 19 39

Thank you so much for your awesome help!

jerosoler commented 3 years ago

Hello @nodegin

The example you are using is for horitzontal mode.

You cannot create a redirect point without it being a point.

But if you modify the line below you can, it would suit you better:

       var center_x = ((end_pos_x - start_pos_x)/2)+start_pos_x;
      return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ center_x +' ' +  start_pos_y  + ' L ' + center_x + ' ' +  end_pos_y  + ' L ' + end_pos_x + ' ' + end_pos_y;

It does not have to be complicated to modify this line: Basically it is the information of a svg path: https://www.w3schools.com/graphics/svg_path.asp

Moveto and Lineto.

Find the center_y. I would only have to change the first and second "lineto".

I do it from memory but it would have to be something like this:

       var center_y = ((end_pos_y - start_pos_y)/2)+start_pos_y;
      return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ start_pos_x +' ' +  center_y  + ' L ' + end_pos_x + ' ' +  center_y  + ' L ' + end_pos_x + ' ' + end_pos_y;

Jero

nodegin commented 3 years ago

Thank you @jerosoler It works!!

princeyogesh commented 3 years ago

Hello @jaspermyrp

For the arrow.

You can override the function createCurvature and add arrow.

For example:

image

Code:

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_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * curvature;
            var hx2 = x - Math.abs(x - line_x) * (curvature*-1);
          } else {
            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;

          break
        case 'close':
          if(start_pos_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1);
            var hx2 = x - Math.abs(x - line_x) * curvature;
          } else {
            var hx1 = line_x + Math.abs(x - line_x) * curvature;
            var hx2 = x - Math.abs(x - line_x) * curvature;
          }                                                                                                                  //M0 75H10L5 80L0 75Z

          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';
          break;
        case 'other':
          if(start_pos_x >= end_pos_x) {
            var hx1 = line_x + Math.abs(x - line_x) * (curvature*-1);
            var hx2 = x - Math.abs(x - line_x) * (curvature*-1);
          } else {
            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;
          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';
      }

    }

Only added at function default:

 M '+ (x-11)  + ' ' + y + ' L'+(x-20)+' '+ (y-5)+'  L'+(x-20)+' '+ (y+5)+'Z';

is there any way give direction of arrow for connection starting from input circle to output circle??

princeyogesh commented 3 years ago

@jerosoler is there any way that dots behave input and output both simultaneously?

we used your library and it's pretty good but now we need that feature that dot can behave as an input and output both.

@NishargShah , if you have achieved this. for ip/op bubbles. Please help me I want to do similar thing with this library. Can you share css or whatever code changes you made ?

NishargShah commented 3 years ago

Here is the code of overlapping issue

https://github.com/jerosoler/Drawflow/issues/20#issuecomment-746144773

Code: https://www.codepile.net/pile/jG2Mykve

CSS: https://www.codepile.net/pile/G9KARvgd

Richard0323 commented 3 years ago

Hi

I've modified connection style like this

and I want the line has round corner

ζˆͺεœ– 2021-07-14 上午10 32 52

But I have no idea to do this with modifying svg, could you please give me a sample? Thank you!

Hello @nodegin

The example you are using is for horitzontal mode.

You cannot create a redirect point without it being a point.

But if you modify the line below you can, it would suit you better:

       var center_x = ((end_pos_x - start_pos_x)/2)+start_pos_x;
      return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ center_x +' ' +  start_pos_y  + ' L ' + center_x + ' ' +  end_pos_y  + ' L ' + end_pos_x + ' ' + end_pos_y;

It does not have to be complicated to modify this line: Basically it is the information of a svg path: https://www.w3schools.com/graphics/svg_path.asp

Moveto and Lineto.

Find the center_y. I would only have to change the first and second "lineto".

I do it from memory but it would have to be something like this:

       var center_y = ((end_pos_y - start_pos_y)/2)+start_pos_y;
      return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ start_pos_x +' ' +  center_y  + ' L ' + end_pos_x + ' ' +  center_y  + ' L ' + end_pos_x + ' ' + end_pos_y;

Jero

dtocci commented 2 years ago

Sorry to dig up an old post but I wanted to accomplish a vertical layout like the first image from the OP. The CSS got me most of the way there, but the curvature at the connection points wasn't working for me, not even when using the other issue that was referenced. Here's the code I used for the curvature. I hope it helps someone.


editor.createCurvature = function(start_pos_x, start_pos_y, end_pos_x, end_pos_y, curvature_value, type) {
    var ydiff = end_pos_y - start_pos_y;
    var xdiff = end_pos_x - start_pos_x;
    var hx1 = start_pos_x + xdiff*curvature_value;
    var hx2 = end_pos_x - xdiff*curvature_value;
    var hy1 = start_pos_y + ydiff*curvature_value;
    var hy2 = end_pos_y - ydiff*curvature_value;
    //type openclose open close other
    switch (type) {
        case 'open':
            return ' M'+start_pos_x+','+start_pos_y+' C'+start_pos_x+','+hy1+' '+hx2+','+end_pos_y+' '+end_pos_x+','+end_pos_y;
            break;
        case 'other':
            return ' M'+start_pos_x+','+start_pos_y+' C'+hx1+','+start_pos_y+' '+hx2+','+end_pos_y+' '+end_pos_x+','+end_pos_y;
            break;
        case 'close':
            return ' M'+start_pos_x+','+start_pos_y+' C'+hx1+','+start_pos_y+' '+end_pos_x+','+hy2+' '+end_pos_x+','+end_pos_y;
            break;
        default:
            return ' M'+start_pos_x+','+start_pos_y+' C'+start_pos_x+','+hy1+' '+end_pos_x+','+hy2+' '+end_pos_x+','+end_pos_y;
    }
}
ramnight commented 2 years ago

@Richard0323 image

editor.createCurvature = function (start_x, start_y, end_x, end_y, curvature_value, type) {
      var center_y = ((end_y - start_y) / 2) + start_y;
      var default_round_radius = 10;
      var round_radius = Math.min(default_round_radius, Math.abs(start_x - end_x), Math.abs(start_y - end_y));

      var isRight = end_x > start_x;
      var isDown = end_y > start_y;
      return `M ${start_x} ${start_y} 
            L ${start_x} ${isDown ? center_y - round_radius : center_y + round_radius} 
            A ${round_radius} ${round_radius} 0 0 ${isRight ^ !isDown ? 0 : 1} ${isRight ? start_x + round_radius : start_x - round_radius} ${center_y}
            L ${isRight ? end_x - round_radius : end_x + round_radius} ${center_y}
            A ${round_radius} ${round_radius} 0 0 ${isRight ^ !isDown ? 1 : 0} ${end_x} ${isDown ? center_y + round_radius : center_y - round_radius}
            L ${end_x} ${end_y}`;
    }
ArG97 commented 2 years ago

Hi Jero, i saw some similar problem but its not working for me, could you help me to find the problem. image

i want like this and tried this code also var center_y = ((end_pos_y - start_pos_y)/2)+start_pos_y; return ' M ' + start_pos_x + ' ' + start_pos_y + ' L '+ start_pos_x +' ' + center_y + ' L ' + end_pos_x + ' ' + center_y + ' L ' + end_pos_x + ' ' + end_pos_y;

jerosoler commented 2 years ago

Hello, You should have two lines. A when the start_pos_y > end_pos_y i the opposite.

ArG97 commented 2 years ago

can you show me the example as in a code? @jerosoler i have tried like this: image

but the lines are disappeared