UNPKG

nvd3-fork

Version:

FORK! of NVD3, a reusable charting library written in d3.js

192 lines (164 loc) 7.36 kB
nv.models.forceDirectedGraph = function() { "use strict"; //============================================================ // Public Variables with Default Settings //------------------------------------------------------------ var margin = {top: 2, right: 0, bottom: 2, left: 0} , width = 400 , height = 32 , container = null , dispatch = d3.dispatch('renderEnd') , color = nv.utils.getColor(['#000']) , tooltip = nv.models.tooltip() , noData = null // Force directed graph specific parameters [default values] , linkStrength = 0.1 , friction = 0.9 , linkDist = 30 , charge = -120 , gravity = 0.1 , theta = 0.8 , alpha = 0.1 , radius = 5 // These functions allow to add extra attributes to ndes and links ,nodeExtras = function(nodes) { /* Do nothing */ } ,linkExtras = function(links) { /* Do nothing */ } , getX=d3.functor(0.0) , getY=d3.functor(0.0) ; //============================================================ // Private Variables //------------------------------------------------------------ var renderWatch = nv.utils.renderWatch(dispatch); function chart(selection) { renderWatch.reset(); selection.each(function(data) { container = d3.select(this); nv.utils.initSVG(container); var availableWidth = nv.utils.availableWidth(width, container, margin), availableHeight = nv.utils.availableHeight(height, container, margin); container .attr("width", availableWidth) .attr("height", availableHeight); // Display No Data message if there's nothing to show. if (!data || !data.links || !data.nodes) { nv.utils.noData(chart, container) return chart; } else { container.selectAll('.nv-noData').remove(); } container.selectAll('*').remove(); // Collect names of all fields in the nodes var nodeFieldSet = new Set(); data.nodes.forEach(function(node) { var keys = Object.keys(node); keys.forEach(function(key) { nodeFieldSet.add(key); }); }); var force = d3.layout.force() .nodes(data.nodes) .links(data.links) .size([availableWidth, availableHeight]) .linkStrength(linkStrength) .friction(friction) .linkDistance(linkDist) .charge(charge) .gravity(gravity) .theta(theta) .alpha(alpha) .start(); var link = container.selectAll(".link") .data(data.links) .enter().append("line") .attr("class", "nv-force-link") .style("stroke-width", function(d) { return Math.sqrt(d.value); }); var node = container.selectAll(".node") .data(data.nodes) .enter() .append("g") .attr("class", "nv-force-node") .call(force.drag); node .append("circle") .attr("r", radius) .style("fill", function(d) { return color(d) } ) .on("mouseover", function(evt) { container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex) .attr('y1', evt.py); container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex) .attr('x2', evt.px); // Add 'series' object to var nodeColor = color(evt); evt.series = []; nodeFieldSet.forEach(function(field) { evt.series.push({ color: nodeColor, key: field, value: evt[field] }); }); tooltip.data(evt).hidden(false); }) .on("mouseout", function(d) { tooltip.hidden(true); }); tooltip.headerFormatter(function(d) {return "Node";}); // Apply extra attributes to nodes and links (if any) linkExtras(link); nodeExtras(node); force.on("tick", function() { link.attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); node.attr("transform", function(d) { return "translate(" + d.x + ", " + d.y + ")"; }); }); }); return chart; } //============================================================ // Expose Public Variables //------------------------------------------------------------ chart.options = nv.utils.optionsFunc.bind(chart); chart._options = Object.create({}, { // simple options, just get/set the necessary values width: {get: function(){return width;}, set: function(_){width=_;}}, height: {get: function(){return height;}, set: function(_){height=_;}}, // Force directed graph specific parameters linkStrength:{get: function(){return linkStrength;}, set: function(_){linkStrength=_;}}, friction: {get: function(){return friction;}, set: function(_){friction=_;}}, linkDist: {get: function(){return linkDist;}, set: function(_){linkDist=_;}}, charge: {get: function(){return charge;}, set: function(_){charge=_;}}, gravity: {get: function(){return gravity;}, set: function(_){gravity=_;}}, theta: {get: function(){return theta;}, set: function(_){theta=_;}}, alpha: {get: function(){return alpha;}, set: function(_){alpha=_;}}, radius: {get: function(){return radius;}, set: function(_){radius=_;}}, //functor options x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}}, y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}}, // options that require extra logic in the setter margin: {get: function(){return margin;}, set: function(_){ margin.top = _.top !== undefined ? _.top : margin.top; margin.right = _.right !== undefined ? _.right : margin.right; margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom; margin.left = _.left !== undefined ? _.left : margin.left; }}, color: {get: function(){return color;}, set: function(_){ color = nv.utils.getColor(_); }}, noData: {get: function(){return noData;}, set: function(_){noData=_;}}, nodeExtras: {get: function(){return nodeExtras;}, set: function(_){ nodeExtras = _; }}, linkExtras: {get: function(){return linkExtras;}, set: function(_){ linkExtras = _; }} }); chart.dispatch = dispatch; chart.tooltip = tooltip; nv.utils.initOptions(chart); return chart; };