如何使用d3js选择多个svg元素

时间:2018-01-05 19:05:58

标签: javascript d3.js svg selection multipleselection

如何使用鼠标右键和CRTL键选择多个SVG元素?

我想要的是与我发现的this example相似(右边的部分)。 可以只选择一个元素,或者通过按住CTRL键,选择几个元素。

我查看了代码,但在我的情况下我无法重现代码。

我的情况: JSFIDDLE

我希望我可以选择更多圈子。 我希望当用户选择一个圆圈时,会打印所选圆圈的id。 当用户完成他想要的选择后,他按下Finish按钮,然后我想要打印所选项目的列表。

可以这样做吗?非常感谢任何帮助。

更新

我更改了@Shashank的代码,现在可以了。我希望它对某人有用:)

的index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.2.1.js"></script>
    <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
    <link rel="stylesheet" type="text/css" href="style.css" media="screen"/>
</head>

<body>

    <div id="circles">
        <svg>
            <circle id="first" cx="10" cy="10" r="10" fill="purple" />
            <circle id="second" cx="60" cy="60" r="5" fill="red" />
            <circle id="third" cx="110" cy="110" r="15" fill="orange" />
            <circle id="fourth" cx="90" cy="50" r="7" fill="yellow" />
        </svg>
    </div>

  <button type="button" id="finalSelection">Finish</button>

  <span style="display:block;margin-top: 10px;">Selected IDs: <span class="values"></span></span>
  <script src="script.js"></script>
</body>

</html>

的script.js

var selectedIds = [];

d3.selectAll('#circles svg circle').on('click', function() {
    // fetch ID
    var id = d3.select(this).attr('id');

    // toggle "clicked" class and push/splice id within the selectedIds array accordingly based on event.metaKey (CTRL)
    if(d3.select(this).classed('clicked')) { // classed add/remove a CSS class from the selection
        d3.select(this).classed('clicked', false).style('stroke', null);
        selectedIds.splice(selectedIds.indexOf(id), 1); // the splice() method adds/removes items to/from an array, and returns the removed item(s)
    } 
    else { // if an item has never been selected
        if(selectedIds.length) { // if the array selectedIds is not empty
            if(d3.event.ctrlKey) { // if CTRL is pressed
                d3.select(this).classed('clicked', true).style('stroke', 'blue');
                selectedIds.push(id); 
            }
            else { // *** OK *** if the item I'm selecting has never been selected and before I had already selected other elements
                // I "remove" all those already selected
                d3.selectAll(".clicked").classed('clicked', false).style('stroke', null);
                selectedIds = [];
                // I consider selected the one actually selected
                d3.select(this).classed('clicked', true).style('stroke', 'blue');
                selectedIds.push(id); 
            }
        } 
        else { // if the array selectedIds is empty
            d3.select(this).classed('clicked', true).style('stroke', 'blue');
            selectedIds.push(id);
        }
    }

    $('span.values').html(selectedIds.join(', '));
});

$('button#finalSelection').click(function() {
    $('span.values').html(selectedIds.join(', '));
    console.log("compare!")
});

的style.css

span.values {
  color: #428bca;
}
带有更新代码的

JSFIDDLE

1 个答案:

答案 0 :(得分:0)

确定可以。你确定它应该是鼠标右键单击和CTRL吗?

这是一个代码片段:

var selectedIds = [];

d3.selectAll('#circles svg circle').on('contextmenu', function() {
	// prevent default right click functionality
	d3.event.preventDefault();
  
  // fetch ID
	var id = d3.select(this).attr('id');
  
  // toggle "clicked" class and push/splice id within the selectedIds array accordingly based on event.ctrlKey (CTRL)
	if(d3.select(this).classed('clicked')) {
  	if(selectedIds.length > 1) {
    	if(d3.event.ctrlKey) {
	  		d3.select(this).classed('clicked', false).style('stroke', null);
  	  	selectedIds.splice(selectedIds.indexOf(id), 1);
      }
    } else {
  		d3.select(this).classed('clicked', false).style('stroke', null);
	    selectedIds.splice(selectedIds.indexOf(id), 1);    
    }  
  } else {
  	if(selectedIds.length) {
    	if(d3.event.ctrlKey) {
		  	d3.select(this).classed('clicked', true).style('stroke', '#000');
    		selectedIds.push(id); 
      }
    } else {
	  	d3.select(this).classed('clicked', true).style('stroke', '#000');
    	selectedIds.push(id);
    }
  }
  
  $('span.values').html(selectedIds.join(', '));
});

	$('button#finalSelection').click(function() {
  	  $('span.values').html(selectedIds.join(', '));
  });
span.values {
  color: #428bca;
}
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="utf-8">
  <script src="https://code.jquery.com/jquery-3.2.1.js"></script>
	<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
</head>

<body>

	<div id="circles">
		<svg>
			<circle id="first" cx="10" cy="10" r="10" fill="purple" />
			<circle id="second" cx="60" cy="60" r="5" fill="red" />
			<circle id="third" cx="110" cy="110" r="15" fill="orange" />
			<circle id="fourth" cx="90" cy="50" r="7" fill="yellow" />
		</svg>
	</div>
  
  <button type="button" id="finalSelection">Finish</button>
  
  <span style="display:block;margin-top: 10px;">Selected IDs: <span class="values"></span></span>
</body>

</html>

我在代码段中添加了评论,但让我告诉你它是如何运作的:

  1. 使用d3.select().on('contextmenu', function())鼠标右键单击事件监听器。
  2. 必须调用
  3. preventDefault()以防止鼠标右键单击的默认功能,即隐藏默认的上下文菜单。
  4. selectedIds是一个跟踪点击ID的数组。
  5. d3.event.ctrlKey在此处是 - 用于检查按住CTRL键。
  6. 添加了简单的HTML来打印ID。我想你可以从这里拿走它。
  7. 此外,如果您改变主意使其成为鼠标左键单击+ CTRL ,请将contextmenu更改为click并取消对{{}的调用1}}。

    如果您有任何疑问,请与我们联系。希望这会有所帮助:)