2017-02-20 10 views
3

У меня есть сгруппированная гистограмма, похожая на https://bl.ocks.org/mbostock/3887051
я использовал функцию курсора, находящийся стираться брусками мышь в настоящее время не болееD3 Grouped Bar Chart - выбор всей группы?

function mouseover(bar) 
{ 
    d3.selectAll(".bar") 
    .filter(function(d){ return (d != bar);}) 
    .transition(t) 
     .style("opacity", 0.5); 
} 

В то время как это работает хорошо, чтобы выделить один бар, я теперь нужно выделить вся группа/исчезает все, кроме этой группы.
До сих пор мне не удалось выяснить, как добраться из элемента элемента d, пройденного через .on("mouseover", function(d) ... назад ко всей группе, к которой принадлежит этот элемент.
Есть ли простой способ добиться этого в D3v4?

ответ

2

В D3 4.0, callback function for the .on() method is passed 3 arguments: текущая точка привязки (D), то текущий индекс (i) и текущую группу (узлы).

В обратном вызове мыши можно указать selectAll("rect") и отфильтровать элементы, находящиеся в текущей группе (node). С помощью этого выбора вы установите непрозрачность на 0,5. На выводе вам просто нужно установить все непрозрачность на 1.0. Соответствующий код:

... 
    .on('mouseover', function(d, i, node) { 
    d3.selectAll("rect") 
     .filter(function (x) { return !isInArray(this, node)}) 
     .attr('opacity', 0.5); 
    } 
) 
    .on('mouseout', function() { 
    d3.selectAll("rect").attr('opacity', 1.0); 
    }); 

с небольшой вспомогательной функцией, чтобы проверить, если значение присутствует в массиве (массив элементов DOM в нашем случае):

function isInArray(value, array) { 
    return array.indexOf(value) > -1; 
} 

Полный код в контексте (с учетом вашего связанного примера):

g.append("g") 
.selectAll("g") 
.data(data) 
.enter().append("g") 
    .attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; }) 
.selectAll("rect") 
.data(function(d) { return keys.map(function(key) { return {key: key, value: d[key]}; }); }) 
.enter().append("rect") 
    .attr("x", function(d) { return x1(d.key); }) 
    .attr("y", function(d) { return y(d.value); }) 
    .attr("width", x1.bandwidth()) 
    .attr("height", function(d) { return height - y(d.value); }) 
    .attr("fill", function(d) { return z(d.key); }) 
    .on('mouseover', function(d, i, node) { 
    d3.selectAll("rect") 
     .filter(function (x) { return !isInArray(this, node)}) 
     .attr('opacity', 0.5); 
    } 
) 
    .on('mouseout', function() { 
    d3.selectAll("rect").attr('opacity', 1.0); 
    }); 
+0

Удивительное решение, спасибо! – TommyF

1

Одним из решений может быть:

сделать функцию, которая выбирает все группы и дает ему переход непрозрачностью 0.

DOM-на котором мыши над дать непрозрачности 1.

function hoverIn(){ 
    d3.selectAll(".group-me").transition() 
     .style("opacity", 0.01);//all groups given opacity 0 
    d3.select(this).transition() 
     .style("opacity", 1);//give opacity 1 to group on which it hovers. 
    } 

Сделайте функцию, которая выбирает всю группу и дает ей переход непрозрачности 1, когда мышь отсутствует.

function hoverOut(){ 
    d3.selectAll(".group-me").transition() 
     .style("opacity", 1); 
    } 

О группе добавить класс и добавить мышь, и в функции, как

g.append("g") 
    .selectAll("g") 
    .data(data) 
    .enter().append("g") 
    .classed("group-me", true)//add a class for selection. 
    .on("mouseover", hoverIn) 
    .on("mouseout", hoverOut) 

рабочий код here