情况:
我正在使用d3覆盖的谷歌地图上工作。它主要基于迈克博斯托克的这个例子:http://bl.ocks.org/mbostock/899711
我正在使用Rails 4应用程序运行它,并从CDN加载到d3.js库中。因此可以访问d3.js和jQuery库,并且更愿意避免添加更多库。
任务:
数据点(由svg:rect
元素表示)有时会模糊谷歌地图上的地名。我想要它,以便用户可以将光标传递到这些数据点上,并且它们会暂时弹出。
我应该注意到我试图让这些点随机重新定位,所以不能真正进入悬停的CSS路线。
因此...
在SVG上放置一个事件监听器(或者取决于实际应该操作哪个元素的矩形)
编写一个回调函数,用于重新定位(偏移?动画?过渡?)触发事件的元素
等待setTimeout(或使用d3 .each("end",function())
),然后将元素返回到其先前位置
简单吧?
尝试:
所以,尝试使用d3然后尝试使用jQuery。受jQuery欢迎,因为它似乎没有处理SVG(虽然我可能不得不求助于使用jQuery-SVG库,如果d3.js没有通过商品)
使用d3尝试,事件处理程序分配很好。我已将处理程序分配给svg父元素,而不是rect子元素。
.on('mouseover', scatter)
这会产生事件触发的预期行为,并在鼠标悬停时调用散点函数。
但是,我无法明确表达我正在寻找的行为。
我尝试过更改x,y值。我试过改变顶部和左边的值。值似乎在对象上发生变化,但没有任何动作。我尝试过直接d3风格选择以及d3风格转换。
我在rect子元素上尝试了相同的更改。这会移动rect元素,但不会带SVG,因此不会显示。
相关代码:
将SVG附加到每个数据点,为SVG设置正确的x和y,并为每个数据点添加事件监听器。
var marker = layer.selectAll("svg")
.data(data)
.each(transformMarker)
.enter().append("svg:svg")
.each(transformMarker)
.on('mouseover', scatter);
另外,我将SVG父元素设置为包含rect子元素的样式,并设置样式的样式,以便实际显示在屏幕上。
transformMarker函数,您可能需要了解标记的定位方式。
function transformMarker(d) {
d = new google.maps.LatLng(J.lat(d), J.lon(d));
d = projection.fromLatLngToDivPixel(d);
return d3.select(this)
.style("left", (d.x) + "px")
.style("top", (d.y) + "px");
分散功能(使用一大堆console.logs,以便您可以看到正在发生的事情)
function scatter(d){
console.log("the event has fired")
d = new google.maps.LatLng(J.lat(d), J.lon(d));
d = projection.fromLatLngToDivPixel(d);
console.log(d.x)
console.log((d.x + 15) + "px")
console.log(this)
d3.select(this)
.attr("x", (d.x + 15))
.attr("y", (d.y + 15))
console.log(this)
控制台.logs抽出的内容
the event has fired
602.0032221842557
617.0032221842557px
<svg style="left: 602.0032221842557px; top: 230.00228557549417px;"
x="617.0032221842557" y="245.00228557549417">
<rect height="7" width="7" fill="#138770" stroke="#0f0f02" stroke-width="0.5"></rect>
</svg>
<svg style="left: 602.0032221842557px; top: 230.00228557549417px;"
x="617.0032221842557" y="245.00228557549417">
<rect height="7" width="7" fill="#138770" stroke="#0f0f02" stroke-width="0.5"></rect>
</svg>
SVG的CSS,因为这可能会在工作中抛出扳手
.overlay, .overlay svg {
position: absolute;
}
.wrapper, .overlay svg {
/*border: 1px solid black;*/
width: 7px;
height: 7px;
transform: translateZ(0px);
-webkit-transform: translateZ(0px);
-moz-transform: translateZ(0px);
}
我离文明只有几天了,所以希望能够解决这个问题,然后采用Stack Overflow和d3 google小组的一些新方法和一些建议回来。
如果您有任何其他问题或需要更多信息,请与我们联系。
答案 0 :(得分:0)
回顾一下:
每个数据点矩形都在其自己的单独 <svg>
元素中。在left
事件中,使用绝对定位(top
和transformMarker
样式)定位每个svg元素。
显然,如果要移动与数据点关联的svg图形,则需要更改<svg>
元素的定位。您尝试使用x
和y
属性进行此操作,但这不是SVG首先定位的方式。仅当<svg>
元素嵌入 另一个SVG时,这些属性才有意义。你的是绝对定位在页面上的独立元素。因此,您需要更改绝对定位样式值:
function scatter(d){
d = new google.maps.LatLng(J.lat(d), J.lon(d));
d = projection.fromLatLngToDivPixel(d);
d3.select(this)
.style("left", (d.x + 15) + "px")
.style("top", (d.y + 15) + "px")
}
另外,我不确定你为什么要在初始化时调用transformMarker
两次;你只需要一次,但要确保你保留的版本是在创建元素之后被称为的版本:
var marker = layer.selectAll("svg")
.data(data)
.enter().append("svg:svg")
.each(transformMarker)
.on('mouseover', scatter);
答案 1 :(得分:0)
我看看这个漂亮的random function for Sass
module Sass::Script::Functions
def random(max = Sass::Script::Number.new(100))
Sass::Script::Number.new(rand(max.value), max.numerator_units, max.denominator_units)
end
end
将随机函数添加到您的sass中,请查看this guide。如果你想让你的项目在mousever上随机重新定位,我会使用随机函数创建一个具有随机位置的类,并将该类移除/添加到元素中。当然,在我提供的链接中有一些使用随机函数的例子。
当然这很简单,只需将上面的代码添加到sass.rb中的config / initializers中。这是使用它的example rails app。
它的一个问题是,如果你在一个类中设置它,它只会生成一次随机数。在刷新和重新加载时,它不会为它生成的css生成新的随机上/下等。我不确定是否有解决方法,或者这是否真的有用。但它很有趣所以我想我还是会发布它。