1

Solved: jsfiddle

Issue #1: Have a grouped bar chart. I'd like the group to highlight if any bars in the group are moused-over.

Currently on mouseover sets all rects with class 'bar' to opacity 0.5 and then the specific rect to opacity 1. But how can I set the node or group of bars to opacity 1, so that they are highlighted against the others?

.on("mouseover", function(d, i, node) { //this is repeated should be in a function
        d3.selectAll(".bar").transition()
          .style("opacity", 0.3); //all groups given opacity 0
        d3.select(this).transition()
          .style("opacity", 1); //give opacity 1 to group on which it hovers.
        return tooltip
          .style("visibility", "visible")
          .html("<span style=font-size:30px;> " + "name:" + d.name +
            "</span>"
          )
      })
      .on("mouseout", function(d) {
        d3.selectAll(".bar").transition()
          .style("opacity", 1);
        return tooltip.style("visibility", "hidden");
      })

Issue #2: Also I would like the bar's x axis labels to behave similarly. So that the names of all but the current bar would have opacity 0.5

I did try adding a clas of bar to the xAxis text, but doesn't work,

.call(xAxis)
      .selectAll("text")
      .style("text-anchor", "end")
      .style("font", "20px times")
      .attr("dx", "-.8em")
      .attr("dy", ".15em")
      .attr("class", "bar")
      .attr("transform", "rotate(-65)");

I this try implementing ideas from this post

D3 Grouped Bar Chart - Selecting entire group?

but I haven't been able to get it to work.

My attempt to give a class of d.name + index to each bar in a group. But I can't select then, the return "." + d.name isn't working as I'd expect.

      .attr("class", function(d, i) {
       return d.name.replace(/\s/g, '') + i + " bar"
      })
      .on("mouseover", function(d, i, node) { 
        d3.selectAll(".bar").transition()
          .style("opacity", 0.3); 
        d3.selectAll("." + d.name.replace(/\s/g) + i)
          .transition()
          .style("opacity", 1); 
        return tooltip
          .style("visibility", "visible")
          .html("<span style=font-size:30px;> " + "name:" + d.name +
            "</span>");
      })

The select should be,

d3.selectAll("." + d.name.replace(/\s/g, '') + i)

Actually each bar in each group could just be given a class of "group + index". There is no need for the regular expression.

Except for the text on the xAxis the highlighting is now working fine.

Any help would be greatly appreciated,

Thanks

Shane G
  • 3,129
  • 10
  • 43
  • 85

2 Answers2

2

you could base the opacity for all bars on its .name value (which is common attribute per group in your example), eg

.on("mouseover", function(d) { 
    let selectedName = d.name;
    d3.selectAll(".bar")
      .style("opacity", function(d) {
        return d.name == selectedName ? 1 : 0.3;
      })

    //etc
Tom Shanley
  • 1,757
  • 1
  • 7
  • 9
  • Yes I was just thinking if that thanks. But of course there is the unlikely possibility of two people having the same name and the name actually comes as a first and second name and so two classes and more change people clash on second names. – Shane G Aug 10 '17 at 00:08
  • Maybe a combination of first and second name trimmed with id concatenated. So that john murphy could become johnmurphy16 for index 16. I think that will be unique for each bar always. – Shane G Aug 10 '17 at 00:10
  • I can add a class of name with white space removed and index concatenated like this .attr("class", function(d, i) { return d.name.replace(/\s/g, '') + i + " bar" }) – Shane G Aug 10 '17 at 00:23
  • Actually each bar in each group could just be given a class of "group + index". There is no need for the regular expression. – Shane G Aug 10 '17 at 07:36
0

This works jsFiddle

.on("mouseover", function(d, i, node) {
        d3.selectAll(".bar").transition()
          .style("opacity", 0.3);
        d3.selectAll(".xAxisText").transition()
          .style("fill", "lightgray")
          .style("font-weight", "100"); //all groups given opacity 0
        d3.selectAll(".groupText" + i)
          .transition()
          .style("font-weight", "900")
          .style("fill", "black"); //give opacity 1 to group on which it hovers.
        d3.selectAll(".group" + i)
          .transition()
          .style("opacity", 1);
        return tooltip
          .style("visibility", "visible")
          .html("<span style=font-size:30px;> " + "name: " + d.name +
            " (on blue bar)</span>");
      })
      .on("mouseout", function(d) {
        d3.selectAll(".bar").transition()
          .style("opacity", 1);
        d3.selectAll(".xAxisText").transition()
          .style("fill", "black")
          .style("font-weight", "normal");
        return tooltip.style("visibility", "hidden");
      })
Shane G
  • 3,129
  • 10
  • 43
  • 85