2

I have problem something like this a decision has 3 side Input, Yes, No. I want to determine the arrow is connected to which of them.

Here is how I'm going to connect

enter image description here

Connected from Yes

enter image description here

Question: how to know connection is connected to whether Input,Yes,No sides

Note: if problem can be solved with builtin Rhombus then solution is most welcome

here is codepen link: https://codepen.io/eabangalore/pen/eYvVGOg?editors=1010

Here is code:

var graph;
function initCanvas(){
  graph = new mxGraph(document.getElementById('graph-wrapper'));
  var graphStr = `<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><div xmlns="http://www.w3.org/1999/xhtml" data-v-38092c6f="" data-id="60f14502305ed03160da1fd0" data-name="Upload" class="workflow-bins-item" draggedattached="true" triggerortaskid="8c47f506-d34f-4851-a31a-c66facd957f2" style="background: rgb(1, 98, 247); color: white;" id="2">Upload<mxCell xmlns="" style="fillColor=none;strokeColor=none" vertex="1" customWorkflowType="bins" cell_id="60f14502305ed03160da1fd0" triggerOrTaskId="8c47f506-d34f-4851-a31a-c66facd957f2" parent="1"><mxGeometry x="80" y="90" width="145" height="59" as="geometry"/></mxCell></div><div xmlns="http://www.w3.org/1999/xhtml" class="decision-rhombus" data-id="c51a6443-afcc-8705-6557-b1748094c920" draggedattached="true" triggerortaskid="null" id="3"><span  value="Decision" class="decision-rhombus-name--center show-rhombus">Decision</span><span title="Input" class="decision-rhombus--left decision-color show-rhombus">Input</span><span title="Yes" class="decision-rhombus--right decision-color show-rhombus">Yes</span><span title="No" class="decision-rhombus--bottom decision-color show-rhombus">No</span><mxCell xmlns="" style="fillColor=none;strokeColor=none" vertex="1" customWorkflowType="decisions" cell_id="c51a6443-afcc-8705-6557-b1748094c920" parent="1"><mxGeometry x="290" y="83" width="162" height="73" as="geometry"/></mxCell></div></root></mxGraphModel>
`
  
  var doc = mxUtils.parseXml(graphStr);
    var codec = new mxCodec(doc);
  codec.decode(doc.documentElement, graph.getModel());
  // render as HTML node always. You probably won't want that in real world though
  graph.convertValueToString = function(cell) {
    return cell.value;
  }
  
  graph.setConnectable(true);
  graph.setAllowDanglingEdges(false);
  
  graph.refresh();
}
#graph-wrapper{
  background: #333;
  //background:gray;
    width: 100%;
    height: 528px;
}

   .decision-rhombus {
        background: gray;
        clip-path: polygon(0 50%, 50% 100%,100% 50%,50% 0);
        width: 162px;
        display: inline-block;
        margin: 5px;
        height: 73px;
        position: relative !important;
        color: #fff;
        font-size: 11px;
        cursor: default;
    }

    .decision-rhombus > span{
      position:absolute;
    }

    .decision-rhombus--left{
        left: 17px;
        top: 30px;
    }

    .decision-rhombus--right{
        left: 137px;
        top: 29px;
    }

    .decision-rhombus--bottom{
        left: 76px;
        top: 52px;
    }
    .decision-rhombus-name--center {
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 90px; 
        height: 16px; 
        position: absolute;
        border: none; 
        background: transparent; 
        color: #fff; 
        text-align: center;
        text-overflow: ellipsis;
        white-space: nowrap;
        overflow: hidden;
        user-select: none;
        outline: none;
        font-size: 12px;
    }
    .hide-rhombus{
        display: none;
    }
    .show-rhombus{
        display: inherit;
    }
    .decision-color{
        color: #d1d1d1;
    }

.workflow-bins-item {
/*     border-radius: 28px; */
    justify-content: center;
/*     padding-top: 5px; */
    display: flex;
    /* margin-left: 20px; */
/*     margin-top: 20px; */
/*     padding: 3px 17px; */
    min-height: 35px;
    /* min-width: 34px; */
    min-width: 111.203px;
    flex-direction: column;
    align-items: center;
    font-size: 12px;
    max-width: 111.203px;
    white-space: pre-wrap;
     background: gray !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
  Copyright (c) 2006-2013, JGraph Ltd
  
-->
<html>
<head>
    <title>Rhombus with connection input,yes,no</title>

    <!-- Sets the basepath for the library if not in same directory -->
      <script type="text/javascript">
        mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
      </script>

      <!-- Loads and initializes the library -->
      <script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>

    <!-- Example code -->
</head>

<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
<body onload="initCanvas()">
  
     <div id="graph-wrapper">

     </div>
</body>
</html>

Please help me thanks in advance!!

Alireza Ahmadi
  • 8,579
  • 5
  • 15
  • 42
EaBengaluru
  • 131
  • 2
  • 17
  • 59
  • I have problem with the structure. for example you can connect to the left side but then move the `upload` to right side and it looks like you connect the edge to right side!! – Alireza Ahmadi Aug 09 '21 at 04:59
  • @Alireza Ahmadi that should be addressed, otherwise problem will be unsolved – EaBengaluru Aug 09 '21 at 07:47
  • @AlirezaAhmadi with built-in `Rhombus` are you able to solve? – EaBengaluru Aug 09 '21 at 11:24
  • 1
    Still I am working on it. From now I am able to get position of edge on connection time (insert edge I mean ) but I can't find any relation between left or right side and edge position – Alireza Ahmadi Aug 09 '21 at 11:35
  • @AlirezaAhmadi did you find any solution? – EaBengaluru Aug 10 '21 at 12:09
  • Unfortunately No. I think we must override the connect function like this: `mxConnectionHandlerInsertEdge = mxConnectionHandler.prototype.insertEdge; mxConnectionHandler.prototype.insertEdge = function(parent, id, value, source, target, style) { value = 'Test'; return mxConnectionHandlerInsertEdge.apply(this, arguments); };` – Alireza Ahmadi Aug 10 '21 at 13:16
  • @AlirezaAhmadi with built-in rhombus https://codepen.io/eabangalore/pen/gOWZGpW is there any possibility – EaBengaluru Aug 11 '21 at 06:24
  • I see the link but I think there is no possibility – Alireza Ahmadi Aug 11 '21 at 06:50
  • @AlirezaAhmadi if we are able to get connected points for a `cell` then we could easily compare it like this `document.querySelector('.decision-rhombus--left').getBoundingClientRect()` if both are very close then we colud determine with the class `decision-rhombus--left` which means input and so on.. – EaBengaluru Aug 12 '21 at 00:47

1 Answers1

1

I spent four days on this problem. Eventually I ended up with overriding mxConnectionHandler.prototype.connect. Third parameter of connect method gives you PointerEvent and you can calculate distances:

mxConnetEvent = mxConnectionHandler.prototype.connect;
mxConnectionHandler.prototype.connect = function (source, target, evt, dropTarget) {
    Value = findClosestPoint(evt);

    return mxConnetEvent.apply(this, arguments);
}

Here is working snippet:

var graph;
function initCanvas() {
graph = new mxGraph(document.getElementById('graph-wrapper'));
var graphStr = `<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><div xmlns="http://www.w3.org/1999/xhtml" data-v-38092c6f="" data-id="60f14502305ed03160da1fd0" data-name="Upload" class="workflow-bins-item" draggedattached="true" triggerortaskid="8c47f506-d34f-4851-a31a-c66facd957f2" style="background: rgb(1, 98, 247); color: white;" id="2">Upload<mxCell xmlns="" style="fillColor=none;strokeColor=none" vertex="1" customWorkflowType="bins" cell_id="60f14502305ed03160da1fd0" triggerOrTaskId="8c47f506-d34f-4851-a31a-c66facd957f2" parent="1"><mxGeometry x="80" y="60" width="145" height="59" as="geometry"/></mxCell></div><div xmlns="http://www.w3.org/1999/xhtml" class="decision-rhombus" data-id="c51a6443-afcc-8705-6557-b1748094c920" draggedattached="true" triggerortaskid="null" id="3"><span  value="Decision" class="decision-rhombus-name--center show-rhombus">Decision</span><span title="Input" class="decision-rhombus--left decision-color show-rhombus">Input</span><span title="Yes" class="decision-rhombus--right decision-color show-rhombus">Yes</span><span title="No" class="decision-rhombus--bottom decision-color show-rhombus">No</span><mxCell xmlns="" style="fillColor=none;strokeColor=none" vertex="1" customWorkflowType="decisions" cell_id="c51a6443-afcc-8705-6557-b1748094c920" parent="1"><mxGeometry x="290" y="83" width="162" height="73" as="geometry"/></mxCell></div></root></mxGraphModel>`


var doc = mxUtils.parseXml(graphStr);
var codec = new mxCodec(doc);
codec.decode(doc.documentElement, graph.getModel());
// render as HTML node always. You probably won't want that in real world though
graph.convertValueToString = function (cell) {
    return cell.value;
}

graph.setConnectable(true);
graph.setAllowDanglingEdges(false);

graph.refresh();

function calculateDistance(elemX, elemY, mouseX, mouseY) {
    return Math.floor(Math.sqrt(Math.pow(mouseX - elemX, 2) + Math.pow(mouseY - elemY, 2)));
}

function findClosestPoint(evt) {
    var elemLetf = document.querySelector('.decision-rhombus--left').getBoundingClientRect();
    var elemRight = document.querySelector('.decision-rhombus--right').getBoundingClientRect();
    var elemBottom = document.querySelector('.decision-rhombus--bottom').getBoundingClientRect();

    var distanceLeft = calculateDistance(elemLetf.x, elemLetf.y, evt.x, evt.y);
    var distanceRight = calculateDistance(elemRight.x, elemRight.y, evt.x, evt.y);
    var distancebottom = calculateDistance(elemBottom.x, elemBottom.y, evt.x, evt.y);

    if (distanceRight > distanceLeft && distancebottom > distanceLeft) {
        return "LEFT";
    }
    else if (distanceLeft > distanceRight && distancebottom > distanceRight) {
        return 'RIGHT';
    }
    else {
        return 'BOTTOM';
    }
}

show = function (e) {
    console.log('e.clientX:', e.clientX, 'clientY', e.clientY, 'offsetX', e.offsetX, 'offsetY', e.offsetY,
        'pageX', e.pageX, 'pageY', e.pageY, 'x', e.x, 'y', e.y);
}

var Value = "";

mxConnetEvent = mxConnectionHandler.prototype.connect;

mxConnectionHandler.prototype.connect = function (source, target, evt, dropTarget) {
   // console.log('left', document.querySelector('.decision-rhombus--left').getBoundingClientRect());
   // console.log('right', document.querySelector('.decision-rhombus--right').getBoundingClientRect());
    //console.log('buttom', document.querySelector('.decision-rhombus--bottom').getBoundingClientRect());
    //show(evt);
    Value = findClosestPoint(evt);

    return mxConnetEvent.apply(this, arguments);
}

mxConnectionHandlerInsertEdge = mxConnectionHandler.prototype.insertEdge;
mxConnectionHandler.prototype.insertEdge = function (parent, id, value, source, target, style) {
    value = Value;
    return mxConnectionHandlerInsertEdge.apply(this, arguments);
};

}
#graph-wrapper {
            background: #333;
            //background:gray;
            width: 100%;
            height: 528px;
        }

        .decision-rhombus {
            background: gray;
            clip-path: polygon(0 50%, 50% 100%,100% 50%,50% 0);
            width: 162px;
            display: inline-block;
            margin: 5px;
            height: 73px;
            position: relative !important;
            color: #fff;
            font-size: 11px;
            cursor: default;
        }

            .decision-rhombus > span {
                position: absolute;
            }

        .decision-rhombus--left {
            left: 17px;
            top: 30px;
        }

        .decision-rhombus--right {
            left: 137px;
            top: 29px;
        }

        .decision-rhombus--bottom {
            left: 76px;
            top: 52px;
        }

        .decision-rhombus-name--center {
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 90px;
            height: 16px;
            position: absolute;
            border: none;
            background: transparent;
            color: #fff;
            text-align: center;
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
            user-select: none;
            outline: none;
            font-size: 12px;
        }

        .hide-rhombus {
            display: none;
        }

        .show-rhombus {
            display: inherit;
        }

        .decision-color {
            color: #d1d1d1;
        }

        .workflow-bins-item {
            /*     border-radius: 28px; */
            justify-content: center;
            /*     padding-top: 5px; */
            display: flex;
            /* margin-left: 20px; */
            /*     margin-top: 20px; */
            /*     padding: 3px 17px; */
            min-height: 35px;
            /* min-width: 34px; */
            min-width: 111.203px;
            flex-direction: column;
            align-items: center;
            font-size: 12px;
            max-width: 111.203px;
            white-space: pre-wrap;
            background: gray !important;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
        mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
    </script>
    <script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>

<body onload="initCanvas()">
    <div id="graph-wrapper"></div>
</body>
Alireza Ahmadi
  • 8,579
  • 5
  • 15
  • 42
  • could you please help me with the solution for a similar question of mine https://stackoverflow.com/questions/73944360/how-to-get-the-name-of-mxconnectionconstraint-defined-for-a-point-in-mxgraph having 50 bounty. i hope would be knowing the solution. – EaBengaluru Oct 20 '22 at 03:45