【问题标题】:How to select multiple svg elements using d3js如何使用 d3js 选择多个 svg 元素
【发布时间】:2018-06-15 15:08:31
【问题描述】:

如何使用鼠标右键和 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 更新代码。

【问题讨论】:

    标签: javascript d3.js svg selection multipleselection


    【解决方案1】:

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

    这是一个 sn-p 这样做的:

    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>

    我在 sn-p 中添加了 cmets,但让我告诉你它是如何工作的:

    1. d3.select().on('contextmenu', function()) 用于鼠标右键单击事件侦听器。
    2. 必须调用 preventDefault() 以防止鼠标右键单击的默认功能,即隐藏默认上下文菜单。
    3. selectedIds 是一个跟踪点击的 ID 的数组。
    4. d3.event.ctrlKey 是这里的 key -- 检查 CTRL 是否按下。
    5. 添加了简单的 HTML 来打印 ID。我想你可以从这里拿走。

    另外,如果您改变主意将其设为鼠标左键单击 + CTRL,请将 contextmenu 更改为 click 并拨打 preventDefault()。 p>

    如果您有任何问题,请告诉我。希望这会有所帮助:)

    【讨论】:

    • 感谢您的帮助,但您的代码不起作用。它只允许您选择一个圆圈,CRTL 键不起作用,甚至按钮也不起作用。我尝试使用鼠标左键(因此在click 中更改contextmenu 并删除preventDefault())或右键。
    • 糟糕,我很抱歉。我已经习惯了在 Mac 上使用 Command Key,所以我对它进行了相应的编码。我已将代码从d3.event.metaKey 更改为d3.event.ctrlKey。查看最新的编辑并告诉我。谢谢。
    猜你喜欢
    • 2015-05-30
    • 2013-11-11
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    相关资源
    最近更新 更多