弹出表单来编辑形状位置和标签? [英] Popup form to edit shape position and label?

查看:89
本文介绍了弹出表单来编辑形状位置和标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想单击一个形状以使用弹出表单编辑其文本标签和x,y坐标,该表单在提交后会更新该形状的数据,然后该形状移至新的x,y坐标.我一直无法在网上或普通书籍中找到类似的例子.

I want to click on a shape to edit its text label and x,y coordinates using a popup form that, when submitted, updates the data for that shape and the shape then moves to the new x, y coordinates. I've been unable to find any examples like this online or in the usual books.

页面上所有形状的数据都存储在JSON数组中.一些在线示例显示了如何就地"编辑文本或编辑单个值.这对我来说不起作用,因为只有标签应该显示在形状上,并且我想编辑通常在页面上不可见的多个形状参数.

Data for all shapes on the page is stored in a JSON array. Some online examples show how to edit text "in place" or edit a single value. This will not work for me, since only the label should be displayed on the shape and I want to edit multiple shape parameters not usually visible on the page.

如果可能的话,我想将解决方案保留为D3或基本的JavaScript.

I would like to keep the solution as D3 or basic JavaScript, if possible.

一个简单的示例显示了三个可单击的矩形: https://jsfiddle.net/NovasTaylor/oyL0hj3d/

A simple example showing three clickable rectangles is here: https://jsfiddle.net/NovasTaylor/oyL0hj3d/

当前"click"事件将标签,x和y值写入控制台.此事件应触发可编辑表单的显示.

The current "click" event writes the label, x and y values to the console. This event should trigger the display of the editable form.

rects.append("rect")
  .attr("x",     function (d)  { return d.x; })
  .attr("y",     function (d)  { return d.y; })
  .attr("height", function (d) { return d.height; })
  .attr("width",  function (d) { return d.width; })
  .style("fill",  function(d)  { return d.color; })
  .on("click", function(d){
    console.log("You clicked rectangle: " + d.label)
    console.log ("X position: " + d.x)
    console.log ("Y position: " + d.y)
  });

所有建议都值得赞赏,工作示例更是如此!

All advice greatly appreciated and working example even more so!

推荐答案

在D3中,覆盖原点非常简单.在侦听器中,其中d是第一个参数,只需执行以下操作:

In D3 it's quite simple to override the datum. Inside the listener where d is the first parameter, just do:

d.foo = bar;

在您的示例中,让我们使用prompt来获取新值.这只是一个演示如何演示的演示:您可以轻松地更改弹出式div的难看提示.

In your example, let's use prompt to get the new values. This is just a demo to show you how to do it: you can easily change the ugly prompts for fancy popup divs.

因此,在侦听器内部,我们获得了新的值...

So, inside the listener, we get the new values...

var newLabel = prompt("Please enter the new label: ");
var newX = prompt("Please enter the new x position: ");
var newY = prompt("Please enter the new y position: ");

...并使用它们重新定位矩形,同时覆盖基准:

... and use them to reposition the rectangles, overriding the datum at the same time:

d3.select(this)
    .attr("x", d.x = +newX)
    .attr("y", d.y = +newY);

唯一的问题是获取标签.由于您必须在DOM中上下移动,因此建议您给他们提供(唯一的)ID ...

The only problem is getting the labels. As you have to go up and down in the DOM, I suggest you to give them (unique) ids...

rects.append("text")
    .attr("id", function(d, i) {
        return "label" + i;
    })

...他们得到了他们:

... and them getting them:

d3.select(this.parentNode)
    .select("#label" + i)
    .text(newLabel)
    .attr("x", function(d) {
        return d.x + 10;
    })
    .attr("y", function(d) {
        return d.y + 10;
    });

这是您的代码,仅包含那些更改:

Here is your code with those changes only:

var rectData = [{
  "label": "one",
  "x": 100,
  "y": 50,
  "height": 100,
  "width": 120,
  "color": "green"
}, {
  "label": "two",
  "x": 250,
  "y": 50,
  "height": 100,
  "width": 120,
  "color": "purple"
}, {
  "label": "three",
  "x": 400,
  "y": 50,
  "height": 100,
  "width": 120,
  "color": "red"
}];

var svg = d3.select("body").append("svg")
  .attr("width", 600)
  .attr("height", 200);

var rects = svg.selectAll("rect")
  .data(rectData)
  .enter();

rects.append("rect")
  .attr("x", function(d) {
    return d.x;
  })
  .attr("y", function(d) {
    return d.y;
  })
  .attr("height", function(d) {
    return d.height;
  })
  .attr("width", function(d) {
    return d.width;
  })
  .style("fill", function(d) {
    return d.color;
  })
  .on('mouseover', function(d) {
    var rectSelection = d3.select(this)
      .style({
        opacity: '0.5'
      })
  })
  .on('mouseout', function(d) {
    var rectSelection = d3.select(this)
      .style({
        opacity: '1'
      })
  })
  .on("click", function(d, i) {
    var newLabel = prompt("Please enter the new label: ")
    var newX = prompt("Please enter the new x position: ")
    var newY = prompt("Please enter the new y position: ")
    d3.select(this).attr("x", d.x = +newX).attr("y", d.y = +newY);
    d3.select(this.parentNode).select("#label" + i).text(newLabel).attr("x", function(d) {
        return d.x + 10;
      })
      .attr("y", function(d) {
        return d.y + 10;
      })
  });

// Rectangle Label
rects.append("text")
  .attr("id", function(d, i) {
    return "label" + i;
  })
  .style("fill", "black")
  .attr("dy", ".35em")
  .attr("x", function(d) {
    return d.x + 10;
  })
  .attr("y", function(d) {
    return d.y + 10;
  })
  .text(function(d) {
    return "Label: " + d.label
  });

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

请记住,这是一个非常非常简单的演示:我既不检查输入的类型(字符串,整数,float ...)也不检查它们的值.

Have in mind that this is a very, very simple demo: I'm neither checking the type of the input (string, integer, float...) nor their values.

PS:如果您使用的是D3 v4(对您的代码来说,根本不需要更改!),则可以通过简单的selection.raise().

PS: If you were using D3 v4 (that, with your code, requires no change at all!), you could avoid the new-positioned rectangle going behind the other ones with a simple selection.raise().

这篇关于弹出表单来编辑形状位置和标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆