如何在d3中增量绘制网格? [英] how to draw a grid incrementally in d3?
问题描述
下面是一个HTML文件,该文件将绘制一个10x10的正方形网格,交替显示浅灰色和深灰色.它用0或1填充称为the_grid
的2d数组;然后用x
,y
和color
填充一个名为nodes
的一维数组;然后用d3绘制nodes
.它们全部出现.他们看起来像这样:
我该如何按照nodes
数组给出的顺序一次绘制(即出现)一个nodes
(这样我就可以绘制不同的图案,例如垂直划像,水平划像等等)?/p>
我尝试摆弄transition
函数没有成功.它只是绘制整个网格并将其滑动到位.正方形在外观上并不会一一出现.
代码:
<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>
要错开从同一数据数组中同时输入的多个元素的过渡,可以使用transition.delay()
,可以指定一个常量(该常量将开始所有跃迁同时进行),也可以指定一个函数将延迟基于每个元素或其索引的基准:
selection.transition()
.delay(function(d,i) { return i * 100; })
.attr(...
上面和下面的代码段中,我使用了索引:
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"/>
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>
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"/>
这篇关于如何在d3中增量绘制网格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!