【问题标题】:Reposition tooltip relative to SVG element for responsive page相对于响应式页面的 SVG 元素重新定位工具提示
【发布时间】:2016-10-03 20:29:11
【问题描述】:

我使用 SVG 矩形和文本元素作为工具提示。它们都在一个 SVG 元素中,该元素是美国县的地图。

如果我的地图是固定高度(我只是在鼠标附近偏移 svg 的坐标),工具提示就可以正常工作,但如果我让我的地图具有响应性或用户决定放大,则工具提示会失去功能给定的区域。

见图片:http://imgur.com/a/ae1Bd

我的 SVG 文件位于 https://codeshare.io/GcJIS,因为它对于这个站点来说太长了。

我只是迷路了。我最初尝试制作一个简单的 div 工具提示(使用 CSS)而不是使用 SVG,但它使我的 svg 地图“反弹”的 div 容器像疯了一样。我尝试了 D3,但发现自己更加困惑。我觉得有一些简单的东西我只是忽略了,但我一直在为尝试实现这个“简单”功能而自责。任何帮助或指导表示赞赏。

window.onload=function() {
			
				var panZoom = window.panZoom = svgPanZoom('#svgObj', {
					zoomEnabled: true,
					controlIconsEnabled: true,
					dblClickZoomEnabled: false,
				});
				
				 $(window).resize(function(){
			          panZoom.resize();
			          panZoom.fit();
			          panZoom.center();
			        })
	
			        var eastCoastStates = [ 'MA', 'RI', 'CT', 'NJ',
			                                'DE', 'MD', 'DC', 'ME', 'NH', 'NY', 'PA',
			                                'VA', 'NC', 'SC', 'FL', 'GA', 'WV', 'VT' ];
	
				var svgDoc = $("#svgObj")[0].contentDocument; // Get the document object for the SVG
				var county;
				$("path", svgDoc).each(function(){	
					county = $(this).attr('inkscape:label');	//name of the county and state abbr i.e. "Travis County, TX
						$(this).attr("title", county);
						$(this).append("<title>"+ county+ "</title>"); 
						$(this).removeAttr('inkscape:label');
				});

				var cssValue; //global variable, stores fill color on mouse enter for use in mouseout
				
				$("path", svgDoc).mouseenter(function(event){		
				
					var current_id = $(this).attr('id');
					if (current_id != "separator"       //ignore anything not a county
							&& current_id != "State_Lines"
							&& current_id != "metadata3671"
							&& current_id != "defs9561"
							&& current_id != "base"
							&& current_id != "State_borders") {

						var countySt = $(this).attr('title');
						var countyStArray = countySt.split(",");
						var stateAbbr = countyStArray[1].trim();


						var countyBahAmount = countiesBah[countySt];
						if (countyBahAmount == undefined)
							countyBahAmount = "Unknown Bah Amount";

						var width = 4.7 * ($(this).attr('title').length + 2 + countyBahAmount.length); //defines the length of the SVG text box based on the inside text length

						$("#textBox", svgDoc).attr('width', width);
						$("#textSvg", svgDoc).text(
								$(this).attr('title') + ": "
										+ countyBahAmount);

						var xPos = event.pageX;
						var yPos = event.pageY;
						
						
						
						if (eastCoastStates.indexOf(stateAbbr) > -1) { // Check to see if the element is a East Coast State, 
																	   // this will offset the tooltip to the left so it's not out of view
																	   // made some readjustments, need to fix
							$("#textSvg", svgDoc).attr('x', xPos - 300);
							$("#textBox", svgDoc).attr('x', xPos - 300);

							$("#textSvg", svgDoc).attr('y', yPos - 91);
							$("#textBox", svgDoc).attr('y', yPos - 100);
						} else {

							$("#textSvg", svgDoc).attr('x', xPos - 153);
							$("#textBox", svgDoc).attr('x', xPos - 155);

							$("#textSvg", svgDoc).attr('y', yPos - 120);
							$("#textBox", svgDoc).attr('y', yPos - 130);

						}
						
						$("#textSvg", svgDoc).attr('visibility','display');
						$("#textBox", svgDoc).attr('visibility','display');

					}
	
					

					cssValue       = $(this).css('fill');						 
					var classAttr  = $(this).attr('class');
					var current_id = $(this).attr('id');
					if (current_id    != "separator"   	 && current_id != "State_Lines" 
						&& current_id != "svg9559"  	 && current_id != "metadata3671" 
						&& current_id != "defs9561" 	 && current_id != "base" 
						&& current_id != "State_borders" && current_id != "svg-pan-zoom-reset-pan-zoom" 
						&& classAttr != "svg-pan-zoom-control-element" && classAttr !="svg-pan-zoom-control-background"){
						$(this, svgDoc).css("fill", "lime");
					}  
					
				});

				$("path", svgDoc).mouseout(function(){ 

					$("#textSvg", svgDoc).attr('visibility', 'hidden');
					$("#textBox", svgDoc).attr('visibility', 'hidden');
					
					var classAttr  = $(this).attr('class');
					var current_id = $(this).attr('id');
					
					if (current_id    != "separator" && current_id != "State_Lines"   
						&& current_id != "svg9559"   && current_id != "metadata3671" 
						&& current_id != "defs9561"  && current_id !="base"
						&& classAttr  != "svg-pan-zoom-control-element" && classAttr !="svg-pan-zoom-control-background"){
						$(this, svgDoc).css("fill", cssValue);  		 //fill the path element back to it's original color
					}  
				});

				$("path", svgDoc).dblclick(function(){
					var nameSt    = $(this).attr('title');
					var index     = nameSt.indexOf(",");
					var county    = nameSt.substring(0, index);
					var stateAbbr = nameSt.substring(index + 1);
					
					$("#var1").val(county.trim() + " County");
					$("#var2").val(stateAbbr.trim());
					$("#form").submit();
				});
				
				
				
};
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Choropleth of Avg Bah Rate Per County</title>

<script src="js/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="js/svg-pan-zoom.min.js"></script>
<script src="js/countiesBahRates.js"></script>
<script src="js/choropleth.js"></script>

<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />

<style>
.svg-container { 
	display: inline-block;
	position: relative;
	width: 67%;
	padding-bottom: 50%; 
	vertical-align: middle; 
	overflow: hidden;
}
.svg-content { 
	display: inline-block;
	position: absolute;
	top: 0;
	left: 0;
}


</style>
</head>
<body>
	<form style="display: hidden" action="CountyColleges" method="GET" id="form">
		<input type="hidden" id="var1" name="countyName" value="" /> 
		<input type="hidden" id="var2" name="stateAbbr" value="" />
	</form>
	<div class="container">
		<div class="row">
			<div class="col-md-2">
		      <p>  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has 
		        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the indust
		        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has
			  </p>
		
		</div>

			<div class="col-md-10" style="background:#F0F8FF;text-align:center; border:3px;border-style:inset;">
		
				<object  id="svgObj" data="UnitedStatesCounties.svg" type="image/svg+xml" 
					width="100%" height="100%" > </object>
			</div>
		</div>
	</div>
</body>
</html>

【问题讨论】:

    标签: javascript jquery svg tooltip responsive


    【解决方案1】:

    您需要使用 SVG 的 getCTM() 函数来获取当前的变换矩阵。然后您可以将屏幕点转换回内部 SVG 坐标。然后你就有了放置工具提示的位置。

    // create an SVG DOM point object
    pt = pt = svg.createSVGPoint();
    pt.x = screenXPosWithinSVG;
    pt.y = screenYPosWithinSVG;
    
    // Transform it back to SVG coordinate space
    var svgCoord = pt.matrixTransform(svg.getCTM().inverse());
    
    // Place tooltip at (svgCoord.x, svgCoord.y)
    

    【讨论】:

    • 感谢您的回复,我对编程还是很陌生,我想知道您是否在 HTML 文档中使用了用于 javascript/SVG 的永恒库(我正在获取一个 svgDoc。 createSVGPoint 不是函数错误)或者我是否应该将此脚本放在 SVG 对象本身中?
    • createSVGPoint()SVGSVGElement DOM 对象的标准DOM 函数,它对应于&lt;svg&gt; 元素。在您的情况下,svgDoc 设置为 HTMLObjectElement.contentDocument,这是一个 Document 对象。要获得对根 SVG 元素的引用,您需要使用 svg = svgDoc.documentElement
    • 谢谢!!我让它工作了。似乎 svg-pan-zoom.min.js 库是罪魁祸首(除了我缺乏知识和能力),而 Firefox 出于某种原因不想再工作了。再次感谢你,我学到了很多。
    • @EricMatthew 您能偶然发布您的解决方案吗?我也在使用 svgPanZoom 库,并试图相对于平移/缩放 svg 定位元素。
    猜你喜欢
    • 2014-04-21
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多