鼠标悬停事件超时

Mouseover event timeout

在这里您可以找到 csv 文件https://www.dropbox.com/s/0ekwalkwqahl806/PeriodicTable.csv?dl=0

<!DOCTYPE html>
<meta charset="utf-8">
<html>
  <head>

    <style>
    rect.bordered {
      stroke: grey;
      stroke-width:2px;
    }
    text.mono {
      font-size: 9pt;
      font-family: Consolas;
      fill: blue;
    }
    </style>

    <script src="http://d3js.org/d3.v3.js"></script>

  </head>
  <body>

    <div id="chart" ></div>

    <script type="text/javascript" >
//cree les variables
      var margin = { top: 50, right: 0, bottom: 0, left: 30 },
          width = 960 - 30 ,
          height = 430 - 50 ,
          espacecases = 3
          gridSize = Math.floor(width / 18),//changer la taille du tableau
          ys = ["1", "2", "3", "4", "5", "6", "7"],
          xs = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"];

// cree la base du svg
      var svg = d3.select("#chart")
                  .append("svg")
                  .attr("width", width + 90)                                              //+70 por agrandire vers la droite
                  .attr("height", height + 250)                                           //+200 pour agrandir l espace por l immage
                  .append("g") // crée un groupe contenant le tp
                  .attr("transform", "translate(" + 30 +"," + 50+ ")");// bouger le tp pour avoir de la place pour les axes

//axe des y
      var yLabels = svg.selectAll(".yLabel")
                       .data(ys)
                       .enter()
                       .append("text")
                       .text(function (d) { return d; })
                       .attr("x", 0)
                       .attr("y", function (d, i) { return i * (gridSize + 10 + espacecases); })             // + espacecases +10 car rectangle
                       .style("text-anchor", "end")
                       .attr("transform", "translate(-6," + gridSize / 1.5 + ")")
                       .attr("class", "yLabel mono axis");

// graduation axe des x
      var xLabels = svg.selectAll(".xLabel")
                       .data(xs)
                       .enter().append("text")
                       .text(function(d) { return d; })
                       .attr("x", function(d, i) { return i * (gridSize+ espacecases); }) //function (d,i) avec d=data et i=index of data
                       .attr("y", 0)
                       .style("text-anchor", "middle")
                       .attr("transform", "translate(" + gridSize / 2 + ", -6)")
                       .attr("class", "xLabel mono axis");

// prendre les données du fichier csv

      var newlist = function(csvFile){
          d3.csv(csvFile,function(d){
            return {
              AtomicNumber: d.AtomicNumber,
              Element:      d.Element,
              Symbole:      d.Symbole,
              AtomicWeight: d.AtomicWeight,
              Period:       d.Period,
              Group:        d.Group,
              Phase:        d.Phase,
              MostStableCrystal: d.MostStableCrystal,
              Type:         d.Type,
              IonicRadius:  d.IonicRadius,
              AtomicRadius: d.AtomicRadius,
              Electronegativity: d.Electronegativity,
              FirstIonizationPotential: d.FirstIonizationPotential,
              Density:      d.Density,
              MeltingPointK: d.MeltingPointK,
              BoilingPointK: d.BoilingPointK,
              Isotopes:     d.Isotopes,
              Discoverer:   d.Discoverer,
              YearofDiscovery: d.YearofDiscovery,
              SpecificHeatCapacity: d.SpecificHeatCapacity,
              ElectronConfiguration: d.ElectronConfiguration,
              DisplayRow: d.DisplayRow,
              DisplayColumn: d.DisplayColumn,};
          },

// traitement des données

        function(error,data) {
          var cards = svg.selectAll(".DisplayRow")
                         .data(data, function(d) {
                           return d.DisplayRow+':'+d.DisplayColumn;
                         });

          var word = function(d) {return (d.Element) ; };

          var g = cards.enter()
                       .append('g')
                       .attr("id", function(d){return d.Type})
                       .append('g')
                       .attr("id",function(d) {return "element"+(d.AtomicNumber)})
                       .on("click", function(d) { if (d.Symbole!="Hg") { return window.open("http://en.wikipedia.org/wiki/"+word(d), '_blank')}
                                                  else  { return window.open("http://en.wikipedia.org/wiki/"+word(d)+"_(element)", '_blank') };
                                                                   });


              g.attr("transform", function(d){
                                 var x = (d.DisplayColumn - 1) * (gridSize + espacecases),
                                     y = (d.DisplayRow - 1) * (gridSize + 10 + espacecases);
                        return "translate(" + x + "," + y + ")";
                        });

              g.append("rect")
               .attr("rx", 4) // arrondir les cases des elements
               .attr("ry", 4) // arrondir les cases des element
               .attr("class", "xpos bordered") // class=style definit dans le head
               .attr("width", gridSize) //largeur des cases d elements
               .attr("height", gridSize+10) //Hauteur...       //+10 pour faire rectangle
               .transition()
               .duration(2000)
               .style("fill", function(d) {
                     if (d.Type =="Transition Metal") {return "LightSkyBlue"}
                     else if (d.Type =="Alkali Metal")   { return "royalblue" }
                     else if (d.Type =="Noble Gas")   { return "Salmon" }
                     else if (d.Type =="Metalloid")   { return "grey" }
                     else if (d.Type =="Metal")   { return "Peru" }
                     else if (d.Type =="Nonmetal")   { return "gold" }
                     else if (d.Type =="Halogen")   { return "orange" }
                     else if (d.Type =="Alkaline Earth Metal")   { return "hotpink" }
                     else if (d.Type =="Lanthanide")   { return "YellowGreen" }
                     else if (d.Type =="Actinide")   { return "PapayaWhip" }
                     else if (d.AtomicNumber <= 112)   { return "LightSkyBlue" }
                     else if (d.AtomicNumber <= 116)   { return "Peru" }
                     else if (d.AtomicNumber <= 117)   { return "orange" }
                ;}) ;


              g.append("text")
               .text(function(d){
                  return (d.AtomicNumber);
                })
               .style("font-size",10)
               .attr("x", +10)
               .attr("y", +10)
               .style("text-anchor", "middle");

               g.append("text")
                .text(function(d) {
                  return (d.Symbole);
                })
                .style("font-size",30)
                .attr("x", +25)
                .attr("y", 40)
                .style("text-anchor", "middle")
                .on("mouseover", function(d){
                  var x = (d.DisplayColumn - 1) * (gridSize + espacecases),
                      y = (d.DisplayRow - 1) * (gridSize + 10 + espacecases);
                         d3.select("body")
                           .select("#element"+(d.AtomicNumber))
                           .transition()
                           .ease("quad")
                           .duration("500")
                           .attr("transform", "translate(" + 200 +"," + 20+ ") scale( 2.5 )")
                })
                .on("mouseleave", function(d){
                  var x = (d.DisplayColumn - 1) * (gridSize + espacecases),
                      y = (d.DisplayRow - 1) * (gridSize + 10 + espacecases);
                         d3.select("body")
                           .select("#element"+(d.AtomicNumber))
                           .transition()
                           .ease("quad")
                           .duration("300")
                           .attr("transform", "translate("+ x +"," + y+ ") scale( 1 )")
                });

               g.append("text")
                .text(function(d) {
                  return (d.AtomicWeight) ;
                })
                .style("font-size",7)
                .attr("x", +25)
                .attr("y", +50)
                .style("text-anchor", "middle")
                .text(word);


               g.append("text")
                .text(function(d) {
                 return (d.AtomicWeight) ;
               })
                .style("font-size",7)
                .attr("x", +25)
                .attr("y",+57)
                .style("text-anchor", "middle");

               g.append("text")
                .text(function(d) {
                  return (d.YearofDiscovery) ;
                 })
                .style("font-size",7)
                .attr("x", +40)
                .attr("y",+10)
                .style("text-anchor", "middle")
                .text(function(d) { return (d.YearofDiscovery) ; });

                //d3.select("body").selectAll("#Nonmetal").remove();
                //d3.select("body").select("#element1").remove();


     });

      };

newlist("PeriodicTable.csv")
  </script>

  </body>
</html>

我从 csv.file 创建了一个周期性的 table。我在 svg 中绘制了所有元素,每个元素都有自己的 id 组。现在我试图在鼠标停留在原子符号上时显示更大的元素。但是这个更大的元素是 unstable,它在闪烁(去和回来)。我认为解决这个问题的一个好方法是为鼠标悬停添加持续时间,但我不知道该怎么做。如果您认为这不是问题,还有另一种方法,我愿意!

您似乎将鼠标事件处理程序附加到每个化学符号的 <text> 元素。这不是最好的主意,因为当您越过字母的实心部分时会触发 mouseover,而当您越过字母之间和字母内部的间隙时会触发 mouseleave。我认为这就是您出现闪烁问题的原因。

您应该做的是将事件附加到每个化学元素的矩形背景上。

然后你会发现当你移动到文本上时 mouseleave 会触发。 要解决此问题,请将 pointer-events: none 添加到 CSS 以用于矩形内的所有文本元素。或者添加属性 pointer-events="none"(如果您愿意)。

问题是处理 mouseenter/mouseleave 事件的元素是由于转换而被重新定位的元素之一。因此,一旦它开始远离鼠标,它就会触发 mouseleave 事件并返回。

我解决的方法是在外部 g 元素上添加初始定位以及鼠标事件处理。您还需要在其中添加一个透明矩形,以便在您开始移动内部 g 元素后它具有内容。

所以修改的部分是

     var gg = cards.enter()
                   .append('g')
                   .attr("id", function(d){return d.Type}),
           g = gg.append('g')
                   .attr("id",function(d) {return "element"+(d.AtomicNumber)})
                   .on("click", function(d) { if (d.Symbole!="Hg") { return window.open("http://en.wikipedia.org/wiki/"+word(d), '_blank')}
                                              else  { return window.open("http://en.wikipedia.org/wiki/"+word(d)+"_(element)", '_blank') };
                                                               });


          gg.attr("transform", function(d){
                             var x = (d.DisplayColumn - 1) * (gridSize + espacecases),
                                 y = (d.DisplayRow - 1) * (gridSize + 10 + espacecases);
                    return "translate(" + x + "," + y + ")";
                    })
            .append('rect')
            .attr("width", gridSize) //largeur des cases d elements
            .attr("height", gridSize+10) //Hauteur...       //+10 pour faire rectangle
            .style("fill","transparent");

          g.append("rect")
           .attr("rx", 4) // arrondir les cases des elements
           .attr("ry", 4) // arrondir les cases des element
           .attr("class", "xpos bordered") // class=style definit dans le head
           .attr("width", gridSize) //largeur des cases d elements
           .attr("height", gridSize+10) //Hauteur...       //+10 pour faire rectangle
           .transition()
           .duration(2000)
           .style("fill", function(d) {
                 if (d.Type =="Transition Metal") {return "LightSkyBlue"}
                 else if (d.Type =="Alkali Metal")   { return "royalblue" }
                 else if (d.Type =="Noble Gas")   { return "Salmon" }
                 else if (d.Type =="Metalloid")   { return "grey" }
                 else if (d.Type =="Metal")   { return "Peru" }
                 else if (d.Type =="Nonmetal")   { return "gold" }
                 else if (d.Type =="Halogen")   { return "orange" }
                 else if (d.Type =="Alkaline Earth Metal")   { return "hotpink" }
                 else if (d.Type =="Lanthanide")   { return "YellowGreen" }
                 else if (d.Type =="Actinide")   { return "PapayaWhip" }
                 else if (d.AtomicNumber <= 112)   { return "LightSkyBlue" }
                 else if (d.AtomicNumber <= 116)   { return "Peru" }
                 else if (d.AtomicNumber <= 117)   { return "orange" }
            ;}) ;


          g.append("text")
           .text(function(d){
              return (d.AtomicNumber);
            })
           .style("font-size",10)
           .attr("x", +10)
           .attr("y", +10)
           .style("text-anchor", "middle");

           g.append("text")
            .text(function(d) {
              return (d.Symbole);
            })
            .style("font-size",30)
            .attr("x", +25)
            .attr("y", 40)
            .style("text-anchor", "middle");

          gg.on("mouseover", function(d){
              var x = (d.DisplayColumn - 1) * (gridSize + espacecases),
                  y = (d.DisplayRow - 1) * (gridSize + 10 + espacecases);
                     d3.select("body")
                       .select("#element"+(d.AtomicNumber))
                       .transition()
                       .ease("quad")
                       .duration("500")
                       .attr("transform", "translate(" + (200-x) +"," + (20-y)+ ") scale( 2.5 )")
            })
            .on("mouseleave", function(d){
              var x = (d.DisplayColumn - 1) * (gridSize + espacecases),
                  y = (d.DisplayRow - 1) * (gridSize + 10 + espacecases);
                     d3.select("body")
                       .select("#element"+(d.AtomicNumber))
                       .transition()
                       .ease("quad")
                       .duration("300")
                       .attr("transform", "scale( 1 )")
            });

演示在 http://plnkr.co/edit/4jyRLSVuVMv3rfnwbJc5?p=preview