javascript - D3 - Combining arrays -
i using d3 code works absolutely fine.
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"} ], // relations shown can calculated using // formulas 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 canvas model var svg = d3.select("#chart").append("svg") .attr("width", width) .attr("height", height); // d3 provides calculations animate model var force = d3.layout.force() .gravity(gravity) .distance(distance) .charge(charge) .size([width, height]); // add data, , start animation force.nodes(nodes) .links(links) .start(); // add classnames links 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 shows unit , formula circle.append("svg:title").text(function(d, i) { return "performer: " + d.performer + ", timestamp: " + d.timestamp; }); // create arrowheads (end markers) // 3 type of styles can made each group // feature 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 group 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 symbol, e.g. kg inside 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); 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 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>
it has 2 arrays, nodes , links.
i wondering if possible combine these 2 arrays single array. make easier understand , maintain.
i write map
-like function, such as:
var result = [] (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... }) }
i suggest checking out underscore
, lodash
, or lazy.js
, libraries make these kind of data transformations more elegant.
Comments
Post a Comment