I've got an array of objects called graphData
(size varies). Each element contains all the information required to create a d3 graph, and I am able to successfully draw the graphs if I access graphData
elements by hardcoding (i.e. graphdata[0]
, graphdata[1]
etc).
The problem comes when I attempt to use a for loop to generate one graph for each of the elements. Looked around stackoverflow and the web, but the solutions are all about generating a fixed number of multiple graphs, not generating multiple graphs dynamically.
Below is my working code for generating one graph. What is the recommended way to generate x number of graphs automatically?
var graphData = data.graph;
var RADIUS = 15;
var edgeData = graphData[0].edges;
var nodeData = graphData[0].nodes;
var stageNum = graphData[0].stage;
var xScale = d3.scale.linear()
.domain([d3.min(edgeData, function (d) {
return d.start[0];
}),
d3.max(edgeData, function (d) {
return d.start[0];
})])
.range([50, w - 100]);
var yScale = d3.scale.linear()
.domain([d3.min(edgeData, function (d) {
return d.start[1];
}),
d3.max(edgeData, function (d) {
return d.start[1];
})])
.range([50, h - 100]);
var rScale = d3.scale.linear()
.domain([0, d3.max(edgeData, function (d) {
return d.start[1];
})])
.range([14, 17]);
// already have divs with classes stage1, stage2... created.
var svg = d3.select(".stage" + stageNum).append("svg")
.attr({"width": w, "height": h})
.style("border", "1px solid black");
var elemEdge = svg.selectAll("line")
.data(edgeData)
.enter();
var edges = elemEdge.append("line")
.attr("x1", function (d) {
return xScale(d.start[0]);
})
.attr("y1", function (d) {
return yScale(d.start[1]);
})
.attr("x2", function (d) {
return xScale(d.end[0]);
})
.attr("y2", function (d) {
return yScale(d.end[1]);
})
.attr("stroke-width", 2)
.attr("stroke", "black");
var elemNode = svg.selectAll("circle")
.data(nodeData)
.enter();
var nodes = elemNode.append("circle")
.attr("cx", function (d) {
return xScale(parseInt(d.x));
})
.attr("cy", function (d) {
return yScale(parseInt(d.y));
})
.attr({"r": rScale(RADIUS)})
.style("fill", "yellow")
.style("stroke", "black");
Mike Bostock recommends implementing charts as reusable closures with methods. This would be an ideal implementation in your case as you want to have
In broad strokes, what you want to do is wrap your code above into a function in very much the same way Mike describes in the post above, and then have
data
be an attribute of your closure. So here is some badly hacked code:Here is some more good reading on the topic.
Well you can try the following approach.
providing this as your source array
a bit of Array stuff
setup: