Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当d3中的点发生变化时更新多边形_Javascript_D3.js_Polygon - Fatal编程技术网

Javascript 当d3中的点发生变化时更新多边形

Javascript 当d3中的点发生变化时更新多边形,javascript,d3.js,polygon,Javascript,D3.js,Polygon,我目前正在处理d3中的多边形,希望在用户拖动点时更新单个多边形。最初绘制它们很好,但我无法让更新正常工作。下面这把小提琴包含了我让它工作的可怕尝试: 相关代码: const areas = [{ uid: 'ajf9v0', points: [{ x: 52, y: 92 }, { x: 50, y: 151 }, { x: 123,

我目前正在处理d3中的多边形,希望在用户拖动点时更新单个多边形。最初绘制它们很好,但我无法让更新正常工作。下面这把小提琴包含了我让它工作的可怕尝试:

相关代码:

const areas = [{
    uid: 'ajf9v0',
    points: [{
        x: 52,
        y: 92
      },
      {
        x: 50,
        y: 151
      },
      {
        x: 123,
        y: 149
      },
      {
        x: 125,
        y: 91
      }
    ],
    foo: 'bar',
    // ...
  },
  {
    uid: 'ufnf12',
    points: [{
        x: 350,
        y: 250
      },
      {
        x: 450,
        y: 250
      },
      {
        x: 450,
        y: 275
      },
      {
        x: 350,
        y: 275
      }
    ],
    foo: 'baz',
    // ...
  }
];

const svg = d3.select('#root');

svg.attr('width', 500)
  .attr('height', 500);

const areasGroup = svg.append('g')
  .attr('class', 'areas');

function drawAreas(areas) {

  console.log('Called draw');
  const self = this;

  const aGroup = areasGroup.selectAll('g.area')
    .data(areas, (d) => {
      console.log('Areas', d.points.map((d) => [d.x, d.y].join('#')).join('#'));
      return d.points.map((d) => [d.x, d.y].join('#')).join('#');
    });

  areasGroup.exit().remove();

  const areaGroups = aGroup.enter()
    .append('g')
    .attr('class', 'area');

  //const areaPolygon = area.append('g')
  //    .attr('class', 'polygon');

  //const areaPoints = area.append('g')
  //    .attr('class', 'points');

  const polygon = areaGroups.selectAll('polygon')
    .data((d) => {
      console.log('Polygon data points', [d.points]);
      return [d.points];
    }, (d) => {
      console.log('Polygon key', d.map((d) => [d.x, d.y].join('#')).join('#'));
      return d.map((d) => [d.x, d.y].join('#')).join('#');
    });

  polygon.enter()
    .append('polygon')
    .merge(polygon)
    .attr('points', (d) => {
      console.log('Polygon points', d);
      return d.map((d) => [d.x, d.y].join(',')).join(' ');
    })
    .attr('stroke', '#007bff')
    .attr('stroke-width', 1)
    .attr('fill', '#007bff')
    .attr('fill-opacity', 0.25)
    .on('click', this.handlePolygonSelection)

  polygon.exit().remove();

  const circles = areaGroups.selectAll('circle')
    .data((d) => d.points, (d) => d.x + '#' + d.y);

  circles.enter()
    .append('circle')
    .attr('r', 4)
    .attr('cx', (d) => d.x)
    .attr('cy', (d) => d.y)
    .attr('fill', '#007bff')
    .on('click', (d, idx, j) => {
      const parentArea = d3.select(j[idx].parentNode).datum().points;

      const i = parentArea.findIndex((p) => p.x === d.x && p.y === d.y);

      if (i === parentArea.length) {
        parentArea.pop();
      } else if (i === 0) {
        parentArea.shift();
      } else {
        parentArea.splice(i, 1);
      }

      this.drawAreas(areas);
    })
    .call(d3.drag()
      .on('start', function(d) {
        d3.select(this).classed('active', true)
      })
      .on('drag', function(d) {
        d3.select(this)
          .attr('cx', d.x = d3.event.x)
          .attr('cy', d.y = d3.event.y);
        self.drawAreas(areas);
      })
      .on('end', function(d) {
        d3.select(this).classed('active', false)
      }));

  circles.exit().remove();

}

this.drawAreas(areas);

感谢所有花时间查看的人,感谢所有帮助。

看来我发现了问题:

改变

const polygon = areaGroups.selectAll('polygon')

好像已经修好了。我假设这与仅处理enter事件的
areaGroups
选择有关

另一种选择是保持现状,改变现状

const areaGroups = aGroup.enter()
  .append('g')
  .attr('class', 'area');

这将产生相同的结果,因为更新事件现在也得到了适当的处理

const areaGroups = aGroup.enter()
  .append('g')
  .attr('class', 'area');
const areaGroups = aGroup.enter()
  .append('g')
  .merge(aGroup)
  .attr('class', 'area');