Variable value does not seem to change according to the loop

1

I have an array and am looping. Inside this loop I take the total size of items from each array and I am summing a onmouseover event displaying a tooltip with those numbers. But when I hover over the element, it only displays a number for all elements: 76 distributors . It does not display the value of each. Now if I put a console.log below the total variable it shows me all the correct values, but when it's inside onmouseover it returns me the same. The code I have is:

setTimeout(function(){

        var tooltip = d3.select("body")
        .append("div")
        .style("position", "absolute")
        .style("z-index", "10")
        .style("visibility", "hidden")
        .style("background", "#FFF");

        var GrupoPosicoesMapa = GeraPosicoesDistribuidores(Posicoes);

        if(GrupoPosicoesMapa != ''){

          for(indexGroup in GrupoPosicoesMapa){

            //var indexArray = randFunction(0, sizeof(GrupoPosicoesMapa[indexGroup]));

            var ObjectGroup = GrupoPosicoesMapa[indexGroup][0];

            var total = GrupoPosicoesMapa[indexGroup].length;

            var circleSelection = group.append("circle")
                                              .attr('id', 'bolha')
                                              .attr('cx', ObjectGroup.x)
                                              .attr('cy', ObjectGroup.y)
                                              .attr('r', 5)
                                              .attr('stroke', 'gray')
                                              .attr('stroke-width', 1)
                                              .attr('fill', 'red')
                                              .on("mouseover", function(){

                                                      console.log('Total:', total);
                                                      return tooltip.style("visibility", "visible")
                                                      .style("padding", "10px")
                                                      .style("border", "1px solid #ccc")
                                                      .style("border-radius", "6px")
                                                      .html(total+' distribuidor(es)'); //alterado 6 = 1

                                                    })
                                                    .on("mousemove", function(){

                                                      return tooltip.style("top", (d3.event.pageY-10)+"px")
                                                      .style("left",(d3.event.pageX+10)+"px");
                                                    })

                                                    .on("mouseout", function(){


                                                      return tooltip.style("visibility", "hidden");
                                                })
                                                .on('click', function(){

                                                  // AbreModalDistribuidores(v.codigo_distribuidor);
                                                  // console.log(v.codigo_distribuidor);

                                                });

                var textSelection = circleSelection.append("text")
                                                 .attr('font-size', 16)
                                                 .attr('fill', 'white')
                                                 .attr('font-family', 'Arial')
                                                 .attr('text-anchor', 'middle')
                                                 .attr('alignment-baseline', 'baseline')
                                                 .attr('x', ObjectGroup.x + 1.5)
                                                 .attr('y', ObjectGroup.y + 6)
                                                 .text(total);

          }
        }

        }, 4000);
    
asked by anonymous 17.03.2017 / 20:57

1 answer

0

The problem is that the variable total is always being declared in the current scope, not in the for... in block (and you always refer to the same variable). For example, the line:

var total = GrupoPosicoesMapa[indexGroup].length;

is re-defining the value of the total variable that belongs to the scope of the function given to setTimeout() , at the top.

Well, since events occur shortly after the loop, the value of total will refer to the last element of Array of GrupoPosicoesMapa (okay, this will also depend on whether the constructor of the object inherits Array ).

Based on ES6, you can declare the variable total in the block of for... in using const or let instead of var .

let total = GrupoPosicoesMapa[indexGroup].length;

In ECMAScript 3 or ECMAScript 5 you can express a function in the body or block of for... in (because the function will generate a scope).

function handle(indexGroup) { /* Aqui fica o corpo do loop */ }

for (var k in GrupoPosicoesMapa) handle(k)
    
18.03.2017 / 18:13