【问题标题】:Selecting a specific svg object using d3使用 d3 选择特定的 svg 对象
【发布时间】:2017-06-28 17:05:21
【问题描述】:

我在 d3 制作的 SVG 对象上有一个多边形。单击时,会打开一个带有两个按钮的“引导弹出框”。我希望能够单击链接并转换多边形(最终目标是在多边形顶部画一个圆)。目前,主要问题是我无法选择多边形并更改其属性。 这是我的代码:

  // create an svg element and append it
  canvas = d3.select("#map")
    .append("svg")
      .attr("width", 500)
      .attr("height", 500)
      .attr("id", "firstFloor");

  // draw polygon
  var coverageAreaIDA1 = 'roomA1';
  var content = '<button id="view" class="btn btn-sm btn-primary view-cam-btn">View Camera</button> <button id="set" class="btn btn-sm btn-primary set-dest-btn">Set Destination</button> <input type="hidden" name="coverage-area-id" value="'+coverageAreaIDA1+'">';
  var polygonA1 = [[65, 215], [65, 250], [140, 250], [140, 215]];
  var roomA1 = canvas.append("polygon")
    .attr("points", polygonA1)
    .attr("class", "coverage-area")
    .attr("id", coverageAreaIDA1)
    .attr("data-toggle", "popover")
    .attr('data-placement', 'top')
    .attr("data-content", content)
    .attr("tabindex", "0")
    .attr("data-trigger", "focus");

我尝试了很多方法,到目前为止,我最接近的是选择弹出框上的按钮及其值(与多边形 id 相同),将其放入 var 中,然后使用 d3 选择多边形,如下面的代码。

function badGuy() {
  $(document).on('click', '.view-cam-btn', function(){
    var coverageAreaID = $(this).nextAll('input').eq(0).val();
    var selection = canvas.select("#" + coverageAreaID).styles("fill", "purple");
    console.log('Selected polygon has ID '+selection.attrs('id'));
    });
}

我知道 'selection' 不是空或 null,因为当我测试它的真实性时它返回 true,但上面的 console.log 返回 "Selected polygon has ID [object Object]" 并且确实不改变多边形的样式。

PS:如果您想知道为什么我使用 attrs 而不是 attr 和 style 而不是 style,通过查看 StackOverflow 上的许多问题/答案,我想我应该添加这个库

<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>

并使用属性和样式。在此之前,console.log 没有返回任何内容。

编辑:完整代码: https://codepen.io/navidfalla/pen/xrpzXE

【问题讨论】:

  • 我想我可以帮助你,但如果你能提供你的 HTML 和完整的 JS 代码,我将不胜感激。
  • 这里是完整的代码:codepen.io/navidfalla/pen/xrpzXE 这是几百行代码,所以我尽量让它简单。但是你可以在右边看到我所说的多边形,如果你点击它们会有一个弹出框,我需要选择弹出框内的按钮。

标签: javascript jquery d3.js svg


【解决方案1】:

感谢代码.. 好吧,我做了一些修改,请尝试看看这是否是您想要的:

1 - 请将您的 createPopover 方法更改为:

function createPopover(roomId) {
     var content = '<button id="view" data-room-id="'+roomId+'" class="btn btn-sm btn-primary view-cam-btn">View Camera</button>'+
                   '<button id="set" data-room-id="'+roomId+'" class="btn btn-sm btn-primary set-dest-btn">Set Destination</button> ';
     return content;
}

这允许您通过 data-room-id 或 $(selector).data('roomId'); 轻松获取单击多边形的 ID;

2 - 请将设置目标按钮上的点击事件处理程序更改为:

$(document).on('click', '.set-dest-btn', function(){
    //var coverageAreaID = $(this).nextAll('input').eq(0).val();
    //console.log('set dest button has parent ID: '+coverageAreaID);

    var roomId = $(this).data('roomId'); 
    var polygon = d3.select('polygon#'+roomId);
    // do you stuff here with polygon
    polygon.style('fill','white'); 
  });

如您所见,您现在可以访问多边形。

为了更好地理解你的代码,我不得不稍微清理一下,你可以看看你是否喜欢它。 我没有以这种方式创建房间,而是创建了一种创建房间的方法:

function createRoom(number,polygon){
  var roomId = 'room'+number;
  var content = createPopover(roomId); 
  var room  = canvas.append("polygon")
    .attr("points", polygon)
    .attr("class", "coverage-area")
    .attr("id", roomId)
    .attr("data-toggle", "popover")
    .attr('data-placement', 'top')
    .attr("data-content", content)
    .attr("tabindex", "0")
    .attr("data-trigger", "focus");
    return room;
} 

然后以这种方式创建房间:

// draw polygon over stairwell
  var roomA1 = createRoom('A1',[[65, 215], [65, 250], [140, 250], [140, 215]]);
  var roomA2 = createRoom('A2',[[140, 215], [140, 278], [230, 278], [230, 215]]);
  var roomA3 = createRoom('A3',[[230, 215], [230, 278], [320, 278], [320, 215]]);
  var roomA4 = createRoom('A4',[[320, 215], [320, 278], [400, 278], [400, 215]]);
  var roomA5 = createRoom('A5',[[65, 250], [65, 278], [140, 278], [140, 250]]);
  var roomA6 = createRoom('A6',[[42, 215], [42, 278], [65, 278], [65, 215]]);
  var roomA7 = createRoom('A7',[[332, 120], [332, 215], [355, 215], [355, 120]]);
  var roomA8 = createRoom('A8',[[302, 120], [302, 215], [332, 215], [332, 120]]); 
  var roomA9 = createRoom('A9',[[302, 99], [302, 120], [355, 120], [355, 99]]);
  var roomA9 = createRoom('A10',[[408, 215], [408, 278], [462, 278], [462, 215]]);

请试试这个,看看这是不是你要找的,还是我误解了:)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2016-08-28
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 2020-02-24
    • 2012-03-08
    • 2020-11-10
    • 1970-01-01
    • 2021-04-14
    相关资源
    最近更新 更多