d3 Scatterplot中每个数据集的唯一符号

时间:2013-03-12 02:03:12

标签: d3.js

我在使用d3的符号机制为每组数据指定唯一符号时遇到问题。数据是这样的: [[{x:1,y:1},{x:2,y:2},{x:3,y:3}],[{x:1,y:1},{x:2,y :4},{x:3,y:9}]等等]

写出符号的代码部分如下所示: 我为每个点矢量创建一个系列组。然后:

series.selectAll("g.points") 
//this selects all <g> elements with class points (there aren't any yet)
.data(Object) //drill down into the nested Data
.enter() 
.append("g") //create groups then move them to the data location
.attr("transform", function(d, i) {
return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")";
        })
.append("path")
.attr("d", function(d,i,j){
        return (d3.svg.symbol().type(d3.svg.symbolTypes[j]));
    }
 );

或者至少我希望它如何运作。麻烦的是我无法从其他函数返回函数d3.svg.symbol()。如果我尝试将函数放在“type”参数中,那么数据将不再正确地限定以了解j是什么(系列的索引)。

是的,但我不希望每个数据点都有一个唯一的符号,我希望每个系列都有一个唯一的符号。数据由多个数组(系列)组成,每个数组可以有任意数量的点(x,y)。我想为每个数组添加一个不同的符号,这就是j应该给我的东西。我将数据(在示例中,显示的两个数组,因此i为0然后为1)与系列选择相关联。然后我将数据Object与点选择相关联,因此我成为每个数组中点的索引,j成为原始数组/数据系列的索引。我实际上从其他地方复制了这个语法,它适用于其他实例(例如,在分组条形图中着色系列的颜色),但我无法确切地告诉你它为什么有效...

任何指导都将不胜感激。 谢谢!

2 个答案:

答案 0 :(得分:5)

究竟是什么问题?您提供的代码可以回答您的问题。我的坏,j确实返回了对该系列的引用。更简单的例子。

   var data = [
        {id: 1, pts: [{x:50, y:10},{x:50, y:30},{x:50, y:20},{x:50, y:30},{x:50, y:40}]},
        {id: 2, pts: [{x:10, y:10},{x:10, y:30},{x:40, y:20},{x:30, y:30},{x:10, y:30}]}
    ];
    var vis = d3.select("svg");
    var series = vis.selectAll("g.series") 
        .data(data, function(d, i) { return d.id; })
        .enter() 
        .append("svg:g")
        .classed("series", true);

    series.selectAll("g.point")
        .data(function(d, i) { return d.pts })
        .enter()
        .append("svg:path")
        .attr("transform", function(d, i) { return "translate(" + d.x + "," + d.y + ")"; })
        .attr("d", function(d,i, j) { return d3.svg.symbol().type(d3.svg.symbolTypes[j])(); })

唯一的区别是我在d3.svg.symbol()之后添加了括号.type(currentType)()返回值而不是函数。 D3js使用链接,jquery风格。这允许你使用symbol()。type('circle')设置一个值和symbol()。type()来获取它。无论何时使用访问器,返回的内容都是对具有方法和属性的函数的引用。请记住,在Javascript函数中是第一类对象 - What is meant by 'first class object'?。在使用该方法的库中,通常会有一个明显的getter来检索有意义的数据。使用符号,您必须使用symbol()()。

符号功能之外的代码可在以下位置查看:https://github.com/mbostock/d3/blob/master/src/svg/symbol.js

d3.svg.symbol = function() {
  var type = d3_svg_symbolType,
      size = d3_svg_symbolSize;

  function symbol(d, i) {
    return (d3_svg_symbols.get(type.call(this, d, i))
        || d3_svg_symbolCircle)
        (size.call(this, d, i));
  }

  ...

  symbol.type = function(x) {
    if (!arguments.length) return type;
    type = d3_functor(x);
    return symbol;
  };


  return symbol;
};

答案 1 :(得分:0)

万一你还没有。你试过吗?

.append("svg:path")
.attr("d", d3.svg.symbol()) 

根据https://github.com/mbostock/d3/wiki/SVG-Shapes