how to draw a grid incrementally in d3?
Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid
with 0 or 1; then fills a 1d array called nodes
with x
, y
, and color
; then draws nodes
with d3. They all appear. They look like this:
How do I instead have nodes
drawn (i.e. appear) one at a time, in the order given by the nodes
array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?
I tried fiddling with the transition
function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.
The code:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
</script>
<style>rect { color: black; }</style>
</head>
<body><div id="graph"/></body>
</html>
d3.js
add a comment |
Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid
with 0 or 1; then fills a 1d array called nodes
with x
, y
, and color
; then draws nodes
with d3. They all appear. They look like this:
How do I instead have nodes
drawn (i.e. appear) one at a time, in the order given by the nodes
array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?
I tried fiddling with the transition
function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.
The code:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
</script>
<style>rect { color: black; }</style>
</head>
<body><div id="graph"/></body>
</html>
d3.js
add a comment |
Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid
with 0 or 1; then fills a 1d array called nodes
with x
, y
, and color
; then draws nodes
with d3. They all appear. They look like this:
How do I instead have nodes
drawn (i.e. appear) one at a time, in the order given by the nodes
array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?
I tried fiddling with the transition
function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.
The code:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
</script>
<style>rect { color: black; }</style>
</head>
<body><div id="graph"/></body>
</html>
d3.js
Below is an HTML file that will draw a 10x10 grid of squares alternating light grey and dark grey. It fills a 2d array called the_grid
with 0 or 1; then fills a 1d array called nodes
with x
, y
, and color
; then draws nodes
with d3. They all appear. They look like this:
How do I instead have nodes
drawn (i.e. appear) one at a time, in the order given by the nodes
array (so I could draw different patterns, say vertical wipe, horizontal wipe, whatever)?
I tried fiddling with the transition
function without success. It just draws the whole grid, and slides it into place. The squares don't visibly appear one by one.
The code:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
</script>
<style>rect { color: black; }</style>
</head>
<body><div id="graph"/></body>
</html>
d3.js
d3.js
asked Dec 31 '18 at 18:49
dfrankowdfrankow
8,7413198152
8,7413198152
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay()
, you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:
selection.transition()
.delay(function(d,i) { return i * 100; })
.attr(...
Above and in the snippet below I've used the index:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
And below I've used the datum to create a random transition order:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill tonone
, I've updated it towhite
so that d3 can interpolate between start and end values without further modification){
– Andrew Reid
Dec 31 '18 at 19:35
will it draw innodes
order, or do i have to set the delays to the right values to reveal them in order?
– dfrankow
Dec 31 '18 at 19:37
1
If using the index of the node in the data array (i * time
), the transitions will always start in same order as they are in the array.
– Andrew Reid
Dec 31 '18 at 19:39
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990545%2fhow-to-draw-a-grid-incrementally-in-d3%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay()
, you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:
selection.transition()
.delay(function(d,i) { return i * 100; })
.attr(...
Above and in the snippet below I've used the index:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
And below I've used the datum to create a random transition order:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill tonone
, I've updated it towhite
so that d3 can interpolate between start and end values without further modification){
– Andrew Reid
Dec 31 '18 at 19:35
will it draw innodes
order, or do i have to set the delays to the right values to reveal them in order?
– dfrankow
Dec 31 '18 at 19:37
1
If using the index of the node in the data array (i * time
), the transitions will always start in same order as they are in the array.
– Andrew Reid
Dec 31 '18 at 19:39
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
add a comment |
To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay()
, you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:
selection.transition()
.delay(function(d,i) { return i * 100; })
.attr(...
Above and in the snippet below I've used the index:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
And below I've used the datum to create a random transition order:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill tonone
, I've updated it towhite
so that d3 can interpolate between start and end values without further modification){
– Andrew Reid
Dec 31 '18 at 19:35
will it draw innodes
order, or do i have to set the delays to the right values to reveal them in order?
– dfrankow
Dec 31 '18 at 19:37
1
If using the index of the node in the data array (i * time
), the transitions will always start in same order as they are in the array.
– Andrew Reid
Dec 31 '18 at 19:39
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
add a comment |
To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay()
, you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:
selection.transition()
.delay(function(d,i) { return i * 100; })
.attr(...
Above and in the snippet below I've used the index:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
And below I've used the datum to create a random transition order:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
To stagger the transitions of multiple elements entered at the same time from the same data array you can use transition.delay()
, you can specify a constant (which will start all transitions simutaneously) or you can specify a function to base the delay on the datum of each element or its index:
selection.transition()
.delay(function(d,i) { return i * 100; })
.attr(...
Above and in the snippet below I've used the index:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
And below I've used the datum to create a random transition order:
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return i * 100; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
function draw_function() {
var vis = d3.select("#graph")
.append("svg")
.attr("width", 200).attr("height", 200);
// fill the_grid
var shape=[10,10];
var the_grid=;
for (var idx = 0; idx < shape[0]; idx++) {
var row = ;
for (var jdx = 0; jdx < shape[1]; jdx++) {
var val = (idx+jdx)/2;
row.push(Math.floor(val)==val ? 1 : 0);
}
the_grid.push(row);
}
// fill nodes
var rectwidth = 10;
var nodes = ;
for (var idx = 0; idx < the_grid.length; idx++) {
for (var jdx = 0; jdx < the_grid[0].length; jdx++) {
var node = {
delay: Math.random()*2000,
x: idx * (rectwidth+1),
y: jdx * (rectwidth+1),
color: the_grid[idx][jdx] == 1 ? 'black' : 'lightgrey'};
nodes.push(node);
}
}
// draw nodes
vis.selectAll("rect.nodes")
.data(nodes)
.enter()
.append("svg:rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", rectwidth)
.attr("width", rectwidth)
.attr("fill","white")
.transition()
.duration(1000)
.delay(function(d,i) { return d.delay; })
.attr("fill", function(d) { return d.color; })
}
// function has to execute after dom is loaded
window.onload = draw_function
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="graph"/>
edited Dec 31 '18 at 19:36
answered Dec 31 '18 at 19:14
Andrew ReidAndrew Reid
17.7k32343
17.7k32343
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill tonone
, I've updated it towhite
so that d3 can interpolate between start and end values without further modification){
– Andrew Reid
Dec 31 '18 at 19:35
will it draw innodes
order, or do i have to set the delays to the right values to reveal them in order?
– dfrankow
Dec 31 '18 at 19:37
1
If using the index of the node in the data array (i * time
), the transitions will always start in same order as they are in the array.
– Andrew Reid
Dec 31 '18 at 19:39
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
add a comment |
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill tonone
, I've updated it towhite
so that d3 can interpolate between start and end values without further modification){
– Andrew Reid
Dec 31 '18 at 19:35
will it draw innodes
order, or do i have to set the delays to the right values to reveal them in order?
– dfrankow
Dec 31 '18 at 19:37
1
If using the index of the node in the data array (i * time
), the transitions will always start in same order as they are in the array.
– Andrew Reid
Dec 31 '18 at 19:39
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
great! the secret seems to be the "delay" function, and putting it in the right spot. duration is unneeded.
– dfrankow
Dec 31 '18 at 19:34
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to
none
, I've updated it to white
so that d3 can interpolate between start and end values without further modification){– Andrew Reid
Dec 31 '18 at 19:35
I used duration just to slow the transition itself a bit, but yes, it is not needed (But I goofed, I set initial fill to
none
, I've updated it to white
so that d3 can interpolate between start and end values without further modification){– Andrew Reid
Dec 31 '18 at 19:35
will it draw in
nodes
order, or do i have to set the delays to the right values to reveal them in order?– dfrankow
Dec 31 '18 at 19:37
will it draw in
nodes
order, or do i have to set the delays to the right values to reveal them in order?– dfrankow
Dec 31 '18 at 19:37
1
1
If using the index of the node in the data array (
i * time
), the transitions will always start in same order as they are in the array.– Andrew Reid
Dec 31 '18 at 19:39
If using the index of the node in the data array (
i * time
), the transitions will always start in same order as they are in the array.– Andrew Reid
Dec 31 '18 at 19:39
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
FYI I ended up using this in github.com/dfrankow/d3maze.
– dfrankow
Jan 1 at 18:36
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990545%2fhow-to-draw-a-grid-incrementally-in-d3%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown