简体   繁体   English

在 D3 svg 节点中添加外部对象作为 React 组件

[英]Adding Foreign Objects as React Components in a D3 svg node

I am working on a D3 React requirement where in if user clicks on a rectangle on svgm an input box is provided for text.我正在研究 D3 React 要求,如果用户单击 svgm 上的矩形,则会为文本提供输入框。 I want to use that input for updating another component in react app.我想使用该输入来更新反应应用程序中的另一个组件。 How do I do that using foreign object in svg.我如何在 svg 中使用国外的 object。 Is there any other way I can link a text box with a rectangle(drawn just above each rectangle) in d3 in React.有没有其他方法可以将文本框与 React 中 d3 中的矩形(绘制在每个矩形上方)链接起来。

My existing code snippet is here我现有的代码片段在这里

 d3.select('svg#target').append("g").selectAll("whatever").data([1,2,3,4]).enter().append("rect").attr("x", function(d, i) { var x = 200 * Math.sin(-60 * i * (Math.PI / 180)); return x - 50; }).attr("y", function(d, i) { var y = 200 * Math.cos(-60 * i * (Math.PI / 180)); return y - 20; }).attr("width", 100).attr("height", 40).attr("fill", "gray").on("click", function(d, i) { const count = i; d3.select(this).append("foreignObject").attr("x", function() { return 300 * Math.sin(-60 * i * (Math.PI / 180)) + 50; }).attr("y", function() { return 280 * Math.cos(-60 * i * (Math.PI / 180)); }).attr("width", 140).attr("height", 20).html(function(d, i) { return ( '<input type="text" id="attribute' + count + 'value="Text goes here" />' ); }); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg viewbox="-250 -250 500 500" width="400" id="target"></svg>

You were pretty close, you only need to change it so that the foreign object is not appended inside the <rect /> , but rather inserted as a sibling, like:您已经非常接近了,您只需要更改它,以便外国 object 不会附加到<rect />内,而是作为兄弟插入,例如:

<g>
  <rect x="-50" y="180" width="100" height="40" fill="gray"> 
  </rect>
  <rect x="-223.20508075688772" y="80.00000000000003" width="100" height="40" fill="gray">
  </rect>
  <rect x="-223.20508075688775" y="-119.99999999999996" width="100" height="40" fill="gray">
  </rect>
  <rect x="-50.0" y="-220" width="100" height="40" fill="gray">
  </rect>

  <foreignObject x="-50.0" y="-220" width="100" height="40">
    <input type="text" id="attribute3" value="text goes here">
  </foreignObject>
</g>

We can do this with this on line 24: d3.select(this.parentNode) which selects the parent, so now when we append, it becomes a sibling of the <rect /> , rather than a child.我们可以在第 24 行这样做: d3.select(this.parentNode)选择父节点,所以现在当我们 append 时,它成为<rect />的兄弟节点,而不是子节点。

 d3.select('svg#target').append("g").selectAll("whatever").data([1,2,3,4]).enter().append("rect").attr("x", function(d, i) { var x = 200 * Math.sin(-60 * i * (Math.PI / 180)); return x - 50; }).attr("y", function(d, i) { var y = 200 * Math.cos(-60 * i * (Math.PI / 180)); return y - 20; }).attr("width", 100).attr("height", 40).attr("fill", "gray").on("click", function(d, i) { const count = i; if (document.getElementById('attribute' + count)){ return 0; } d3.select(this.parentNode).append("foreignObject").attr("x", function() { var x = 200 * Math.sin(-60 * i * (Math.PI / 180)); return x - 50; }).attr("y", function() { var y = 200 * Math.cos(-60 * i * (Math.PI / 180)); return y - 20; }).attr("width", 100).attr("height", 40).html(function(d, i) { return ( `<input type="text" id="attribute${count}" style="height: 40px;" value="Text goes here" />` ); }); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg viewbox="-250 -250 500 500" width="400" id="target"></svg>

Demo:演示:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM