All versions of this documentation
X

CSV

This example shows how to transform a CSV file into a Ogma's network visualization. The dataset contains edges network data for character relationships within George R. R. Martin's A Storm of Swords, the third novel in his series A Song of Ice and Fire (also known as the HBO television adaptation Game of Thrones). This data was originally compiled by A. Beveridge and J. Shan, "Network of Thrones," Math Horizons Magazine , Vol. 23, No. 4 (2016), pp. 18-22.. The Papa Parse library is used to correctly parse the CSV file.

Open in a new window.
          <!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <script src="../build/ogma.min.js"></script>
    <link href="fonts/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js"
        integrity="sha256-Fh801SO9gqegfUdkDxyzXzIUPWzO/Vatqj8uN+5xcL4=" crossorigin="anonymous"></script>
    <style>
        #graph-container {
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            position: absolute;
            margin: 0;
            overflow: hidden;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            -o-user-select: none;
            user-select: none;
        }

        .toolbar {
            display: block;
            position: absolute;
            top: 20px;
            right: 20px;
            padding: 10px;
            box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
            border-radius: 4px;
            background: #ffffff;
            color: #222222;
            font-weight: 300;
            max-width: 350px;
        }

        .controls {
            text-align: center;
            margin-top: 5px;
        }

        .btn {
            padding: 6px 8px;
            background-color: white;
            cursor: pointer;
            font-size: 18px;
            border: none;
            border-radius: 5px;
            outline: none;
        }

        .btn:hover {
            color: #333;
            background-color: #e6e6e6;
        }

        .menu {
            border: 1px solid #ddd;
            width: 80%;
            font-size: 14px;
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <div id="graph-container"></div>
    <div class="toolbar">
        <div class="controls">
            <button id="load-csv" class="btn menu">Click to load CSV</button>
        </div>
    </div>

    <script>
        'use strict';

        var ogma = new Ogma({
            container: 'graph-container',
        });

        // some UI logic

        function layout() {
            return ogma.layouts.force({
                locate: { padding: 80 },
            });
        }


        // Add some edge styling rules
        ogma.styles.addEdgeRule({
            color: function (e) {
                return '#80ce87';
            },
            shape: "arrow",
            width: function (e) {
                return Math.log(e.getData("weight"));
            }
        });

        // Add some node styling rules
        ogma.styles.addNodeRule({
            text: {
                content: function (n) {
                    return n.getData("label");
                },
                minVisibleSize: 2
            },
            radius: function (n) {
                return n.getDegree();
            },
            icon: {
                content: function (n) {
                    return "\uf2c0";
                },
                font: 'FontAwesome',
                color: 'rgb(61,139,223)',
                minVisibleSize: 0
            },
            outerStroke: {
                color: 'rgb(61,139,223)',
                width: 2
            },
            color: 'white'
        });

        function toRawGraph(results) {
            // format the incoming JSON to the RawGraph format

            // use a Set here to avoid duplicates
            var nodesSet = new Set();
            var edges = [];
            results.data.forEach(function (item, i) {
                nodesSet.add(item.source);
                nodesSet.add(item.target);
                // mind parallel edges
                var edgeId = item.source + "-" + item.target + "-" + i;
                // cast to Number numeric values as in CSV everything is a string!
                edges.push({
                    id: edgeId,
                    source: item.source,
                    target: item.target,
                    data: { weight: Number(item.weight) }
                })
            });

            // now iterate on the nodesSet to create the node list
            var nodes = [];
            nodesSet.forEach(function (id) {
                nodes.push({ id: id, data: { label: id } });
            });

            return ogma.setGraph({ nodes: nodes, edges: edges }).then(layout);
        }

        document.querySelector('#load-csv').addEventListener('click', function (evt) {
            // load the csv from the URL and parse it returning a JSON
            return Papa.parse('files/got-edges.csv', {
                download: true,
                header: true,
                complete: toRawGraph
            });
        });

    </script>
</body>

</html>