问题描述
我想将决策树显示为具有某种交互性的SVG.不同的路径都在那里,并且悬停时它们的不透明度增加了.但是,悬停状态似乎仅适用于顶部元素.
I want to display a decision tree as a SVG with somer interactivity. The different paths are all there and on hover have their opacity increased. But the hover state seems to apply only to the top element.
#flow polyline {
stroke: #0071bc;
stroke-opacity: 0;
stroke-width: 8px;
mix-blend-mode: color;
}
#flow polyline:hover {
stroke-opacity: 1;
}
https://jsfiddle.net/yv82f3ud/
如何将悬停事件应用于所有悬停的svg折线,而不仅仅是顶层?
How can I apply the hover event on all hovered svg polylines, not only the top layer?
后续问题:有没有一种方法可以将悬停状态应用到更宽的路径上,所以我不必完全越过线路?
Followup question:Is there a way to have a wider path are on which the hover state is applied so I don't have to be exactly over the line?
推荐答案
没有简单的方法.您需要检测结束的部分,确定应突出显示的部分,然后自己手动突出显示它们.
There is no trivial way. You would need to detect which section you are over, determine which ones should be highlighted, then manually highlight them yourself.
是的,请使用一条单独的透明粗线
Yes, use a separate transparent thicker line
.line {
stroke: grey;
stroke-width: 2;
}
.line-wider {
stroke: transparent;
stroke-width: 40;
}
g:hover .line {
stroke: blue;
}
<svg>
<g>
<path d="M0,50 L 300,50" class="line"/>
</g>
<g>
<path d="M0,100 L 300,100" class="line"/>
<path d="M0,100 L 300,100" class="line-wider"/>
</g>
</svg>
您可以在透明的粗线部分上使用鼠标悬停事件,来确定所经过的部分,并以此为基础进行突出显示.
You can use mouseover events on thick transparent line sections as a way to determine which section you are over, and do your highlighting based on that.
类似以下内容:
// Add event listener to each "line-wider" path, that highlights the sections
var sections = document.querySelectorAll(".line-wider");
sections.forEach(function(elem) {
elem.addEventListener("mouseover", doHover);
elem.addEventListener("mouseout", clearHover);
});
var highlightedSections = {
's1': '.s1, .s11, .s12, .s111, .s112, .s121, .s122',
's11': '.s1, .s11, .s111, .s112',
's12': '.s1, .s12, .s121, .s122',
's111': '.s1, .s11, .s111',
's112': '.s1, .s11, .s112',
's121': '.s1, .s12, .s121',
's122': '.s1, .s12, .s122'
};
function doHover(evt) {
// Which section are we hovering over?
var id = evt.target.id;
// highlightedSections[id] is a CSS selector which selects all the sections which should be highlighted for this hover section
document.querySelectorAll(highlightedSections[id]).forEach( function(elem) {
// Add the "highlight" class to all the matching sections
elem.classList.add("highlight");
});
}
// Remove the "highlight" class from all elements which currently have it set
function clearHover(evt) {
document.querySelectorAll(".highlight").forEach( function(elem) {
elem.classList.remove("highlight");
});
}
.line {
fill: none;
stroke: grey;
stroke-width: 2;
}
.line-wider {
fill: none;
stroke: transparent;
stroke-width: 40;
}
.highlight {
stroke: blue;
}
<svg width="400" height="500">
<!-- top section -->
<path d="M 200,0 L 200,100" class="line s1"/>
<path d="M 200,0 L 200,100" class="line-wider" id="s1"/>
<!-- left branch -->
<path d="M 200,100 L 100,200, 100,300" class="line s11"/>
<path d="M 200,100 L 100,200, 100,300" class="line-wider" id="s11"/>
<!-- left branch -->
<path d="M 100,300 L 50,350, 50,450" class="line s111"/>
<path d="M 100,300 L 50,350, 50,450" class="line-wider" id="s111"/>
<!-- right branch -->
<path d="M 100,300 L 150,350, 150,450" class="line s112"/>
<path d="M 100,300 L 150,350, 150,450" class="line-wider" id="s112"/>
<!-- right branch -->
<path d="M 200,100 L 300,200, 300,300" class="line s12"/>
<path d="M 200,100 L 300,200, 300,300" class="line-wider" id="s12"/>
<!-- left branch -->
<path d="M 300,300 L 250,350, 250,450" class="line s121"/>
<path d="M 300,300 L 250,350, 250,450" class="line-wider" id="s121"/>
<!-- right branch -->
<path d="M 300,300 L 350,350, 350,450" class="line s122"/>
<path d="M 300,300 L 350,350, 350,450" class="line-wider" id="s122"/>
</svg>
这篇关于SVG悬停状态不仅在顶层,而且在多层上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!