1

我正在尝试为我的可视化中的 SVG 元素创建 SVG 工具提示(简单的 DIV)。我使用 D3 javascript 库并使用内置的 D3 缩放行为,它可以转换和缩放 SVG 对象。单击SVG元素时,我想在它们旁边创建工具提示。工具提示应该与 SVG 对象一起移动,但它们不应该被鼠标滚轮缩放。相反,我想删除缩放开始时的所有工具提示,并在缩放结束后重新创建它们。

我得到它的工作,但我仍然有问题。工具提示的位置计算正常,即使它们被缩放。我还可以使用 SVG 对象沿屏幕移动它们。问题是如果我先用鼠标移动 SVG 对象,创建一个工具提示并再次移动 SVG 对象。然后工具提示会跳转。我也无法在缩放开始时删除它们并在缩放完成时重新创建。

这是一个展示我的方法的小例子:

var tooltipCounter = 0;

var  svgElement = d3.select('body')
    .append("svg:svg")
    .attr('width', '100%')
    .attr('height', '100%');

var container = svgElement.append('svg:g');

var circle = container.append('svg:circle')
    //.attr('cx', 100)
    //.attr('cy', 100)
    .attr('transform', 'translate(100,100)')
    .attr('r', 30)
    .attr('fill', 'red')
    .on('click', createTooltip);

svgElement.call(d3.behavior.zoom().on('zoom', redrawOnZoom));

 function redrawOnZoom(){
    container.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' +         d3.event.scale + ')')
    var tooltips = $("[id$=tooltip] ");
    for (var i=0; i<tooltips.length; i++) {
        var tooltip = tooltips[i];
        tooltip.style['-webkit-transform'] = "translate(" + d3.event.translate[0] + "px," +  d3.event.translate[1] + "px)"
    }
};

function createTooltip(){
    tooltipCounter ++
    var tooltipId = tooltipCounter + '_tooltip'
    // get the transformation matrix of the circle
    var transMat = circle[0][0].getCTM();
    var x = transMat.e;
    var y = transMat.f;
    var scale = transMat.d; 
    var radius = parseInt(circle.attr('r'))

    var margin = parseInt(d3.select('body').style('margin'))

    var tooltip = d3.select('body').append('xhtml:div')
        .attr('id', tooltipId)
        .style('position', 'absolute')
        .style('background', 'gray')
        .style('left', x + (scale * radius) + margin + 'px')     
        .style('top', y + (scale * radius/2) + margin + 'px')
        .html('<- This is tooltip.');

}

这是一个有效的 JsFiddle 代码:http: //jsfiddle.net/HzBQg/

编辑 :

我设法通过将容器的当前缩放值与缩放事件的缩放值进行比较来检测滚动/缩放。不确定这是否是最好的方法,但它有效,我可以在移动滚轮时删除所有工具提示。缩放行为结束后,我仍然不知道如何重新创建它们。在移动 SVG 对象后创建工具提示时我仍然遇到问题。

在这里更新了 JsFiddle http://jsfiddle.net/HzBQg/1/

4

1 回答 1

2

我解决了我的问题,虽然解决方案并不完美,但它确实有效。

var dx = d3.event.translate[0] - container[0][0].getCTM().e;
var dy = d3.event.translate[1] - container[0][0].getCTM().f;

container.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' + d3.event.scale + ')')
var tooltips = $("[id$=tooltip] ");
    for (var i=0; i<tooltips.length; i++) {
        var tooltip = tooltips[i];
        if (scrolling){
            tooltip.parentNode.removeChild(tooltip)
        }
        else{
            tooltipTransMat = $('#'+tooltip.id).css("-webkit-transform").match(/(-?[0-9\.]+)/g);
            tooltip.style['-webkit-transform'] = "translate(" + (parseFloat(tooltipTransMat[4])+dx) + "px," + (parseFloat(tooltipTransMat[5])+dy) + "px)"
        }
    }

你可以在这里看到它的作用:http: //jsfiddle.net/HzBQg/3/

于 2013-07-30T09:07:53.520 回答