2013-03-12 93 views
1

我使用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}]等]独特的符号每个数据D3散点图

写出符号的代码部分如下所示: 我为每个点的传染媒介。然后:

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()。如果我试图将该函数放在“类型”参数中,那么数据不再被正确地限定为知道j是什么(系列的索引)。

对,但我不想每个数据点都有一个唯一的符号,我想为每个系列设置一个唯一的符号。数据由多个数组组成(系列),每个数组可以有任意数量的点(x,y)。我想为每个阵列使用不同的符号,这就是j应该给我的。我将这些数据(例如,显示的两个数组,因此我是0,然后是1)与系列选择相关联。然后我将数据对象与点选择相关联,所以我成为每个数组中点的索引,并且j成为原始数组/数据序列的索引。其实,我从别的地方复制这种语法,它的作品确定为其它实例(着色系列例如分组条形图在酒吧),但我不能告诉你到底为什么它的工作原理...

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

+0

你能否澄清j的用法在你的“d”的属性功能的第三个参数?我不明白它传递英寸 – 2013-03-12 23:59:00

+0

安德鲁指出,鉴于.attr( “d”,函数(d,I,J){}),J应始终为0使用d3.svg.symbolTypes [I]相反,因为我引用每个数据点的(唯一)索引值。 – widged 2013-03-13 08:56:45

回答

0

万一你没有。你有没有尝试过?

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

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

+0

是的,试过了,它给了我每个数据点的相同符号,并不完全符合要求。 – user1885761 2013-03-13 14:29:18

+0

确实“[0,1,2] .forEach(function(d,i){console.log(i,d3.svg.symbol()());});”每次迭代返回相同的符号。 – widged 2013-03-13 23:19:50

+0

符号(datum [,index])似乎没有使用i值。 [0,1,2] .forEach(function(d,i){console.log(i,d3.svg.symbol(d,i)());});返回相同的符号。您建议的解决方法似乎是唯一一个返回不同符号的解决方案。 – widged 2013-03-13 23:21:44

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后添加括号()。类型(currentType)()返回的值,而不是功能。 D3js使用链接,jquery风格。这让你使用symbol()。type('circle')来设置一个值和符号()。type()来获取它。每当使用访问器时,返回的是对具有方法和属性的函数的引用。请记住,在JavaScript函数中是第一类对象 - What is meant by 'first class object'?。在使用这种方法的图书馆中,通常有一个显而易见的获取有意义数据的方法。使用符号,您必须使用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; 
}; 
+0

谢谢!这是完美的,非常感谢,修复和教程。 – user1885761 2013-03-14 19:24:42

+0

很高兴你发现它很有用。让我知道j。整齐。 – widged 2013-03-18 02:15:45