2015-09-17 5 views
0

У меня есть такой объект, data, с которым я хочу создать выделение.Распространять данные от выбора родителя к ребенку (D3)

var data = [ 
    { 
    range: 30, 
    color: 'blue', 
    }, 
    { 
    range: 50, 
    color: 'red' 
    } 
]; 

Так что я сделать что-то вроде

var group = chart.selectAll('g') 
    .data(data) 
.enter().append('g'); 

Теперь я хочу добавить несколько circle элементов, равное data['range'].

var circle = group.selectAll('circle') 
    .data(function(d) { return d3.extent(d.range); }) 
.enter().append('circle'); 

Так вот мой вопрос, что лучшая практика для возможности доступа к данным от выбора родителей в своих детях. Например, я хочу получить доступ к data['color'] в нескольких атрибутах circle.

До сих пор я с помощью each(), чтобы затем применить атрибут к элементу circle рекурсивно

var circle = group.selectAll('circle') 
    .data(function(d) { return d3.range(d.range); }) 
.enter().append('circle'); 

circle.each(function(d) { 
    var parentData = this.parentNode.__data__; 
    d3.select(this).attr('fill', function() { return parentData.color; }); 
}); 

Есть более эффективная практика для связывания с исходными данными, один, который не требует использование each() и доступ к родительским данным через this.parentNode.__data__?

+0

Есть несколько способов. Однако то, что вы хотите сделать, неясно. Поскольку вы создаете круги на основе 'd3.extent (d.range)', это означает, что вы создадите только 2 круга - тогда какой цвет вы хотите получить? – Gildor

+0

Прошу прощения, я хотел сказать 'd3.range (d.range)', внесенные изменения. Я хочу, чтобы цвет отражал цвет, указанный в родительских данных. Если 30 элементов 'circle' привязаны к первому объекту в' data', я хочу иметь возможность легко получить доступ к данным [0] .color' во всех элементах 'circle'. Имеет ли это смысл? – Himmel

ответ

1

Как правило, самым простым способом является создание объекта, который содержит как значение диапазона, так и цвет.

Например:

var circle = group.selectAll('circle') 
    .data(function(d) { 
    return d3.range(d.range).map(function (rangeValue) { 
     // returns an item that combines range value and color from parent data 
     return { 
     range: rangeValue, 
     color: d.color 
     }; 
    }); 
    }) 
.enter() 
    .append('circle') 
    .attr('r', function (d) { return d.range; }) 
    .attr('fill', function (d) { return d.color; }); 
+1

@Himmel Если вы хотите редактировать имя переменной, вы можете изменить оба события ... – Gildor