2015-04-29 63 views
0

我正在使用这个绝对正常的D3代码。D3 - 组合阵列

var width = 960, 
 
    height = 700, 
 
    r = 12, 
 
    gravity = 0.1, 
 
    distance = 100, 
 
    charge = -800, 
 
    fill = d3.scale.category10(), 
 

 
    nodes=[ 
 
     {name:"Start", performer:"admin", status:1, timestamp:"16-Aug-2014"}, 
 
     {name:"Dept Approver", performer:"admin", status:1, timestamp:"23-Aug-2014"}, 
 
     {name:"Amount>20", performer:"admin", status:1, timestamp:"23-Aug-2014"}, 
 
     {name:"Div Approver", performer:"admin", status:3, timestamp:"23-Aug-2014"}, 
 
     {name:"Section Aprpover", performer:"admin", status:1, timestamp:"23-Aug-2014"}, 
 
     {name:"End", performer:"admin", status:2, timestamp:"23-Aug-2014"} 
 
     ], 
 

 
    // the relations shown can be calculated using 
 
    // formulas from either 1 or 2 other quantities 
 
    links=[ 
 
     {"source":0,"target":1,"value":1}, {"source":1,"target":2,"value":1}, 
 
     {"source":2,"target":3,"value":1}, {"source":2,"target":4,"value":1}, 
 
     {"source":3,"target":5,"value":1}, {"source":4,"target":5,"value":1} 
 
    ]; 
 

 
// create the canvas for the model 
 
var svg = d3.select("#chart").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 
// d3 provides the calculations to animate the model 
 
var force = d3.layout.force() 
 
    .gravity(gravity) 
 
    .distance(distance) 
 
    .charge(charge) 
 
    .size([width, height]); 
 

 
// add data, and start the animation 
 
force.nodes(nodes) 
 
    .links(links) 
 
    .start(); 
 

 
// add classnames to links for styling 
 
var link = svg.selectAll(".link") 
 
    .data(links) 
 
    .enter().append("line") 
 
    .attr("class", "link"); 
 

 
// enable drag of nodes 
 
var node = svg.selectAll(".node") 
 
    .data(nodes) 
 
    .enter().append("g") 
 
    .attr("class", "node") 
 
    .call(force.drag); 
 

 
// draw circles 
 
var circle=node.append("svg:circle").attr("r", r - .75).style("fill", function(d) { 
 
     return fill(d.status); 
 
    }).style("stroke", function(d) { 
 
     return d3.rgb(fill(d.status)).darker(); 
 
    }).call(force.drag); 
 

 
// add tooltip so it shows the unit and formula 
 
circle.append("svg:title").text(function(d, i) { return "Performer: " + d.performer + ", Timestamp: " + d.timestamp; }); 
 

 

 
// create arrowheads (end markers) 
 
// three type of styles can be made for each group 
 
// this feature is not used 
 
svg.append("svg:defs").selectAll("marker") 
 
    .data([1,2,3]) 
 
    .enter().append("svg:marker") 
 
    .attr("id", String) 
 
    .attr("viewBox", "0 -5 10 10") 
 
    .attr("refX", 22) 
 
    .attr("refY", -1.5) 
 
    .attr("markerWidth", 6) 
 
    .attr("markerHeight", 6) 
 
    .attr("fill-color","#cccccc") 
 
    .attr("orient", "auto") 
 
    .append("svg:path") 
 
    .attr("d", "M0,-5L10,0L0,5"); 
 

 
// attach markers 
 
var path = svg.append("svg:g").selectAll("path") 
 
    .data(force.links()) 
 
    .enter().append("svg:path") 
 
    .attr("class", function(d) { return "link " + d.value; }) 
 
    .attr("marker-end", function(d) { return "url(#" + d.value + ")"; }); 
 

 
// create a group for text elements 
 
var text = svg.append("svg:g").selectAll("g") 
 
    .data(force.nodes()) 
 
    .enter().append("svg:g"); 
 

 
// create shadow in white 
 
text.append("svg:text") 
 
     .attr("dx", 12) 
 
     .attr("dy", ".35em") 
 
     .attr("class", "shadow") 
 
     .text(function(d) { return d.name;} 
 
); 
 

 
// create name on top of shadow 
 
text.append("svg:text") 
 
     .attr("dx", 12) 
 
     .attr("dy", ".35em") 
 
     .text(function(d) { return d.name;} 
 
); 
 

 
// put the symbol, e.g. kg inside the circle 
 
/*text.append("svg:text") 
 
     .attr("dx", -4) 
 
     .attr("dy", 2) 
 
     .attr("fill", "#ffffff") 
 
     .text(function(d) { return d["symbol"]?d.symbol:"";} 
 
); */ 
 

 
force.on("tick", function(d) { 
 
    path.attr("d", function(d) { 
 
     var dx = d.target.x - d.source.x, 
 
     dy = d.target.y - d.source.y, 
 
     dr = 0; // straight lines (0=straight, 1=round) 
 
     // alternatively use dr = Math.sqrt(dx * dx + dy * dy); for similar arcs 
 
     return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
 
     }); 
 
    
 
     circle.attr("transform", function(d) { 
 
     return "translate(" + d.x + "," + d.y + ")"; 
 
     }); 
 
    
 
     text.attr("transform", function(d) { 
 
     return "translate(" + d.x + "," + d.y + ")"; 
 
     }); 
 

 
}); 
 

 
// when clicked redraw the diagram 
 
d3.select("#chart").on("click", function() { 
 
    nodes.forEach(function(o, i) { 
 
    o.x += (Math.random() - .5) * 100; 
 
    o.y += (Math.random() - .5) * 100; 
 
    }); 
 
    force.resume(); 
 
});
.link { 
 
    stroke: #fcfcfc; 
 
} 
 

 
.node text { 
 
    pointer-events: none; 
 
    font: 12px Calibri, Arial; 
 
} 
 
path.link { 
 
    fill: none; 
 
    stroke: #666; 
 
    stroke-width: 1.5px; 
 
} 
 

 
marker#licensing { 
 
    fill: green; 
 
} 
 

 
path.link.licensing { 
 
    stroke: green; 
 
} 
 

 
path.link.resolved { 
 
    stroke-dasharray: 0,2 1; 
 
} 
 

 
circle { 
 
    fill: #ccc; 
 
    stroke: #333; 
 
    stroke-width: 1.5px; 
 
} 
 

 
text { 
 
    font: 10px sans-serif; 
 
    pointer-events: none; 
 
} 
 

 
text.shadow { 
 
    stroke: #fff; 
 
    stroke-width: 3px; 
 
    stroke-opacity: .8; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<body> 
 
     <div id="chart"></div> 
 
    </body>

它具有两个阵列,节点和链接。我想知道是否有可能将这两个数组组合成一个数组。这将使它更容易理解和维护。

+2

这两个数组在内容上是完全不同的......如果您要混合不同类型的数据,究竟如何更容易维护? – Cerbrus

+0

感谢您的回复。我正在寻找{source:“Start”,target:“Dept Approver”,执行者:“admin”,状态:1,时间戳:“2014年8月16日”}。那样,节点如何连接可以在一个地方找到,而不是两个。 – kayasa

回答

0

我会写一个map样的功能,如:

var result = [] 
for (var idx in nodes) { 
    var link = links[idx], 
     node = nodes[idx] 
    result.push({ 
    source: nodes[link.source].name, 
    target: nodes[link.target].name, 
    performer: nodes[link.???].performer, 
    // etc... 
    }) 
} 

我也建议检查出UnderscoreLoDash,或Lazy.js,图书馆,使这些类型的数据转换的更优雅。