In an effort incrementally introduce complexity, data is bound one datum
at a time with a for
loop to blend the declarative/functional paradigm of D3 and the imperative/procedural paradigm of standard Javascript.
In this example we can see how D3's data binding functions (data()
and datum()
) create a closure encapsulating the state of variables at the time the data is bound.
Built with blockbuilder.org
forked from Jay-Oh-eN's block: Foundations of D3: Data Binding Scope
forked from margeigh's block: Foundations of D3: Data Binding Scope
forked from margeigh's block: Foundations of D3: Data Binding Scope
forked from margeigh's block: Foundations of D3: Data Binding Scope
forked from margeigh's block: Foundations of D3: Data Binding Scope
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg { width: 100%; height: 100%; }
circle {
opacity: 0.5;
;
}
</style>
</head>
<body>
<svg>
</svg>
<script>
var width = 960;
var height = 500;
var svg = d3.select('svg');
var colors = ["grey", "yellow"]
for(var i = 0; i < 1800; i++) {
var data = {
x: Math.random() * width,
y: Math.random() * height,
radius: 2,
color: colors[i%colors.length]
};
// each cicle gets a different span value
svg.append('circle')
// datum bind a closure of the current variables.
.datum(data);
}
// new value for width doesn't affect bound data
width = 2000000;
// the last value from the for loop
console.log(data);
// mutate the circles' visual appearance
svg.selectAll('circle')
.attr('cx', function(d) {
console.log(d);
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('fill', function(d) {
return d.color;
})
.attr('r', function(d) {
return d.radius;
})
console.log(d3.selectAll('circle'));
</script>
</body>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js