0

我正在尝试在多系列折线图上放置符号。在d3.js API 参考中,符号是使用转换函数定位的:

vis.selectAll("path")
    .data(data)
    .enter().append("path")
    .attr("transform", function(d) { return "translate(" + x(d.x) + "," + y(d.y) + ")"; })
    .attr("d", d3.svg.symbol());

不幸的是,我似乎无法应用它来构建我自己的 function(d) 回调函数来访问 d.date 和几个 d.temperature 集,如下所示并在此示例中描述:

var cities = color.domain().map(function(name) {
    return {
        name: name,
        values: data.map(function(d) {
        return {date: d.date, temperature: +d[name]}; <-- stored in 'd.values'
    })
};});

通过反复试验,我能想到的最好的方法如下,我提供的是喜剧救济:

for (i=0; i<cities[0].values.length; i++) // note: for comic relief only
{
    vis.selectAll(".class")
    .data(cities)
    .enter().append("path")
    .attr("transform", function(d) { return "translate(" + x(d.values[i].date) + "," + y(d.values[i].temperature) + ")"; })
    .attr("d", d3.svg.symbol())
}

它确实有效,我认为这很有趣,但我编写正确嵌套函数的尝试到目前为止都失败了。例如,这给出了 transform="translate(NaN,NaN)"

.attr("transform", function(d) { return "translate(" + x(d.values, function(c) { return c.date}) + "," + y(d.values, function(c) { return c.temperature}) + ")"; })

我不明白什么?任何帮助将不胜感激。

4

1 回答 1

1

在您的尝试代码中,您具有约束力data,但我认为您的意思是cities,对吗?您链接到的示例中的data变量包含从 TSV 文件中读取的数据,因此它没有values属性。

cities变量指向一个嵌套的数据结构,其中每个城市(系列)都包含一个包含该行(值)的数据点列表。这种嵌套在创建路径时很方便,因为每个城市都是单独的路径,并且路径定义由值列表组成。但是对于应用形状,您不再需要分组。您只需要一个值列表,以便您可以为每个值创建/定位一个形状。

与其尝试从嵌套结构中提取值,不如执行数据转换以生成平面值列表可能是最简单的。请注意,我将城市名称放入每个节点中,因为您可能希望使用它来将每个城市的颜色或类型应用于您的形状:

var values = [];
cities.forEach(function(city) {
    city.values.forEach(function(v) {
        values.push({
            date: v.date,
            temperature: v.temperature,
            city: city.name
        });
    });
});

然后你可以简单地使用这个数组来创建形状。每个值都包含将其放入正确位置所需的所有信息。要从您的问题中复制一些代码:

vis.selectAll("path")
    .data(values)
    .enter().append("path")
    .attr("transform", function(d) { return "translate(" + x(d.date) + "," + y(d.temperature) + ")"; })
    .attr("d", d3.svg.symbol());

这将创建所有相同的形状,但如上所述,您可以使用 d.city 更改符号类型或笔触颜色。您可以使用简单的序数刻度或带有城市名称的颜色刻度作为域来执行此操作。

** 编辑:根据您表示希望使用分组数据结构而不进行进一步转换来执行此操作的评论,这是一种在循环中连接多个数据的方法:

for (i=0; i < cities.length; i++) {
    vis.selectAll(".class")
        .data(cities[i].values)
        .enter().append("path")
            .attr("transform", function(d) { return "translate(" + x(d.date) + "," + y(d.temperature) + ")"; })
            .attr("d", d3.svg.symbol())
}
于 2013-08-24T06:47:13.487 回答