API Docs for: 0.6.0
Show:

File: src/visualization/DraculaGraph.js


        /**
         * Draws a graph with clickable and movable nodes.
         *
         * Input format:
         *
         *  - 7 columns, last three are optional.
         *  - each row represents a source node, a target node and an edge from source to target.
         *  - the URIs are the id's for the nodes, and make the nodes clickable.
         *
         * Columns:
         *
         *  1. sourceURI
         *  2. sourceLabel
         *  3. targetURI
         *  4. targetLabel
         *  5. edgeLabel
         *  6. sourceColor
         *  7. targetColor
         *
         * @class sgvizler.visualization.DraculaGraph
         * @extends sgvizler.charts.Chart
         * @constructor
         * @param {Object} container The container element where the
         * chart will be drawn.
         * @beta
         * @author Magnus Stuhr, Martin G. Skjæveland
         */

        /**
         * @method draw
         * @public
         * @param {google.visualization.DataTable} data
         * @param {Object} [chartOptions]
         * @since 0.5.1
         */
        /*global Dracula */
        C.DraculaGraph = charts.add(modSC, "DraculaGraph",
            function (data, chartOpt) {

                var row, numberOfRows = data.getNumberOfRows(),
                    i, len,
                    numberOfColumns = data.getNumberOfColumns(),

                    // set defaults.
                    opt = $.extend({
                        noderadius: 0.5,
                        nodefontsize: "10px",
                        nodeheight: 20,
                        nodestrokewidth: "1px",
                        directed: false,
                        nodecornerradius: "1px",
                        nodepadding: 7,
                        nodecolor: "green",
                        edgestroke: "blue",
                        edgefill: "blue",
                        edgestrokewidth: 1,
                        edgefontsize: "10px",
                        edgeseparator: ", "
                    }, chartOpt),

                    graph = new Dracula.Graph(),
                    layouter,
                    renderer,
                    edge,
                    source,
                    target,
                    label,

                    // custom node rendering using Raphael.
                    nodeRenderer = function (color, URL) {
                        return function (r, n) {
                            return r.set()
                                // rectangle
                                .push(r.rect(n.point[0],
                                             n.point[1],
                                             n.label.length * opt.nodepadding,
                                             opt.nodeheight)
                                      .attr({fill: color,
                                             'stroke-width': opt.nodestrokewidth,
                                             r : opt.nodecornerradius}))
                                // label inside rectangle
                                .push(r.text(n.point[0] + n.label.length * opt.nodepadding / 2,
                                             n.point[1] + opt.nodeheight / 2,
                                             n.label)
                                      .attr({'font-size': opt.nodefontsize})
                                      .click(function () { if (URL) { window.open(namespace.unprefixify(URL)); } })
                                     );
                        };
                    },

                    // helper function.
                    addNode = function (URL, name, color) {
                        graph.addNode(URL, {label: name, render: nodeRenderer(color, URL)});
                        //console.log("add node - name: " + name + ", URL: " + URL);
                    },
                    edges = {},
                    keys_edges = [];

                for (row = 0; row < numberOfRows; row += 1) {
                    source = data.getValue(row, 0);
                    target = data.getValue(row, 2);

                    // add source node
                    // Note: does dracula take care of duplicates?
                    if (source) {
                        addNode(source,
                                data.getValue(row, 1) || source,
                                numberOfColumns > 5 ? data.getValue(row, 5) : opt.nodecolor);
                    }
                    // add target node
                    if (target) {
                        addNode(target,
                                data.getValue(row, 3) || target,
                                numberOfColumns > 6 ? data.getValue(row, 6) : opt.nodecolor);
                    }

                    // collect edge labels. Only one edge per pair of nodes,
                    // so we concatinate labels of multiple edges into one.
                    if (source && target) {
                        label = "";
                        // test if source--target pair is seen before:
                        if (edges[source + target] !== undefined) {
                            label = edges[source + target].label; // retrieve accumulated label.
                        } else {
                            keys_edges.push(source + target);
                        }

                        if (numberOfColumns > 4 && data.getValue(row, 4).length > 0) {
                            if (label.length > 0) {
                                label += opt.edgeseparator;
                            }
                            label += data.getValue(row, 4);
                        }

                        edges[source + target] = {
                            source: source,
                            target: target,
                            label: label
                        };
                    }
                }

                // add edges
                for (i = 0, len = keys_edges.length; i < len; i += 1) {
                    edge = edges[keys_edges[i]];
                    //console.log("add edge - source: " + edge.source + ", target " + edge.target);
                    graph.addEdge(edge.source, edge.target,
                                  { stroke: opt.edgestroke,
                                    directed: opt.directed,
                                    fill: opt.edgefill,
                                    label: edge.label,
                                    width: opt.edgestrokewidth,
                                    fontsize: opt.edgefontsize
                                  });
                }

                layouter = new Dracula.Graph.Layout.Spring(graph);
                layouter.layout();

                $(this.container).empty();
                renderer = new Dracula.Graph.Renderer.Raphael(
                    this.container,
                    graph,
                    opt.width,
                    opt.height,
                    { noderadius : opt.nodeheight * opt.noderadius}
                );
                renderer.draw();

                this.fireListener('ready');
            },
            { Dracula: 'http://www.data2000.no/sgvizler/lib/raphael-dracula.min.js' }
            );