Wiki Discussion: Generating Cytoscape.js graphs with SWI-Prolog

Another example.

This one passes the data as JSON and not as JSON wrapped with a JavaScript variable. This is important because JSON is much easier to validate as input when being accepted for use on a web site. With SWI-Prolog the validation of the JSON can be done with DCGs and quasiquotations. (ref)

Uses
a. JavaScript promises.
b. JavaScript fetch

This has two buttons that will display data in the Internet browser console. F12 for Chrome, FireFox or Edge.

  1. Show the same JSON data used by cytoscpae()
  2. Demonstrates how to select values from the Cytoscape.js objects using JavaScript array map

This is just code for demonstration purposes; it has not been enhanced for production use.

Since this code uses JavaScript fetch, a server is required to pass the files to the Internet browser. If you are on Windows and install node.js you can start the server by clicking on http_server.lnk, then access the page as noted by the node.js startup messages.

Details - Click triangle to expand.

You will need to create http_server.lnk with the properties

Target: C:\Windows\System32\cmd.exe /k "http_server.bat"
Start in: Clear field so it is empty

http_server.bat

SET PATH=%ProgramFiles%\nodejs;%AppData%\npm
http-server --cors

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Cytoscape.js - Example - pass data as JSON</title>
        <link rel="stylesheet" href="style.css">
        <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.15.2/cytoscape.min.js" integrity="sha512-PqivlaNWoXvHYlvku80fbWO/yBiRmGhISj5uVdAodyqsGprDcVZy6aecJDVNE0fIIE/YeiOzp5yJTR5ZjFlR4Q==" crossorigin="anonymous"></script>
        <script src="script.js" defer="defer"></script>
    </head>

    <body>
        <div id="cy"></div>
        <input type='button' id='showJson' value='Show JSON'>
        <input type='button' id='showPositions' value='Show Positions'>
    </body>

</html>

style.css

#cy {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
}
#showJson {
    font-size: 40px;
    font-weight: bold;
    width: 10%;
    height: 5%;
    position: absolute;
    top: 5%;
    right: 80%;
}
#showPositions {
    font-size: 40px;
    font-weight: bold;
    width: 10%;
    height: 5%;
    position: absolute;
    top: 15%;
    right: 80%;
}

script.js

Promise.all([
    fetch('/elements.json'),
    fetch('/style.json'),
    fetch('/layout.json')
]).then(function (responses) {
    return Promise.all(responses.map(function (response) {
        return response.json();
    }));
}).then(data => {
    cy = cytoscape(
        {
            container: document.getElementById('cy'),
            elements: data[0],
            style: data[1],
            layout: data[2]
        }
    );
    return cy
}).then(cy => {
    let showJsonButton = document.getElementById('showJson');
    showJsonButton.addEventListener('click', function () {
        console.log('Elements:');
        console.log( cy.elements().jsons() );   // Gets all elements - JSON
        console.log('Styles:');
        console.log( cy.style().json() );       // Gets all styles - JSON
        console.log('Layout:');
        console.log(cy.options().layout);       // Gets layout
    });

    let showPositionsButton = document.getElementById('showPositions');
    showPositionsButton.addEventListener('click', function () {
        let positions = cy.nodes().map(node => node.position());
        console.log('Positions:');
        console.log(positions);
    });
}).catch(function (error) {
    console.log(error);
});

elements.json

{
    "nodes": [
        { "data": { "id": "a" } },
        { "data": { "id": "b" } }
    ],
    "edges": [
        { "data": { "source": "a", "target": "b" } }
    ]
}

style.json

[
    {
        "selector": "node",
        "style": {
            "label": "data(id)"
        }
    },
    {
        "selector": "edge",
        "style": {
            "curve-style": "haystack"
        }
    }
]

layout.json

{
    "name": "grid"
}
1 Like