我正在使用dc.js和d3.js创建交互式地图。地图应该支持缩放和平移,所以我正在使用d3.zoom行为。我还希望在单击地图上的区域时运行一个函数。代码在Firefox(Linux和Windows),IE和Chrome(Linux)中按预期工作,但Windows上的Chrome版本47将点击解释为尝试缩放,这会抑制点击事件。有什么方法可以避免这种情况吗?
我创建了一个简化的jsfiddle来演示这个问题。代码如下:
HTML
<div id="container"></div>
JS
var container = d3.select('#container');
var fmt = d3.format('.2f');
var svg = container.append('svg')
.attr('width', 400)
.attr('height', 400)
.append('g');
var colors = ['#444488', '#448844', '#884444'];
svg.selectAll('circle')
.data(colors)
.enter()
.append('circle')
.attr('cx', function(d, i) { return 50 + 100*i; })
.attr('cy', function(d, i) { return 50 + 100*i; })
.attr('r', function(d, i) { return 10 + 10*i; })
.style('fill', function(d) { return d; })
.on('click', function(d, i) {
// Skip the click handler if preventDefault was called. This prevents the click
// handler from running at the end of a drag.
if (!d3.event.defaultPrevented) {
console.log('clicked circle #' + i);
}
});
var zoomBehavior = d3.behavior.zoom()
.scale(1)
.scaleExtent([1, 15])
.translate([0, 0])
.on('zoom', function() {
console.log('got zoom: scale = ' + fmt(d3.event.scale) + ', translate = [' + fmt(d3.event.translate[0]) + ',' + fmt(d3.event.translate[1]) + ']');
svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
});
container.call(zoomBehavior);
该演示为SVG添加了三个圆圈,并为每个圆圈提供了一个点击处理程序。它还将d3.zoom行为添加到容器元素。我希望它能够做到以下几点:
Firefox和IE中的演示满足了所有这些要求。在Chrome中,当我点击一个圆圈时,运行缩放处理程序而不是单击处理程序。有没有人建议如何处理这个?
作为另一种方法,我尝试在SVG元素的其余部分上方或下方放置一个矩形,并将缩放行为附加到矩形而不是容器,但我遇到了各种问题,事件未达到正确的元素。如果人们认为这是最佳选择,我愿意进一步探索。
答案 0 :(得分:1)
我在旧版本的d3(3.3.3)中遇到了同样的问题。我不知道自那以后它是否已被修复。正如你所说,问题在于Chrome处于奇怪的状态,鼠标点击会触发鼠标移动事件。完全关闭Chrome并重新打开它似乎让它脱离了这种状态。
我能够通过检查d3的mousemove功能来解决这个问题。我在d3中的mousedowned()中向move()函数添加了两行:
function moved() {
if(d3.event.movementX === 0 && d3.event.movementY === 0) // new
return false; // new
dragged = 1;
translateTo(d3.mouse(target), l);
zoomed(event_);
}
这似乎可以在不重新启动Chrome的情况下解决问题。
答案 1 :(得分:0)
在我开发和调试时,我的Chrome实例必定会进入一些奇怪的状态。我重新启动Chrome并再次尝试,现在它正常工作。