我想制作一个3D矩阵,并用文本文件中的值填充它,然后制作一个尺寸为180 * 90的网格,并根据我的矩阵中的值对其进行着色,
例如:蓝色表示负值,红色表示正值,白色表示零值。
我想将我从文本文件中读取的内容存储在3D矩阵中。
但是当我执行我的html文件并使用时,我遇到了问题
console.log(myMatrix)
会显示undefined
,当我在控制台中复制粘贴for-loop
时,
例如
console.log(myMatrix[0][0][4])
向我显示了正确的答案,即90
。
所以我想可能是问题与 javaScript 有关,因为 js 读取了所有代码,当我尝试console.log(myMatrix[0][0][4])
时,它显示了undefined
因为读取文件并存储在数组中还没有完成,但是当我使用控制台命令(因为它位于RAM中)时,我可以看到正确的答案。
因此,我决定检查是否已读取文件并将其存储在完整的数组中,然后执行我的for-loop
将值从数组存储到myMatrix
。但是我不知道该怎么办?
我尝试使用setTimeout
,但是我认为也许我系统中的执行时间不同于其他系统或网络。我也想使用Callback函数,但是我什么都没做。我希望你能帮助我。
这是我的代码:
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script>
//creat 1670 numbers of matrices with size of 180*90
var myMatrix = new Array(1670)
for (var i=0; i<1670; i++){
myMatrix[i] = twodmatrix()
}
function twodmatrix(){
var myMat = new Array(180)
for (var i=0; i<180; i++){
myMat[i] = new Array(90)
}
return(myMat)
}
var myGrid = new Array(1670)
for (var i=0; i<1670; i++){
myGrid[i] = twodmatrix()}
var array = new Array()
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "tempanomaly_new.txt", true);
xmlhttp.send();
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
parse(xmlhttp.responseText);
}
}
function parse (text) {
array = text.split(",");
return array
//Do something
}
function treeDmatrix(){
var n=0;
for(var i=0;i<1670;i++){
for(var j=0;j<180;j++){
for(var k=0; k<90; k++){myMatrix[i][j][k]= array[n];
n +=1;}}}
}
/*var mycolor;
for(var i=0; i<array.length; i++){
if (array[i] == 0){ function white(){ mycolor = d3.scalelinear().domain([1,5]).range(["white"])}}
else if (array[i] > 0 ){ function red(){ mycolor = d3.scalelinear().domain([1,5]).range(["red"])}}
else if (array[i] < 0 ){function blue(){ mycolor = d3.scalelinear().domain([1,5]).range(["blue"])}}
}
/* Start make a grid and color it */
/*
const BLOCK_SIZE = 30;
const BLOCK_SPACE = 5;
const ROW_SIZE = 90;
const COL_SIZE = 180;
gridData = new Array(COL_SIZE);
for (var i = 0; i < COL_SIZE; i++) {
gridData[i] = new Array(ROW_SIZE);
for (var j = 0; j < ROW_SIZE; j++) {
gridData[i][j] = {
x: (i + 1) * BLOCK_SIZE + BLOCK_SPACE,
y: (j + 1) * BLOCK_SIZE + BLOCK_SPACE,
size: BLOCK_SIZE,
}}}
var grid = d3.select("#grid")
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.style("color", "#b2b2b2");
var row = grid.selectAll(".row")
.data(gridData)
.enter().append("g")
.attr("class", "row");
var column = row.selectAll(".square")
.data(function(data) { return data; })
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(data) { return data.x; })
.attr("y", function(data) { return data.y; })
.attr("width", function(data) { return data.size; })
.attr("height", function(data) { return data.size; })
.style("stroke", "#222")
.style("fill", function(data) { return mycolor(data)});*/
</script>
</body>
</html>
答案 0 :(得分:1)
onreadystatechange
是一个异步函数,因此很可能只有在运行所有脚本之后才调用它。因此,您必须等到调用parse
函数之后,再继续处理数据。我建议您将所有代码移至parse
内并进行检查。如果您确实想以正确的方式进行操作,请阅读有关Promise
的信息。
答案 1 :(得分:1)
XMLHTTPRequest是异步的。这意味着JS只会启动数据请求并继续处理其余代码。当请求的数据到达时(为简单起见,我会说),它将触发onreadystatechange
函数。
现在,这是您应该填充数组并开始处理它的时刻。将循环放入名为buildMatrix
的函数中,并在数据到达后执行该函数。
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var d = parse(xmlhttp.responseText);
buildMatrix(d);
}
}
所有这些操作结束后,将矩阵记录到控制台。因此,要在代码中执行的最后一行是
buildMatrix(d)
console.log(myMatrix)