source: OpenRLabs-Git/deploy/rlabs-docker/web2py-rlabs/applications/admin/static/js/d3_graph.js

main
Last change on this file was 42bd667, checked in by David Fuertes <dfuertes@…>, 4 years ago

Historial Limpio

  • Property mode set to 100755
File size: 5.9 KB
Line 
1function d3_graph() {
2
3// Some reference links:
4//   How to get link ids instead of index
5//     http://stackoverflow.com/questions/23986466/d3-force-layout-linking-nodes-by-name-instead-of-index
6//   embedding web2py in d3
7//     http://stackoverflow.com/questions/34326343/embedding-d3-js-graph-in-a-web2py-bootstrap-page
8
9// nodes and links are defined in appadmin.html <script>
10
11
12    var edges = [];
13
14    links.forEach(function(e) {
15        var sourceNode = nodes.filter(function(n) {
16            return n.name === e.source;
17        })[0],
18            targetNode = nodes.filter(function(n) {
19            return n.name === e.target;
20        })[0];
21
22        edges.push({
23            source: sourceNode,
24            target: targetNode,
25            value: 1});
26
27    });
28
29    edges.forEach(function(e) {
30
31        if (!e.source["linkcount"]) e.source["linkcount"] = 0;
32        if (!e.target["linkcount"]) e.target["linkcount"] = 0;
33
34        e.source["linkcount"]++;
35        e.target["linkcount"]++;
36    });
37
38    //var width = 960, height = 600;
39    var height = window.innerHeight|| docEl.clientHeight|| bodyEl.clientHeight;
40    var width = window.innerWidth || docEl.clientWidth || bodyEl.clientWidth;
41    var svg = d3.select("#vis").append("svg")
42            .attr("width", width)
43            .attr("height", height);
44
45       // updated for d3 v4.
46    var simulation = d3.forceSimulation()
47            .force("link", d3.forceLink().id(function(d) { return d.id; }))
48            .force("charge", d3.forceManyBody().strength(strength))
49            .force("center", d3.forceCenter(width / 2, height / 2))
50            .force("collision", d3.forceCollide(35));
51
52    // Node charge strength.  Repel strength greater for less links.
53    //function strength(d) { return -50/d["linkcount"] ; }
54    function strength(d) { return -25 ; } 
55   
56    // Link distance.  Distance increases with number of links at source and target
57    function distance(d) { return (60 + (d.source["linkcount"] * d.target["linkcount"])) ; }
58   
59    // Link strength.  Strength is less for highly connected nodes (move towards target dist)
60    function strengthl(d) { return 5/(d.source["linkcount"] + d.target["linkcount"]) ; }
61
62    simulation
63        .nodes(nodes)
64        .on("tick", tick);
65
66    simulation.force("link")
67        .links(edges)
68        .distance(distance)
69        .strength(strengthl);
70
71    // build the arrow.
72    svg.append("svg:defs").selectAll("marker")
73        .data(["end"])      // Different link/path types can be defined here
74        .enter().append("svg:marker")    // This section adds in the arrows
75        .attr("id", String)
76        .attr("viewBox", "0 -5 10 10")
77        .attr("refX", 25)   // Moves the arrow head out, allow for radius
78        .attr("refY", 0)   // -1.5
79        .attr("markerWidth", 6)
80        .attr("markerHeight", 6)
81        .attr("orient", "auto")
82        .append("svg:path")
83        .attr("d", "M0,-5L10,0L0,5");
84
85    var link = svg.selectAll('.link')
86        .data(edges)
87        .enter().append('line')
88        .attr("class", "link")
89        .attr("marker-end", "url(#end)");
90
91    var node = svg.selectAll(".node")
92        .data(nodes)
93        .enter().append("g")
94        .attr("class", function(d) { return "node " + d.type;})
95        .attr('transform', function(d) {
96            return "translate(" + d.x + "," + d.y + ")"})
97        .classed("auth", function(d) { return (d.name.startsWith("auth") ? true : false);});
98
99    node.call(d3.drag()
100            .on("start", dragstarted)
101            .on("drag", dragged)
102            .on("end", dragended));
103
104    // add the nodes
105    node.append('circle')
106        .attr('r', 16)
107        ;
108
109    // add text
110    node.append("text")
111        .attr("x", 12)
112        .attr("dy", "-1.1em")
113        .text(function(d) {return d.name;});
114
115    node.on("mouseover", function(d) {
116
117        var g = d3.select(this);  // the node (table)
118
119        // tooltip
120
121        var fields = d.fields;
122        var fieldformat = "<TABLE>";
123        fields.forEach(function(d) {
124            fieldformat += "<TR><TD><B>"+ d.name+"</B></TD><TD>"+ d.type+"</TD><TD>"+ d.disp+"</TD></TR>";
125        });
126        fieldformat += "</TABLE>";
127        var tiplength = d.fields.length;
128
129        // Define 'div' for tooltips
130        var div = d3.select("body").append("div")  // declare the tooltip div
131                .attr("class", "tooltip")              // apply the 'tooltip' class
132            .style("opacity", 0)
133            .html('<h5>' + d.name + '</h5>' + fieldformat)
134            .style("left", 20 + (d3.event.pageX) + "px")// or just (d.x + 50 + "px")
135            .style("top", tooltop(tiplength))// or ...
136            .transition()
137            .duration(800)
138            .style("opacity", 0.9);
139        });
140
141        function tooltop(tiplength) {
142           //aim to ensure tooltip is fully visible whenver possible
143           return (Math.max(d3.event.pageY - 20 - (tiplength * 14),0)) + "px"
144        }
145
146        node.on("mouseout", function(d) {
147            d3.select("body").select('div.tooltip').remove();
148    });
149
150    // instead of waiting for force to end with :     force.on('end', function()
151    // use .on("tick",  instead.  Here is the tick function
152    function tick() {
153        node.attr('transform', function(d) {
154            d.x = Math.max(30, Math.min(width - 16, d.x));
155            d.y = Math.max(30, Math.min(height - 16, d.y));
156            return "translate(" + d.x + "," + d.y + ")"; });
157
158        link.attr('x1', function(d) {return d.source.x;})
159            .attr('y1', function(d) {return d.source.y;})
160            .attr('x2', function(d) {return d.target.x;})
161            .attr('y2', function(d) {return d.target.y;});
162    };
163
164    function dragstarted(d) {
165        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
166        d.fx = d.x;
167        d.fy = d.y;
168    };
169
170    function dragged(d) {
171        d.fx = d3.event.x;
172        d.fy = d3.event.y;
173    };
174
175    function dragended(d) {
176        if (!d3.event.active) simulation.alphaTarget(0);
177        d.fx = null;
178        d.fy = null;
179    };
180
181};
Note: See TracBrowser for help on using the repository browser.