我尝试将 map.set(key,value)用于特定数据集 - 并将其分配给变量 mapdata - 而不是在何时指定它我排队csv。
即,而不是:
d3.queue()
.defer(d3.json, 'counties.json')
.defer(d3.csv, 'employmentdata.csv') function(d) {
d3.map()
.set(d.county, +d.rate);
})
.await(ready);
我想要的更多内容
var mapdata = d3.map(data)
.set(function(d) {d.county}, function(d) {d.rate});
除了代码没有返回我想要的内容。索引是键而不是县,值包括整个数据集而不仅仅是速率。我该如何解决这个问题?
提前致谢
答案 0 :(得分:4)
当这样使用时:
.defer(d3.csv, 'employmentdata.csv') function(d) {
map
.set(d.county, +d.rate);
})
为csv中的每一行调用map.set
的回调函数,并且单独设置每个键和值。如果您已经有一个数据数组,可以使用forEach循环模拟它:
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map();
data.forEach(function(d) {
map.set(d.key, d.value);
})
console.log(map.get("A"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
我们可以扩展它来操作键和值,因为行函数或forEach循环允许访问数据d
,我们不需要在函数中实际包含操作:< / p>
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map();
data.forEach(function(d,i) {
map.set(d.key+"-"+i, d.value*2);
})
console.log(map.get("A-0"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
你的第二个例子:
var mapdata = d3.map(data)
.set(function(d) {d.county}, function(d) {d.rate});
这不起作用,因为.set
只被调用一次,d
未定义。实际上,根本不会调用这些函数。
在我们查看set方法中的函数之前,让我们先看一下第一行:
var mapdata = d3.map(data)
d3.map需要两个参数,一个定义数据数组,另一个定义键。由于您没有提供密钥,因此使用默认密钥index:
d3.map([object [,key]])&lt;&gt;
构造一张新地图。如果指定了object,则复制所有可枚举的对象 从指定对象到此映射的属性。指定的 对象也可以是数组或其他映射。可选的按键功能 可以指定计算数组中每个值的键。 (source)
因此,您所看到的行为并非来自.set
方法,而只来自默认索引:
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map(data);
console.log(map.get(0));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
那么.set
在你的例子中做了什么?它正在为您的数据集添加一个新的值键对,让我们在之前和之后仔细查看地图:
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map(data);
console.log(map);
console.log("---------------");
map.set(function(d) { console.log(d); },
function(d) { console.log(d); })
console.log(map);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
这是一个有趣的行为,不仅在set方法中没有调用console.log
,而且这两个函数被添加为数组中的键值对。它很容易被遗漏(很大程度上是由于堆栈片段和日志记录),但这里是地图的补充:
"$function (d) { console.log(d); }": function (d) { console.log(d); },
set方法只会添加一个键值对,它不会修改现有的对(除非覆盖一个)。这就是.set将在行函数或forEach循环中工作的原因,但在设置多个键/值对时则不然。
虽然密钥的功能被强制转换为字符串,但您可以将函数嵌入为值:
var data = [
{key: "A", value: 100},
]
var map = d3.map(data);
map.set("B",function() { return "Hello"; })
console.log(map.get("B")());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
总结
因此,如果您想使用键创建地图,并将整个对象作为值使用,则可以使用:
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map(data, function(d) { return d.key; });
console.log(map.get("A"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
但是如果你想为每个键指定一个特定值(而不是数据数组项),那么使用forEach循环会更容易(如本答案的第一个片段所示):
var map = d3.map()
data.forEach(function(d) {
map.set(d.key,d.value)
})
如果你想在set方法中使用一个函数,你需要执行该函数并有一个返回值(在你的第二个例子/所需的代码中都缺少),你想要的功能是&#39;输出,而不是功能本身:
var data = [
{key: "A", value: 100},
{key: "B", value: 200},
{key: "C", value: 300},
{key: "D", value: 400},
{key: "E", value: 500}
]
var map = d3.map();
data.forEach(function(d) {
map.set(function() { return d.key + "-key"}(),
double(d.value))
})
console.log(map.get("A-key"));
function double(n) { return n*2; }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
最后一点,您的初始(参考/起点)代码块没有正确设置,d3.map()会创建一个新的地图。我们不想为每一行创建新地图,我们想要创建一次地图,然后为每一行使用set。
因此:
d3.queue()
.defer(d3.json, 'counties.json')
.defer(d3.csv, 'employmentdata.csv') function(d) {
d3.map()
.set(d.county, +d.rate);
})
.await(ready);
应如下所示:
var map = d3.map(); // create a map.
d3.queue()
.defer(d3.json, 'counties.json')
.defer(d3.csv, 'employmentdata.csv') function(d) {
map // use that same map for each row.
.set(d.county, +d.rate);
})
.await(ready);
上面的代码段使用相同的方法,创建地图,并为数组中的每个项目调用.set
。
相反,像d3.map().get(d.property)
这样的内容不会返回任何内容,因为您刚刚创建了一个空的d3.map()
的新地图。
答案 1 :(得分:0)
感谢您的解释。我尝试了上面的代码,它返回undefined。我可能知道问题是什么:
所以我目前的数据有多个类别。我想为不同的类别创建不同的键和值,我想通过将它们分配给新变量来区分它们。我想这样做是因为我想在我的地图上为不同的数据添加不同的功能,例如,我想根据失业率为地图着色,但我想根据不同的比率在地图上添加气泡,然后我想要根据其他内容创建下拉菜单。例如,我目前有:
var nest = d3.nest()
.key(function(d) {return d.occupation; })
.entries(data);
// array of locations in the data
var nocs = nest.map(function(d) { return d.key; });
所以,当我创建我的下拉菜单时,我写下这个:
var nocMenu = d3.select('#dropDown')
nocMenu
.append("select")
.attr("id", "selectMenu")
.selectAll("option")
.data(nest) /// i'm using 'nest' now instead of the entire dataset
.enter()
.append("option")
//.attr("value", function(d) { return d.values })
.text(function(d) { return d.key; });
这给了我想要的东西。 topojson文件和csv文件之间的唯一关系是县名。我需要将县名作为关键,以失业为价值,以便在用地图填充地图时可以使用 d3.map()。get(d.properties.counties)。
我试过了:
var mMap = d3.map()
var mapdata = data.forEach(function(d) {
mMap
.set(d.geography, +d.rate)
});
console.log(mapdata);
但它返回undefined。
答案 2 :(得分:0)
作为 D3 版本 6,v6.4.0
package main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class Main {
/**
* Iterate through each line of input.
*/
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
BufferedReader in = new BufferedReader(reader);
String line;
while ((line = in.readLine()) != null) {
long n = Long.parseLong(line);
long result = getHeights(n);
System.out.println(result);
System.out.println();
}
}
static long getHeights(long n){
long result = 0;
ArrayList<Long> heights = new ArrayList<>();
long left, right;
int count = 0;
for (int i = 0; i < n-1; i++) {
long item = heights.size()>0?heights.get(i):n;
if (heights.size() > 0)
heights.remove(i);
if (item % 2 == 0) {
long step = item / 2;
left = step;
right = step;
heights.add(count, left);
heights.add(count, right);
} else {
left = 1;
right = item - 1L;
heights.add(0, left);
heights.add(i==0?1:i,right);
count++;
}
if (right >= 1){
result = (left * right) + result;
}
System.out.println(result + " " + Arrays.toString(heights.toArray()));
}
System.out.println();
return result;
}
}
没有参数给我错误:d3.map()
。当降级到 v5 版本时,错误也会出现直到更改为 v4
以下是我的代码显示错误:
values is undefined