0
votes

I have Done a stacked Bar chart now I am extending the Chart feature as when mouseover on the legend the Respective Bars should highlight.

The Problem I am facing is the mouseover event is working on the Last legend only but but highlighting the every rect layer in chart.

The Problem shown in below fig.enter image description here This image is when I mouseover on D_Lines Legend Rect

My Code part is

var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var fData = 

[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},{
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}] 

var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];

        var layers = d3.layout.stack()(headers.map(function (count) {
            return fData.map(function (d) {
                // alert(d);
                return { x: d.ORDER_TYPE, y: +d[count] };
            });
        }));
        //StackedBar Rectangle Max

        var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
        // Set x, y and colors
        var xScale = d3.scale.ordinal()
     .domain(layers[0].map(function (d) { return d.x; }))
     .rangeRoundBands([25, width], .08);
        colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
        var y = d3.scale.linear()
            .domain([0, yStackMax])
            .range([height, 0]);
        var colorScale = d3.scale.ordinal()
    .domain(headers)
     .range(colors);

        // Define and draw axes
        var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .tickSize(1)
                    .tickPadding(6)
                    .orient("bottom");

        var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .tickFormat(d3.format(".2s"))



        var layer = svg.selectAll(".layer")
            .data(layers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function (d, i) { return colorScale(i); });

        var rect = layer.selectAll("rect")
            .data(function (d) { return d; })
            .enter().append("rect")
            .attr("x", function (d) { return xScale(d.x); })
            .attr("y", height)
            .attr("width", xScale.rangeBand())
            .attr("height", 0)
             .attr("class", function (d) {
                 return "rect bordered " + "color-" + colorScale(d.value).substring(1);
             });
        debugger;
        layer.selectAll("text.rect")
            .data(function (layer) { return layer; })
            .enter().append("text")
            .attr("text-anchor", "middle")
            .attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
            .attr("y", function (d) { return y(d.y + d.y0) - 3; })
            .text(function (d) { return d.y + d.y0; })
            .style("fill", "4682b4");

        //********** AXES ************

        svg.append("g")
             .attr("class", "x axis")
             .attr("transform", "translate(0," + height + ")")
             .call(xAxis)
             .selectAll("text").style("text-anchor", "end")
                 .attr("dx", "-.8em")
                 .attr("dy", ".15em")
                 .attr("transform", function (d) {
                     return "rotate(-45)"
                 });

        svg.attr("class", "x axis")
           .append("text")
           .attr("text-anchor", "end")  // this makes it easy to centre the text as the transform is applied to the anchor
           .attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")")  // centre below axis
           .text("Order Velocity Group");


        svg.append("g")
            .attr("class", "y axis")
            .attr("transform", "translate(20,0)")
            .call(yAxis)
          .append("text")
            .attr("transform", "rotate(-90)")
            .attr({ "x": -75, "y": -70 })
            .attr("dy", ".75em")
            .style("text-anchor", "end")
            .text("No. Of Lines");

        //********** LEGEND ************
        var legend = svg.selectAll(".legend")
                    .data(headers.slice().reverse())
                .enter().append("g")
                .attr("class", "legend")
                .attr("transform", function (d, i) { return "translate(" + i * (-100) + "," + (height + 50) + ")"; });

        debugger;
        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", function (d, i) { return colors[i]; })
        .on("mouseover", function (d, i) {
            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
        })
        .on("mouseout", function (d, i) {
            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
        });

        legend.append("text")
              .attr("x", width - 24)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "end")
              .text(function (d) { return d; });


        transitionStacked();
        function transitionStacked() {

            y.domain([0, yStackMax]);

            rect.transition()
                .duration(500)
                .delay(function (d, i) { return i * 10; })
                .attr("y", function (d) { return y(d.y0 + d.y); })
                .attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
              .transition()
                .attr("x", function (d) { return xScale(d.x); })
                .attr("width", xScale.rangeBand());

        };

   }

Can any one help me to overcome this problem.

1
could you post the complete code with your fData to observe the chart behavior.Amani Ben Azzouz
@Amani I have updated the question with fData Please Checkcharan tej
there is nothing wrog with you hover event your are only giving the wrong class to yours rect elementsAmani Ben Azzouz

1 Answers

1
votes

You are appending the same class : color-9999CC to all your rect elements, so once you hover the last legend item having color : #9999CC all rect element will be selected.

To create the required class properly, you can add the corresponding color info to each element in your layers object while creating it.

I added a color property that has as value the color of the corresponding headers item:

var layers = d3.layout.stack()(
     headers.map(function (count) {
            return fData.map(function (d,i) {
               return { x: d.orders, y: +d[count] , color:  colorScale(count)}; 
                                                   /*color = current headers item color */

            }); 
     }));

Then while creating your rect items you can add to each element a class by accessing its color property like this:

var rect = layer.selectAll("rect")
            .data(function (d) { return d; })
            .....
            .attr("class", function (d) {
                    return "rect bordered " + "color-" +d.color.substring(1);
            });

complete code:

var margin = {top:10, right: 10, bottom: 80, left: 50},
    width =960,
    height=650;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var fData = 

[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}] 

var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];
         var colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
          var colorScale = d3.scale.ordinal()
                             .domain(headers)
                             .range(colors);
        var layers = d3.layout.stack()(
           headers.map(function (count) {
            return fData.map(function (d,i) {
               return { x: d.orders, y: +d[count] , color:  colorScale(count)};
                
            }); 
        }));
        //StackedBar Rectangle Max

        var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
        // Set x, y and colors
        var xScale = d3.scale.ordinal()
     .domain(layers[0].map(function (d) { return d.x; }))
     .rangeRoundBands([25, width], .08);
       
        var y = d3.scale.linear()
            .domain([0, yStackMax])
            .range([height, 0]);
       
 
        // Define and draw axes
        var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .tickSize(1)
                    .tickPadding(6)
                    .orient("bottom");

        var yAxis = d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .tickFormat(d3.format(".2s"))



        var layer = svg.selectAll(".layer")
            .data(layers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function (d, i) { return colorScale(i); });
            

        var rect = layer.selectAll("rect")
            .data(function (d) { return d; })
            .enter().append("rect")
            .attr("x", function (d) { return xScale(d.x); })
            .attr("y", height)
            .attr("width", xScale.rangeBand())
            .attr("height", 0)
            .attr("class", function (d,i) {
                    return "rect bordered " + "color-" +d.color.substring(1);
            });
           
         
            
        layer.selectAll("text.rect")
            .data(function (layer) { return layer; })
            .enter().append("text")
            .attr("text-anchor", "middle")
            .attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
            .attr("y", function (d) { return y(d.y + d.y0) - 3; })
            .text(function (d) { return d.y + d.y0; })
            .style("fill", "4682b4");

        //********** AXES ************

        svg.append("g")
             .attr("class", "x axis")
             .attr("transform", "translate(0," + height + ")")
             .call(xAxis)
             .selectAll("text").style("text-anchor", "end")
                 .attr("dx", "-.8em")
                 .attr("dy", ".15em")
                 .attr("transform", function (d) {
                     return "rotate(-45)"
                 });

        svg.attr("class", "x axis")
           .append("text")
           .attr("text-anchor", "end")  // this makes it easy to centre the text as the transform is applied to the anchor
           .attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")")  // centre below axis
           .text("Order Velocity Group");


        svg.append("g")
            .attr("class", "y axis")
            .attr("transform", "translate(20,0)")
            .call(yAxis)
          .append("text")
            .attr("transform", "rotate(-90)")
            .attr({ "x": -75, "y": -70 })
            .attr("dy", ".75em")
            .style("text-anchor", "end")
            .text("No. Of Lines");

        //********** LEGEND ************
        var legend = svg.selectAll(".legend")
                    .data(headers)
                    .enter().append("g")
                    .attr("class", "legend")
                    .attr("transform", function (d, i) { return "translate(" +  (headers.length-(i+1))*-100 + "," + (height + 50) + ")"; });
        
        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", function (d, i) { return colors[i]; })
        .on("mouseover", function (d, i) {
        svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
        })
        .on("mouseout", function (d, i) {
            svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
        });

        legend.append("text")
              .attr("x", width - 24)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "end")
              .text(function (d) { return d; });


        transitionStacked();
        function transitionStacked() {

            y.domain([0, yStackMax]);

            rect.transition()
                .duration(500)
                .delay(function (d, i) { return i * 10; })
                .attr("y", function (d) { return y(d.y0 + d.y); })
                .attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
              .transition()
                .attr("x", function (d) { return xScale(d.x); })
                .attr("width", xScale.rangeBand());

        };
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.0/d3.min.js"></script>
<body></body>