我目前正在通过D3编写可视化,我希望你能帮助我。
要了解我正在制作的内容,您可以查看以下链接:https://dl.dropboxusercontent.com/u/56480311/Data-visualization/index.html
我面临两个问题:首先是我似乎无法将.csv数据放在2D数组中。我找到了关于将它放在普通数组中的multiplie教程,但是如果你的数据在表中,我想出的唯一解决方案是使用2D数组。我无法找到如何做到这一点,所以我认为会有所帮助:
var lines = []; //define lines as an array
//retrieve data from .csv file
d3.csv("https://dl.dropboxusercontent.com/u/56480311/Data-visualization/growth-prep.csv", function(data) {
lines = data.map(function(d) {
return d;
});
});
//create 2D array named myArray
var myArray = new Array(10);
for (var i = 0; i < 10; i++) {
myArray[i] = new Array(18);
}
//place each value of .csv file into myArray
for (var j = 0; j < lines.length; j++) {
var values = lines[j].split(";");
for (var k = 0; k < values.length; k++) {
myArray[k][j] = values[k];
}
}
但是,此代码不起作用。控制台一直说数组是未定义的,它们是空的。
我面临的第二个问题是可视化数据。我将三个彼此相邻的值相加(例如,数据集[0] [0] +数据集[0] [1] +数据集[0] [2])。我将此值绘制为矩形的宽度。最重要的是,我想绘制三个不同的矩形,每个矩形的值为三个中的一个。所以在这种情况下,有一个矩形由数据集[0] [0] +数据集[0] [1] +数据集[0] [2]组成,顶部有一个显示数据集[0] [0]的矩形,一个显示数据数据集[0] [1],另一个显示数据数据集[0] [2]。我希望只有当鼠标悬停在'sum'/ parent矩形上时才能显示三个较小的。
如果你查看链接,你可以看到我的意思。一切都已经存在,只有三个较小的矩形具有不透明度0,所以你还没有看到它们(但你可以通过检查元素找到它们)。
我想我可以通过将三个矩形的不透明度设置为0并在鼠标悬停时将其设置为1来完成此操作。对我来说最好的解决方案是将三个矩形放在一种div中。一旦鼠标悬停在它上面,它的不透明度就是1.只有我无法弄清楚如何轻松地给出不同的类名而不必单独为每个矩形手动完成。有没有人知道如何做到这一点,或者有更好的解决方案,一旦鼠标悬停在“更大”的矩形上,就可以更改所有三个矩形的不透明度?
这是代码:
var dataset = [[6,6,3,3,3,0,6,6,0,12,6,6,0,0,18,6,3,3],[3,0,0,6,3,0,3,3,0,9,3,0,0,0,18,6,6,6],[3,0,3,6,3,3,6,0,3,9,6,3,0,0,15,6,6,6],[6,6,3,3,0,3,6,6,6,12,6,6,0,0,18,6,6,3],[6,6,0,6,0,0,6,6,6,12,6,6,0,0,24,6,6,0],[3,6,3,6,3,3,6,6,3,3,0,0,0,0,15,3,9,6],[3,3,0,3,0,3,3,3,3,9,3,0,0,0,15,6,3,9],[0,0,0,3,0,6,6,3,3,3,0,3,0,0,24,6,12,6],[6,6,3,6,0,0,9,9,6,12,6,6,0,0,15,3,3,3],[6,6,0,6,3,0,6,6,0,9,6,3,0,0,9,3,6,0]];
var h = 800;
var w = 800;
//create svg of 800x800px
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var xPos = 150;
for (var k = 0; k < 10; k++) { //loop through lines of array
var yPos = 40 + k*80;
for (var j = 0; j < 18; j++) { //loop through rows of array
var count = j + 1;
//assign data of three boxes to value1/value2/value3 with which we will later on draw three separate rectangles to visualize the data
if (count == 1 || count == 4 || count == 7 || count == 10 || count == 13 || count == 16) {
var value1 = dataset[k][j];
}
if (count == 2 || count == 5 || count == 8 || count == 11 || count == 14 || count == 17) {
var value2 = dataset[k][j];
}
if (count == 3 || count == 6 || count == 9 || count == 12 || count == 15 || count == 18) {
var value3 = dataset[k][j];
}
if (count % 3 ==0) {
var sum = dataset[k][j] + dataset[k][j-1] + dataset[k][j-2]; //count the three values to also draw one bigger rectangle of their sum
var rectangle = svg.append("rect")
.attr("x", xPos)
.attr("y", yPos)
.attr("width", sum*5)
.attr("height", 20)
.attr("fill", function(d) {
if (count == 3) {
return "LightSeaGreen";
}
else if (count == 6) {
return "MediumSeaGreen";
}
else if (count == 9) {
return "MediumSpringGreen";
}
else if (count == 12) {
return "LimeGreen";
}
else if (count == 15) {
return "ForestGreen"
}
else if (count == 18) {
return "GreenYellow"
}
});
for (var l = 0; l < 3; l++) { //draw three 'sub' rectangles on top of the one 'sum' rectangle. they should appear when the mouse hovers over their 'sum' rectangle
var rectangle2 = svg.append("rect")
.attr("class", "sqr")
.attr("x", function() {
if (l == 0) {
return xPos;
} else if (l == 1) {
return xPos + value1*5;
} else if (l == 2) {
return xPos + (value1+value2)*5;
}
})
.attr("y", yPos)
.attr("width", function() {
if (l == 0) {
return value1*5;
} else if (l == 1) {
return value2*5;
} else if (l == 2) {
return value3*5;
}
})
.attr("height", 20)
.attr("fill", function() {
if (l == 0) {
return "SteelBlue";
} else if (l == 1) {
return "aquamarine";
} else if (l == 2) {
return "SkyBlue";
}
})
.attr("opacity", 0); //in first instance the rectangles are not visible. Opacity should turn to 1 when the mouse hovers over their according div
}
if (sum > 0) {
xPos = xPos + sum*5 + 5;
}
}
}
xPos = 150;
}