鼠标悬停事件超时
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 )")
});
在这里您可以找到 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 )")
});