Variable value seems not to change according to loop

Asked

Viewed 65 times

1

I have an array and am making a loop. Within this loop I take the total size of items from each array and mount an event onmouseover displaying a tooltip with these numbers. But when I hover the mouse over the element, it only displays a number for all elements: 76 distributors. Does not display the value of each. Now if I put one console.log below the variable total he shows me all the right values, but when it’s inside the 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);
  • You could put what GrupoPosicoesMapa seems? A console.log(GrupoPosicoesMapa) maybe?

  • @Nottherealhemingway it is an array with an array of objects inside. The values they return all right. If I put one console.log under total they appear the right count, now inside the "mouseover" it returns the same.

1 answer

0

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

var total = GrupoPosicoesMapa[indexGroup].length;

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

Well, as events occur just after the loop, the value of total will refer to the last element of Array of GrupoPosicoesMapa (okay, that will also depend on whether the object builder inherits Array).

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

let total = GrupoPosicoesMapa[indexGroup].length;

In Ecmascript 3 or Ecmascript 5 you can express a function in the body or block of the 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)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.