How to validate for un-connected edges to cell in mxgraph
Asked Answered
D

1

18

Hi i'm facing problem with validation for un-connected edges to cells in mxgraph

below image will show you my expectation:

enter image description here

Question: whenever i press validate button un-connected edges and cells must be highlighted with red color.

For full view Codepen:https://codepen.io/eabangalore/pen/pmELpL?editors=1100

NOTE: PLEASE SEE CODEPEN LINK (https://codepen.io/eabangalore/pen/pmELpL?editors=1100) as BELOW CODE IS NOT WORKING

Full Code:

<!--
  Copyright (c) 2006-2013, JGraph Ltd
  
  Dynamic toolbar example for mxGraph. This example demonstrates changing the
  state of the toolbar at runtime.
-->
<html>
<head>
	<title>Toolbar example for mxGraph</title>

	<!-- Sets the basepath for the library if not in same directory -->
  <script type="text/javascript">
    mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
    
    function setGraphData(){
      var graphState ={"tagName":"mxGraphModel","children":[{"tagName":"root","children":[{"tagName":"mxCell","attributes":{"id":"0"}},{"tagName":"mxCell","attributes":{"id":"1","parent":"0"}},{"tagName":"mxCell","attributes":{"id":"2","value":"A","style":"","parent":"1","vertex":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"271.56251525878906","y":"82.44792175292969","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"3","value":"B","style":"","parent":"1","vertex":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"678.2291717529297","y":"106.89236450195312","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"4","value":"Bangalore","parent":"1","edge":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"0.0511","y":"-20","relative":"1","as":"geometry"},"children":[{"tagName":"mxPoint","attributes":{"x":"370.06251525878906","y":"109.95338610053051","as":"sourcePoint"}},{"tagName":"mxPoint","attributes":{"x":"676.7291717529297","y":"128.3869001543523","as":"targetPoint"}},{"tagName":"mxPoint","attributes":{"as":"offset"}}]}]},{"tagName":"mxCell","attributes":{"id":"5","value":"C","style":"","parent":"1","vertex":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"1013.7847747802734","y":"83.55902862548828","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"6","parent":"1","source":"3","target":"5","edge":"1"},"children":[{"tagName":"mxGeometry","attributes":{"relative":"1","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"7","value":"Not Connected","style":"","vertex":"1","parent":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"552","y":"267.640625","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"8","value":"Edge Not connected must highlight in red color","edge":"1","parent":"1","source":"5"},"children":[{"tagName":"mxGeometry","attributes":{"relative":"1","as":"geometry"},"children":[{"tagName":"mxPoint","attributes":{"x":"740","y":"260","as":"targetPoint"}}]}]}]}]};
      
      localStorage.setItem('graphState',JSON.stringify(graphState));
    }
    
    	function html2json(html){
		if(html.nodeType==3){
			return {
				"tagName":"#text",
				"content":html.textContent
			}
		}
		var element = {
			"tagName":html.tagName
		};

		if(html.getAttributeNames().length>0){
			element.attributes = html.getAttributeNames().reduce(
				function(acc,at){acc[at]=html.getAttribute(at); return acc;},
				{}
			);
		}

		if(html.childNodes.length>0){
			element.children = Array.from(html.childNodes)
				.filter(
					function(el){
						return el.nodeType!=3
						||el.textContent.trim().length>0
					})
				.map(function(el){return html2json(el);});
		}
		return element;
	}

	function json2html(json){
		var xmlDoc = document.implementation.createDocument(null, json.tagName);

		var addAttributes = function(jsonNode, node){
			if(jsonNode.attributes){
				Object.keys(jsonNode.attributes).map(
					function(name){
						node.setAttribute(name,jsonNode.attributes[name]);
					}
				);
			}
		}

		var addChildren = function(jsonNode,node){
			if(jsonNode.children){
				jsonNode.children.map(
					function(jsonChildNode){
						json2htmlNode(jsonChildNode,node);
					}
				);
			}
		}

		var json2htmlNode = function(jsonNode,parent){
			if(jsonNode.tagName=="#text"){
				return xmlDoc.createTextNode(jsonNode.content);
			}

			var node = xmlDoc.createElement(jsonNode.tagName);

			addAttributes(jsonNode,node);
			addChildren(jsonNode,node);

			parent.appendChild(node);
		}

		addAttributes(json,xmlDoc.firstElementChild);
		addChildren(json,xmlDoc.firstElementChild);

		return xmlDoc;
	}
  </script>

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

	<!-- Example code -->
	<script type="text/javascript">
		// Program starts here. Creates a sample graph in the
		// DOM node with the specified ID. This function is invoked
		// from the onLoad event handler of the document (see below).
		function main()
		{
      setGraphData();
			// Checks if browser is supported
			if (!mxClient.isBrowserSupported())
			{
				// Displays an error message if the browser is
				// not supported.
				mxUtils.error('Browser is not supported!', 200, false);
			}
			else
			{
				// Defines an icon for creating new connections in the connection handler.
				// This will automatically disable the highlighting of the source vertex.
				mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);

				// Creates the div for the toolbar
				var tbContainer = document.createElement('div');
				tbContainer.style.position = 'absolute';
				tbContainer.style.overflow = 'hidden';
				tbContainer.style.padding = '2px';
				tbContainer.style.left = '0px';
				tbContainer.style.top = '0px';
				tbContainer.style.width = '24px';
				tbContainer.style.bottom = '0px';
				
				document.body.appendChild(tbContainer);
			
				// Creates new toolbar without event processing
				var toolbar = new mxToolbar(tbContainer);
				toolbar.enabled = false
				
				// Creates the div for the graph
				var container = document.createElement('div');
				container.style.position = 'absolute';
				container.style.overflow = 'hidden';
				container.style.left = '24px';
				container.style.top = '0px';
				container.style.right = '0px';
				container.style.bottom = '0px';
				container.style.background = 'url("editors/images/grid.gif")';

				document.body.appendChild(container);
				
				// Workaround for Internet Explorer ignoring certain styles
				if (mxClient.IS_QUIRKS)
				{
					document.body.style.overflow = 'hidden';
					new mxDivResizer(tbContainer);
					new mxDivResizer(container);
				}
	
				// Creates the model and the graph inside the container
				// using the fastest rendering available on the browser
				var model = new mxGraphModel();
				var graph = new mxGraph(container, model);

				// Enables new connections in the graph
				graph.setConnectable(true);
				graph.setMultigraph(false);

				// Stops editing on enter or escape keypress
				var keyHandler = new mxKeyHandler(graph);
				var rubberband = new mxRubberband(graph);
				
				var addVertex = function(icon, w, h, style)
				{
					var vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
					vertex.setVertex(true);
				
					var img = addToolbarItem(graph, toolbar, vertex, icon);
					img.enabled = true;
					
					graph.getSelectionModel().addListener(mxEvent.CHANGE, function()
					{
						var tmp = graph.isSelectionEmpty();
						mxUtils.setOpacity(img, (tmp) ? 100 : 20);
						img.enabled = tmp;
					});
				};
				
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rectangle.gif', 100, 40, '');
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rounded.gif', 100, 40, 'shape=rounded');
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/triangle.gif', 40, 40, 'shape=triangle');
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
				addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/actor.gif', 30, 40, 'shape=actor');
        
        
       				// read state on load 
				if(window.localStorage.graphState){	
					var doc = json2html(JSON.parse(localStorage.graphState));	
					var dec = new mxCodec(doc);
					dec.decode(doc.documentElement, graph.getModel());
				}

				// save state on change
				graph.getModel().addListener('change',function(){
						var codec = new mxCodec();		
						window.localStorage.graphState = JSON.stringify(html2json(codec.encode(
							graph.getModel()
						)));
				});
			}
		}

		function addToolbarItem(graph, toolbar, prototype, image)
		{
			// Function that is executed when the image is dropped on
			// the graph. The cell argument points to the cell under
			// the mousepointer if there is one.
			var funct = function(graph, evt, cell, x, y)
			{
				graph.stopEditing(false);

				var vertex = graph.getModel().cloneCell(prototype);
				vertex.geometry.x = x;
				vertex.geometry.y = y;
					
				graph.addCell(vertex);
				graph.setSelectionCell(vertex);
			}
			
			// Creates the image which is used as the drag icon (preview)
			var img = toolbar.addMode(null, image, function(evt, cell)
			{
				var pt = this.graph.getPointForEvent(evt);
				funct(graph, evt, cell, pt.x, pt.y);
			});
			
			// Disables dragging if element is disabled. This is a workaround
			// for wrong event order in IE. Following is a dummy listener that
			// is invoked as the last listener in IE.
			mxEvent.addListener(img, 'mousedown', function(evt)
			{
				// do nothing
			});
			
			// This listener is always called first before any other listener
			// in all browsers.
			mxEvent.addListener(img, 'mousedown', function(evt)
			{
				if (img.enabled == false)
				{
					mxEvent.consume(evt);
				}
			});
						
			mxUtils.makeDraggable(img, graph, funct);
			
			return img;
		}

	</script>
</head>

<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
<body onload="main();" >
</body>
</html>

Please help me thanks in advance!!!

Defiance answered 1/6, 2019 at 9:14 Comment(1)
A quick glance around seems like you can query for the edge relations with getEdgeCount() , if there are none then update the style? See the mxCell docs here: jgraph.github.io/mxgraph/docs/js-api/files/model/mxCell-js.htmlSpadefish
F
10

Edit: As per the comment, to validate the cells not connected to the parent cell or its branches, we can use a recursive function checking each connected edge starts from the parent cell and so on.

Due to the limit of characters, the original code snippet is removed.

.not_connected * {
  color: red;
  font-color: red;
  stroke: red;
  stroke-color: red;
}
<!--
  Copyright (c) 2006-2013, JGraph Ltd
  
  Dynamic toolbar example for mxGraph. This example demonstrates changing the
  state of the toolbar at runtime.
-->
<html>

<head>
  <title>Toolbar example for mxGraph</title>

</head>

<!-- Calls the main function after the page has loaded. Container is dynamically created. -->

<body onload="main();">
  <button style="position:absolute; left:300px;padding:8px 40px;background:orangered;color:#fff;outline:none;border:none;z-index:100;" id="validate_btn">Validate</button>
</body>

</html>

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

  function setGraphData() {
    var graphState = {
      "tagName": "mxGraphModel",
      "children": [{
        "tagName": "root",
        "children": [{
          "tagName": "mxCell",
          "attributes": {
            "id": "0"
          }
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "1",
            "parent": "0"
          }
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "2",
            "value": "A",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "460",
              "y": "80",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "3",
            "value": "C",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "460",
              "y": "190",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "4",
            "edge": "1",
            "parent": "1",
            "source": "2",
            "target": "3"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "relative": "1",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "5",
            "value": "B",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "280",
              "y": "190",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "6",
            "value": "D",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "663",
              "y": "193",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "7",
            "edge": "1",
            "parent": "1",
            "source": "2",
            "target": "5"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "relative": "1",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "8",
            "edge": "1",
            "parent": "1",
            "source": "2",
            "target": "6"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "relative": "1",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "9",
            "value": "E",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "660",
              "y": "260",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "10",
            "edge": "1",
            "parent": "1",
            "source": "6",
            "target": "9"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "relative": "1",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "11",
            "value": "F",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "280",
              "y": "260",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "12",
            "value": "G",
            "style": "",
            "vertex": "1",
            "parent": "1"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "x": "459",
              "y": "257",
              "width": "100",
              "height": "40",
              "as": "geometry"
            }
          }]
        }, {
          "tagName": "mxCell",
          "attributes": {
            "id": "13",
            "edge": "1",
            "parent": "1",
            "source": "11",
            "target": "12"
          },
          "children": [{
            "tagName": "mxGeometry",
            "attributes": {
              "relative": "1",
              "as": "geometry"
            }
          }]
        }]
      }]
    };
    graphStateJSON = JSON.stringify(graphState);
  }

  function html2json(html) {
    if (html.nodeType == 3) {
      return {
        "tagName": "#text",
        "content": html.textContent
      }
    }
    var element = {
      "tagName": html.tagName
    };
    if (html.getAttributeNames().length > 0) {
      element.attributes = html.getAttributeNames().reduce(
        function(acc, at) {
          acc[at] = html.getAttribute(at);
          return acc;
        }, {}
      );
    }
    if (html.childNodes.length > 0) {
      element.children = Array.from(html.childNodes)
        .filter(
          function(el) {
            return el.nodeType != 3 ||
              el.textContent.trim().length > 0
          })
        .map(function(el) {
          return html2json(el);
        });
    }
    return element;
  }

  function json2html(json) {
    var xmlDoc = document.implementation.createDocument(null, json.tagName);
    var addAttributes = function(jsonNode, node) {
      if (jsonNode.attributes) {
        Object.keys(jsonNode.attributes).map(
          function(name) {
            node.setAttribute(name, jsonNode.attributes[name]);
          }
        );
      }
    }
    var addChildren = function(jsonNode, node) {
      if (jsonNode.children) {
        jsonNode.children.map(
          function(jsonChildNode) {
            json2htmlNode(jsonChildNode, node);
          }
        );
      }
    }
    var json2htmlNode = function(jsonNode, parent) {
      if (jsonNode.tagName == "#text") {
        return xmlDoc.createTextNode(jsonNode.content);
      }
      var node = xmlDoc.createElement(jsonNode.tagName);
      addAttributes(jsonNode, node);
      addChildren(jsonNode, node);
      parent.appendChild(node);
    }
    addAttributes(json, xmlDoc.firstElementChild);
    addChildren(json, xmlDoc.firstElementChild);
    return xmlDoc;
  }
</script>

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

<!-- Example code -->
<script type="text/javascript">
  // Program starts here. Creates a sample graph in the
  // DOM node with the specified ID. This function is invoked
  // from the onLoad event handler of the document (see below).
  var graph;
  var graphView;
  var notConnectedCells = [];
  var parentCellId = "2";

  function main() {
    setGraphData();
    // Checks if browser is supported
    if (!mxClient.isBrowserSupported()) {
      // Displays an error message if the browser is
      // not supported.
      mxUtils.error('Browser is not supported!', 200, false);
    } else {
      // Defines an icon for creating new connections in the connection handler.
      // This will automatically disable the highlighting of the source vertex.
      mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
      // Creates the div for the toolbar
      var tbContainer = document.createElement('div');
      tbContainer.style.position = 'absolute';
      tbContainer.style.overflow = 'hidden';
      tbContainer.style.padding = '2px';
      tbContainer.style.left = '0px';
      tbContainer.style.top = '0px';
      tbContainer.style.width = '24px';
      tbContainer.style.bottom = '0px';
      document.body.appendChild(tbContainer);
      // Creates new toolbar without event processing
      var toolbar = new mxToolbar(tbContainer);
      toolbar.enabled = false
      // Creates the div for the graph
      var container = document.createElement('div');
      container.style.position = 'absolute';
      container.style.overflow = 'hidden';
      container.style.left = '24px';
      container.style.top = '0px';
      container.style.right = '0px';
      container.style.bottom = '0px';
      container.style.background = 'url("editors/images/grid.gif")';
      document.body.appendChild(container);
      // Workaround for Internet Explorer ignoring certain styles
      if (mxClient.IS_QUIRKS) {
        document.body.style.overflow = 'hidden';
        new mxDivResizer(tbContainer);
        new mxDivResizer(container);
      }
      // Creates the model and the graph inside the container
      // using the fastest rendering available on the browser
      var model = new mxGraphModel();
      graph = new mxGraph(container, model);
      // Enables new connections in the graph
      graph.setConnectable(true);
      graph.setMultigraph(false);
      // Stops editing on enter or escape keypress
      var keyHandler = new mxKeyHandler(graph);
      var rubberband = new mxRubberband(graph);
      var addVertex = function(icon, w, h, style) {
        var vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
        vertex.setVertex(true);
        var img = addToolbarItem(graph, toolbar, vertex, icon);
        img.enabled = true;
        graph.getSelectionModel().addListener(mxEvent.CHANGE, function() {
          var tmp = graph.isSelectionEmpty();
          mxUtils.setOpacity(img, (tmp) ? 100 : 20);
          img.enabled = tmp;
        });
      };
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rectangle.gif', 100, 40, '');
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rounded.gif', 100, 40, 'shape=rounded');
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/triangle.gif', 40, 40, 'shape=triangle');
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
      addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/actor.gif', 30, 40, 'shape=actor');
      // read state on load 
      if (graphStateJSON) {
        var doc = json2html(JSON.parse(graphStateJSON));
        var dec = new mxCodec(doc);
        dec.decode(doc.documentElement, graph.getModel());
      }
      // save state on change
      graph.getModel().addListener('change', function() {
        var codec = new mxCodec();
        graphStateJSON = JSON.stringify(html2json(codec.encode(
          graph.getModel()
        )));
      });
    }
  }

  function addToolbarItem(graph, toolbar, prototype, image) {
    // Function that is executed when the image is dropped on
    // the graph. The cell argument points to the cell under
    // the mousepointer if there is one.
    var funct = function(graph, evt, cell, x, y) {
      graph.stopEditing(false);
      var vertex = graph.getModel().cloneCell(prototype);
      vertex.geometry.x = x;
      vertex.geometry.y = y;
      graph.addCell(vertex);
      graph.setSelectionCell(vertex);
    }
    // Creates the image which is used as the drag icon (preview)
    var img = toolbar.addMode(null, image, function(evt, cell) {
      var pt = this.graph.getPointForEvent(evt);
      funct(graph, evt, cell, pt.x, pt.y);
    });
    // Disables dragging if element is disabled. This is a workaround
    // for wrong event order in IE. Following is a dummy listener that
    // is invoked as the last listener in IE.
    mxEvent.addListener(img, 'mousedown', function(evt) {
      // do nothing
    });
    // This listener is always called first before any other listener
    // in all browsers.
    mxEvent.addListener(img, 'mousedown', function(evt) {
      if (img.enabled == false) {
        mxEvent.consume(evt);
      }
    });
    mxUtils.makeDraggable(img, graph, funct);
    return img;
  }

  function Validate(mxCell){
        let isConnected = true;
        // check each cell that each edge connected to
        for(let i=0;i<mxCell.getEdgeCount();i++){
            let edge = mxCell.getEdgeAt(i);

            if(edge.target === null) continue; // no target
            if(mxCell.getId() === edge.target.getId()) continue; // target is mxCell itself
            
            isConnected = edge.source !== null && edge.target !== null;
            if(isConnected){
                // remove source cell if found and so on
                let sourceIndex = notConnectedCells.findIndex(c=>c.id === edge.source.getId());
                if(sourceIndex !== -1) notConnectedCells.splice(sourceIndex,1);

                let targetIndex = notConnectedCells.findIndex(c=>c.id === edge.target.getId());
                if(targetIndex !== -1) notConnectedCells.splice(targetIndex,1);

                let edgeIndex = notConnectedCells.findIndex(c=>c.id === edge.getId());
                if(edgeIndex !== -1) notConnectedCells.splice(edgeIndex,1);

                // check next cell and its edges
                Validate(edge.target);
            }
        }
    }

    function ResetColor(state){
        state.shape.node.classList.remove("not_connected");
        if(state.text)
            state.text.node.classList.remove("not_connected");
    }

    function SetNotConnectedColor(state){
        for(let i=0;i<notConnectedCells.length;i++){
            let mxCell = notConnectedCells[i];
            let state = graphView.getState(mxCell);
            state.shape.node.classList.add("not_connected");
            if(state.text)
                state.text.node.classList.add("not_connected");
        }
    }

    document.querySelector("#validate_btn").addEventListener("click", function() {
        
        let cells = graph.getModel().cells;
        graphView = graph.getView();
        notConnectedCells.length = 0;

        // create an array of cells and reset the color
        for(let key in cells){
            if(!cells.hasOwnProperty(key)) continue;

            let mxCell = cells[key];
            if(!mxCell.isVertex() && !mxCell.isEdge()) continue;
            notConnectedCells.push(mxCell);
            let state = graphView.getState(mxCell);
            ResetColor(state);
        }
        
        // starts with the parent cell
        let parentCell = notConnectedCells.find(c=>c.id === parentCellId);
        Validate(parentCell);

        SetNotConnectedColor();
    })
</script>

First, set graph to a global variable. (var graph = new mxGraph(container, model);)

Then, get all cells(as an object) and graphView from graph and iterate all the cells checking if it's connected or not.

function Validate(){
    let cells = graph.getModel().cells;
    let graphView = graph.getView();

    for(let key in cells){
        if(!cells.hasOwnProperty(key)) continue;

        let mxCell = cells[key];
        if(!mxCell.isVertex() && !mxCell.isEdge()) continue;

        let state = graphView.getState(mxCell);
        ResetColor(state);

        let notConnected = true;
        if(mxCell.isVertex()){
            for(let i=0;i<mxCell.getEdgeCount();i++){
                let edge = mxCell.getEdgeAt(i);
                // if any of an edge connected to both source and target, it's connected
                if(edge.source !== null && edge.target !== null){
                    notConnected = false;
                    break;
                }
            }
        }
        else { // mxCell.isEdge()
            notConnected = mxCell.source === null || mxCell.target === null;
        }

        if(notConnected) SetNotConnectedColor(state);
    }
}

function ResetColor(state){
    state.shape.node.classList.remove("not_connected");
    if(state.text)
        state.text.node.classList.remove("not_connected");
}

function SetNotConnectedColor(state){
    state.shape.node.classList.add("not_connected");
    if(state.text)
        state.text.node.classList.add("not_connected");
}

document.querySelector("#validate_btn").addEventListener("click", function(){
    Validate();
})

And here's the localStorage version code if you want(codepen)

Fideicommissary answered 21/6, 2019 at 0:49 Comment(8)
That's really a great solution!!!, but I want reference to be A for all validation, if it is having parent as A then it is connected. For the sake of understanding here n, m is not connected to A even though is validated as correct. See codepen codepen.io/eabangalore/pen/MMogywDefiance
How can we tell that n, m are having the same parent as A from the pen you provided?Fideicommissary
For the sake of my problem consider A as a parent for every other node(I, e m, n.. )Defiance
Your question: if m, n is having closest or farthest parent as A then it is connected.Defiance
Please check the links again since they're all the same and considering update the question to the post for future readers.Fideicommissary
hi @Hikarunomemory, please consider this example for connectedness and unconnectedness. you are the only hope for me. 1.connected : codepen.io/eabangalore/pen/vqZQew 3.connected : codepen.io/eabangalore/pen/ZdymRv 2.unconnected : codepen.io/eabangalore/pen/WqOYMo 4.unconnected : codepen.io/eabangalore/pen/rEwQrvDefiance
hi @Hikarunomemory, have seen my all codepen?? please reply if you have not seen it.Defiance
I have already seen all of them and edited my post. If this is not what you want, please edit your question and give us some examples include the input(graphState) and expected output(in which case that some of the cells and edges would be highlighted)Fideicommissary

© 2022 - 2024 — McMap. All rights reserved.