3

Network graph dynamically in javascript

 2 years ago
source link: https://dev.to/zkel/network-graph-dynamically-in-javascript-3p2c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Zkel

Posted on Mar 21

Network graph dynamically in javascript

Hello everyone, I want to create a graph network dynamically in js, I have found vis library to achieve my goal.Also, I would like to add some events when I clicked in a node or in an edge. I have done this but I have a problem. When I double click in a node, I show a pop-up and I have to add some extra info about the node. This info I want to save and when I double click again the same node, I want to have it. This unfortunately does not happen, I lost my info when i click save. Can you help me how to fix this problem?
Thank you!
Here is my code,

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Vis Network | Manipulation | Edit Edge Without Drag</title>

    <style type="text/css">
      body,
      select {
        font: 10pt sans;
      }
      #mynetwork {
        position: relative;
        width: 850px;
        height: 400px;
        border: 1px solid lightgray;
      }
      table.legend_table {
        font-size: 11px;
        border-width: 1px;
        border-color: #d3d3d3;
        border-style: solid;
      }
      table.legend_table,
      td {
        border-width: 1px;
        border-color: #d3d3d3;
        border-style: solid;
        padding: 2px;
      }
      div.table_content {
        width: 80px;
        text-align: center;
      }
      div.table_description {
        width: 100px;
      }
      #operation {
        font-size: 28px;
      }
      #popUp{
        display: none;
        position: absolute;
        top: 350px;
        left: 170px;
        z-index: 299;
        width: 250px;
        height: 120px;
        background-color: #f9f9f9;
        border-style: solid;
        border-width: 3px;
        border-color: #5394ed;
        padding: 10px;
        text-align: center;
      }
      #node-popUp {
        display: none;
        position: absolute;
        top: 350px;
        left: 170px;
        z-index: 299;
        width: 250px;
        height: 120px;
        background-color: #f9f9f9;
        border-style: solid;
        border-width: 3px;
        border-color: #5394ed;
        padding: 10px;
        text-align: center;
      }
      #edge-popUp {
        display: none;
        position: absolute;
        top: 350px;
        left: 170px;
        z-index: 299;
        width: 250px;
        height: 90px;
        background-color: #f9f9f9;
        border-style: solid;
        border-width: 3px;
        border-color: #5394ed;
        padding: 10px;
        text-align: center;
      }
    </style>

    <script
      type="text/javascript"
      src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>

    <script
      type="text/javascript"
      src="https://unpkg.com/[email protected]/alea.js"></script>
    <script 
      type="text/javascript" 
      src="..\exampleUtils.js"></script>

    <script type="text/javascript">
      var nodes = null;
      var edges = null;
      var network = null;
      // randomly create some nodes and edges
      var data = getScaleFreeNetwork(0);
      var seed = 2;

      function setDefaultLocale() {
        var defaultLocal = navigator.language;
        var select = document.getElementById("locale");
        select.selectedIndex = 0; // set fallback value
        for (var i = 0, j = select.options.length; i < j; ++i) {
          if (select.options[i].getAttribute("value") === defaultLocal) {
            select.selectedIndex = i;
            break;
          }
        }
      }

      function destroy() {
        if (network !== null) {
          network.destroy();
          network = null;
        }
      }

      function draw() {
        destroy();
        nodes = new vis.DataSet();//[];
        edges = new vis.DataSet();//[];

        // create a network
        var container = document.getElementById("mynetwork");
        var options = {
          layout: { randomSeed: seed }, // just to make sure the layout is the same when the locale is changed
          locale: document.getElementById("locale").value,
          manipulation: {
            addNode: function (data, callback) {
              // filling in the popup DOM elements
              document.getElementById("node-operation").innerText = "Add Node";
              console.log('Data Node', data);
              editNode(data, clearNodePopUp, callback);
              console.log('Saved Data', data);
            },
            editNode: function (data, callback) {
              // filling in the popup DOM elements
              document.getElementById("node-operation").innerText = "Edit Node";
              editNode(data, cancelNodeEdit, callback);
            },
            addEdge: function (data, callback) {
              if (data.from == data.to) {
                var r = confirm("Do you want to connect the node to itself?");
                if (r != true) {
                  callback(null);
                  return;
                }
              }
              document.getElementById("edge-operation").innerText = "Add Edge";
              editEdgeWithoutDrag(data, callback);
            },
            editEdge: {
              editWithoutDrag: function (data, callback) {
                document.getElementById("edge-operation").innerText =
                  "Edit Edge";
                editEdgeWithoutDrag(data, callback);
              },
            },
          },
        };
        network = new vis.Network(container, data, options);
        network.on("doubleClick", function (data, callback) {
          console.log('Data Double Click', data);
            document.getElementById("eventSpanHeading").innerText = "doubleClick event:";
            if(data.nodes.length){
              document.getElementById("node-operation").innerText = "Add Node Data";
              console.log('Data', data);
              addNodeData(data,clearNodePopUp,callback);
            }
            if(data.edges.length){
              document.getElementById("edge-operation").innerText = "Add Edge Data";
              addEdgeData(data,clearEdgePopUp,callback);
            }
        });
        // rigth click 
        network.on("oncontext", function (data, callback) {
        data.event = "[original event]";
        document.getElementById("eventSpanHeading").innerText = "Right Click Event";
        console.log('my data', data);
        if(data.nodes.length){
              // var node = data.nodes[0];
              document.getElementById("node-operation").innerText = "Edit Node Data";
              console.log('Data', data);
              addNodeData(data,cancelNodeEdit,callback);
              console.log('New Data', data);
            }
            if(data.edges.length){
              document.getElementById("edge-operation").innerText = "Edit Edge Data";
              addEdgeData(data,cancelEdgeEdit,callback);
            }
        });

      }  
      // add extra info for nodes
      function addNodeData(data,callback){

        editNode(data,clearNodePopUp,callback);  
      }
      // add extra info for edges
      function addEdgeData(data,callback){

        editEdgeWithoutDrag(data,callback);

      }

      function editNode(data, cancelAction, callback) {
        document.getElementById("node-label").value = data.label;
        document.getElementById("node-saveButton").onclick = saveNodeData.bind(this,data,callback);
        document.getElementById( "node-cancelButton").onclick = cancelAction.bind(this, callback);
        document.getElementById("node-popUp").style.display = "block";
      }

      // Callback passed as parameter is ignored
      function clearNodePopUp() {
        document.getElementById("node-saveButton").onclick = null;
        document.getElementById("node-cancelButton").onclick = null;
        document.getElementById("node-popUp").style.display = "none";
      }

      function cancelNodeEdit(callback) {
        clearNodePopUp();
        callback(null);
      }

      function saveNodeData(data, callback) {
        console.log('Data', data);
        data.label = document.getElementById("node-label").value;
        clearNodePopUp();
        callback(data);
        console.log('New data', data);
      }

      function editEdgeWithoutDrag(data, callback) {
        // filling in the popup DOM elements
        document.getElementById("edge-label").value = data.label;
        document.getElementById("edge-saveButton").onclick = saveEdgeData.bind(this,data,callback);
        document.getElementById( "edge-cancelButton").onclick = cancelEdgeEdit.bind(this, callback);
        document.getElementById("edge-popUp").style.display = "block";
      }

      function clearEdgePopUp() {
        document.getElementById("edge-saveButton").onclick = null;
        document.getElementById("edge-cancelButton").onclick = null;
        document.getElementById("edge-popUp").style.display = "none";
      }

      function cancelEdgeEdit(callback) {
        clearEdgePopUp();
        callback(null);
      }

      function saveEdgeData(data, callback) {
        if (typeof data.to === "object") data.to = data.to.id;
        if (typeof data.from === "object") data.from = data.from.id;
        data.label = document.getElementById("edge-label").value;
        clearEdgePopUp();
        callback(data);
      }

      function init() {
        setDefaultLocale();
        draw();
      }
    </script>
  </head>

  <body onload="init();">
    <h2>Editing the nodes and edges-without-drag (localized)</h2>
    <p style="width: 700px; font-size: 14px; text-align: justify">
      The localization is only relevant to the manipulation buttons.
    </p>

    <p>
      <label for="locale">Select a locale:</label>
      <select id="locale" onchange="draw();">
        <option value="en">en</option>
        <option value="cn">cn</option>
        <option value="cs">cs</option>
        <option value="de">de</option>
        <option value="es">es</option>
        <option value="fr">fr</option>
        <option value="it">it</option>
        <option value="nl">nl</option>
        <option value="pt-br">pt</option>
        <option value="ru">ru</option>
        <option value="uk">uk</option>
      </select>
    </p>
    <!--Node part-->
    <div id="node-popUp">
      <span id="node-operation">node</span> <br />
      <table style="margin: auto">
        <tr>
          <td>id</td>
          <td><input id="node-id" value="new value" /></td>
        </tr>
        <tr>
          <td>label</td>
          <td><input id="node-label" value="new value" /></td>
        </tr>
      </table>
      <input type="button" value="save" id="node-saveButton" />

      <input type="button" value="cancel" id="node-cancelButton" />
    </div>
    <!--Edge Part-->
    <div id="edge-popUp">
      <span id="edge-operation">edge</span> <br />
      <table style="margin: auto">
        <tr>
          <td>label</td>
          <td><input id="edge-label" value="new value" /></td>
        </tr>
      </table>
      <input type="button" value="save" id="edge-saveButton" />
      <input type="button" value="cancel" id="edge-cancelButton" />
    </div>
    <br />
    <div id="mynetwork"></div>
    <h2 id="eventSpanHeading"></h2>
  </body>
</html>

Enter fullscreen mode

Exit fullscreen mode


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK