我正在尝试从CSV数据集构建d3.js热图。使用d3.csv导入后,数据如下所示:
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, columns: Array(11)]
其中每个对象如下:
Object {0: "0.934999642", 1: "0.1031451091", 2: "0.077435557", 3:
"0.129644215", 4: "0.666245944", 5: "0.133087829", 6: "0.113218775", 7:
"0.120796943", 8: "0.257501418", 9: "0.840916491", "": "0"}
我一直在尝试按原样使用数据,但是for循环太慢(真实数据集有1300个值),并且尝试嵌套结构不起作用,因为d3的data()函数只能拿一个数组。
像这样:
var row = svg.selectAll(".rows")
.data(data)
.enter()
.append("rect")
[etc]
d3.selectAll(".blocks")//nested data
.data(function(d) {//d has no length property, so this line fails
return d;
})
.enter()
.append("rect")
[etc]
如何将对象数组转换为数组数组?或者,有没有办法成功使用对象数组?另外,有没有理由说它不是直接来自数组数组中的CSV而不是这个奇怪的对象数组?这些数据是在Python的Pandas中策划和导出的,如果这样做有所不同,我们可以在那里进行调整。
谢谢。
答案 0 :(得分:5)
let myArray = Object
.keys(myObj)
.map(key => myObj[key]);
虽然您可能希望保证按键按顺序显示并排除非数字键。
let myArray = Object
.keys(myObj)
.sort((a,b) => +a - +b)
.filter(key => !isNaN(+key))
.map(key => myObj[key]);
您可以通过map将其用于将其应用于父数组
let newArray = bigArray
.map(el => Object
.keys(el)
/* ... */
.map(key => el[key]));
答案 1 :(得分:0)
您可以迭代数组并将每个对象映射到Object值:
var result=array.map(Object.values)
但它与两个循环的速度相同。
答案 2 :(得分:0)
数组数组。使用带有对象迭代和数组赋值的While循环。从技术上讲,两个循环。实际上应该算作一个循环,因为它是嵌套计数的延续。
var objs = [{
0: "0.934999642",
1: "0.1031451091",
2: "0.077435557",
3: "0.129644215",
4: "0.666245944",
5: "0.133087829",
6: "0.113218775",
7: "0.120796943",
8: "0.257501418",
9: "0.840916491",
"": "0"
}, {
0: "0.934999642",
1: "0.1031451091",
2: "0.077435557",
3: "0.129644215",
4: "0.666245944",
5: "0.133087829",
6: "0.113218775",
7: "0.120796943",
8: "0.257501418",
9: "0.840916491",
"": "0"
}]
var i = objs.length,
arr = Array.from(new Array(i), x => []);
while (i--) {
for (let val in objs[i]) {
var values = objs[i][val];
arr[i].push([values]);
}
}
console.log(arr);
答案 3 :(得分:0)
myObj = {prop1:[object,object,...],prop2:''};
将prop1作为数组,使用:
var result = myObj.prop1;
或 result = myObj.prop1.map(function(item){ / item - 您的每个对象,您可以获得任何属性,例如:return {“name”:item。 name,“value”:item [3];}; / return item;});
result = [{name:Alex,value:Cash},..];
答案 4 :(得分:0)
您已经有4个不同的答案,向您展示如何在数组中转换具有多个属性的对象。但是,正如我在my comment中所说,这对我来说似乎是一个XY problem,因为你最终想要的只是创建一个热图。
当然,您可以使用任何提供的答案在内部选择中创建数据数组。但是,有不同的方法可以实现相同的结果。这个答案只是我对你的目标的两分钱,而不是你实际问的是什么。
当你说data()
不接受某个对象时,你是对的。事实上,data()
只接受三件事:
话虽这么说,我们必须以某种方式在多个对象中转换那个巨大的对象,因为每个单独的对象代表一个数据点。
假设您有以下CSV(8 x 8矩阵值)。在此CSV中,第一行标题只是列号。所有值(从第二行开始)从0到100:
1, 2, 3, 4, 5, 6, 7, 8
99, 01, 01, 56, 65, 34, 87, 65
76, 99, 73, 23, 54, 62, 12, 15
54, 77, 66, 23, 98, 76, 11, 12
13, 24, 56, 76, 88, 75, 43, 76
12, 33, 44, 52, 45, 87, 65, 67
88, 76, 67, 87, 54, 34, 44, 45
12, 13, 24, 65, 45, 47, 76, 87
65, 43, 23, 42, 42, 34, 42, 17
使用此CSV,您可以创建一个数据数组,其中每个对象都包含行号,列号和值。例如,将CSV解析为名为rawData
的数组,我们可以填充名为data
的最终数据数组,如下所示:
rawData.forEach(function(d, i) {
Object.keys(d).forEach(function(e) {
data.push({
row: i,
column: e,
value: d[e]
})
})
});
因此,您只需要在所选内容中访问d.row
,d.column
和d.value
。
.attr("x", function(d) {
return xScale(d.column)
})
.attr("y", function(d) {
return xScale(d.row)
})
.attr("fill", function(d) {
return color(d.value)
})
这是一个非常简单的演示:
var svg = d3.select("svg");
var rawData = d3.csvParse(d3.select("#csv").text())
var color = d3.scaleLinear().domain([0, 100]).range(["maroon", "lawngreen"]);
var xScale = d3.scaleBand().domain(d3.range(1, 9, 1)).range([20, 180]);
var yScale = d3.scaleBand().domain(d3.range(1, 9, 1)).range([20, 180]);
var data = [];
rawData.forEach(function(d, i) {
Object.keys(d).forEach(function(e) {
data.push({
row: i,
column: e,
value: d[e]
})
})
});
var rects = svg.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("width", xScale.bandwidth() - 2)
.attr("height", yScale.bandwidth() - 2)
.attr("x", function(d) {
return xScale(d.column)
})
.attr("y", function(d) {
return xScale(d.row)
})
.attr("fill", function(d) {
return color(d.value)
})
pre {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="200" height="200"></svg>
<pre id="csv">1,2,3,4,5,6,7,8
99,01,01,56,65,34,87,65
76,99,73,23,54,62,12,15
54,77,66,23,98,76,11,12
13,24,56,76,88,75,43,76
12,33,44,52,45,87,65,67
88,76,67,87,54,34,44,45
12,13,24,65,45,47,76,87
65,43,23,42,42,34,42,17</pre>
请注意,在此演示中,我使用<pre>
元素来存储数据,因为我无法在Stack片段中使用d3.csv
。