gaup
gaup

Reputation: 129

D3.js mouseover event not working in bar charts

I have developed d3.js series bar chart,The chart is displaying correctly but the problem is I have to display tooltip on mouseover events of bars.But in my case mouseover event or infact any event is not working. The code for the whole bar chart is as below:

     var localfinaldata = [];
    var seriesData = "";
    var legendseperator = [];

    for (var i = 0; i < data.length; i++) {
        if (data[i].jobfamilydesc.length > 15) {
            data[i].jobfamilydesc = data[i].jobfamilydesc.substring(0, 15);
        }

    }
    var KeyGroup = [];
    for (var i = 0; i < data.length; i++) {
        KeyGroup.push(data[i].jobfamilydesc);
    }
    // KeyGroup = $.unique(KeyGroup);
    KeyGroup = KeyGroup.filter(function (itm, i, KeyGroup) {
        return i == KeyGroup.indexOf(itm);
    });
    var outerData = [];
    for (var j = 0; j < KeyGroup.length; j++) {

        var innerData = [];
        var items = {};
        items["key"] = KeyGroup[j];
        for (var i = 0; i < data.length; i++) {


            if (data[i].jobfamilydesc == KeyGroup[j]) {
                var item = {}
                item["genderkey"] = data[i].genderkey;
                item["HeadCount"] = data[i].HeadCount;
                innerData.push(item);
            }

        }
        items["details"] = innerData;
        outerData.push(items)
    }
    for (var i = 0; i < outerData.length; i++) {
        for (var j = 0; j < outerData[i].details.length; j++) {

            legendseperator.push(outerData[i].details[j].genderkey);
        }
    }
    legendseperator = $.unique(legendseperator);
    for (var i = 0; i < outerData.length; i++) {
        var itemupdated = {};
        var localdata = [];
        for (var j = 0; j < outerData[i].details.length; j++) {
            var item = {};
            item["genderkey"] = outerData[i].details[j].genderkey;
            item["count"] = outerData[i].details[j].HeadCount;
            localdata.push(item);

        }

        var flag = 0;
        for (var k = 0; k < legendseperator.length; k++) {
            for (var l = 0; l < localdata.length; l++) {
                if (legendseperator[k] == localdata[l].genderkey) {
                    flag = 1;
                    break;
                }
                else {
                    flag = 0;
                }

            }
            if (flag == 0) {
                var item = {};
                item["genderkey"] = legendseperator[k];
                item["count"] = 0;
                localdata.push(item);
            }
        }






        // Call Sort By Name
        localdata.sort(SortByName);
        itemupdated["data"] = localdata;
        itemupdated["names"] = outerData[i].key;
        localfinaldata.push(itemupdated);
    }
var margins = {
        top: 3,
        left: 10,
        right: 5,
        bottom: 90
    },
legendPanel = {
    width: 190
};
    var w = $('#jobDescriptionChart').width();
    var h = $('#jobDescriptionChart').height();
    var margin = { top: 10, right: 20, bottom: 30, left: 40 },
    width = w - margins.left - margins.right - legendPanel.width,
    height = 225- margins.top - margins.bottom;
    var padding = { top: 40, right: 40, bottom: 40, left: 40 };
    var x0 = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

//tooltip function
 var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function (d) {
      return "<strong>Frequency:</strong> <span style='color:red'>hju</span>";
  })


var x1 = d3.scale.ordinal();

    var y = d3.scale.linear()
        .range([height, 0]);

    var color = d3.scale.ordinal()
        .range(["#b91d47", "#e3a21a", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

    var xAxis = d3.svg.axis()
        .scale(x0)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .tickFormat(d3.format(".2s"));
    $('#jobDescriptionChart').html("");
    var svg = d3.select("#jobDescriptionChart").append("svg")
        .attr("width", width + margins.left + margins.right + legendPanel.width)
        .attr("height", height + margins.top + margins.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    svg.call(tip);

   var maxCount = 0;
    for (var j = 0; j < localfinaldata.length; j++) {
        for (var i = 0; i < localfinaldata[j].data.length; i++) {
            if (localfinaldata[j].data[i].count > maxCount) {
                maxCount = localfinaldata[j].data[i].count;
            }
        }
    }

    x0.domain(localfinaldata.map(function (d) { return d.names; }));
    x1.domain(legendseperator).rangeRoundBands([0, x0.rangeBand()]);
    y.domain([0, maxCount]);
    svg.append('g') // Container for the axis
             .attr({
                 class: 'yaxis',

                 height: height,

             })

      .call(yAxis);
    svg.append("g")
        .attr("class", "axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
    .selectAll("text")
                             .attr("x", ".0em")
                             .attr("y", "0em")
     .style("text-anchor", "end")
                            .attr("font-family", "Arial")
                            .attr("font-size", "13px")
                           .attr("transform", "rotate(-50)");
    var state = svg.selectAll(".name")
      .data(localfinaldata)
    .enter().append("g")
      .attr("class", "g")
      .attr("transform", function (d) {
          return "translate(" + x0(d.names) + ",0)";
      });

    $('.axis path').css("fill", "none");
    var rect = state.selectAll("rect")
          .data(function (d) { return d.data; })
        .enter().append("rect")

                  .attr({
                      y: height,
                      height: 0
                  })

          .transition()
                  .duration(1500)
          .attr("width", x1.rangeBand())

          .attr("x", function (d) {
              return x1(d.genderkey);
          })
          .attr("y", function (d) {
              return y(d.count);
          })
          .attr("height", function (d) {
              return height - y(d.count);
          })

          .style("fill", function (d) { return color(d.genderkey); })
          .on('mouseover', tip.show)
          .on('mouseout', tip.hide);






    legendseperator.forEach(function (s, i) {
        svg.append('rect')
           .attr('fill', color(legendseperator[i]))
           .attr('width', 20)
           .attr('height', 20)
           .attr('x', width + margins.left + 30)
           .attr('y', i * 24 + 115);//130
        svg.append('text')
            .attr('fill', 'black')
             .attr("font-size", "11")
            .attr('x', width + margins.left + 50)
            .attr('y', i * 24 + 132)//147
            .attr("font-family", "Arial")
            .text(s);

    });

Upvotes: 1

Views: 1550

Answers (1)

Mark
Mark

Reputation: 108537

Your method chaining is incorrect. You are attempting to call the .on on the transition returned from .transition, when you want to call it on the selection:

var rect = state.selectAll("rect")
    .data(function(d) {
      return d.data;
    })
    .enter()
    .append("rect")
    .attr({
      y: height,
      height: 0
    })
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide) //<-- call on selection before .transition
    .transition()
    .duration(1500)
    .attr("width", x1.rangeBand())
    .attr("x", function(d) {
      return x1(d.genderkey);
    })
    .attr("y", function(d) {
      return y(d.count);
    })
    .attr("height", function(d) {
      return height - y(d.count);
    })
    .style("fill", function(d) {
      return color(d.genderkey);
    });

Upvotes: 2

Related Questions