【问题标题】:D3js / AngularJS - drag and data bind the rect's coordinatesD3js / AngularJS - 拖动和数据绑定矩形的坐标
【发布时间】:2018-09-03 08:31:15
【问题描述】:

我想绑定rect的坐标x,y。(记录为“坐标”)。并拖动矩形,希望记录(坐标x,y)会同步变化。

以下是部分代码。(完整代码jsbin

html

<tr ng-repeat="item in data">
    <td>({{ item.x }}, {{ item.y }})</td>
    <td>{{ item.width }}</td>
    <td>{{ item.height }}</td>
</tr>

JS

$scope.data = [{ 'x': 30, 'y': 50, 'width': 90, 'height': 70 }];

var drag = d3.drag()        
    .on('drag', function (d) {
        d3.select(this)
            .attr('x', d.x = d3.event.x)
            .attr('y', d.y = d3.event.y)
    })
    .on('end', function (d) {
        //update  coordinate x ,y to array
        arrayNum = this.id;   
        $scope.data.splice(arrayNum, 1, { 'x': d.x, 'y': d.y, 'width': d.width, 'height': d.height });
        console.log($scope.data);
    });

我还有 $scope.data.splice 来更新数组。它确实更新了 $scope.data。 但它不适用于浏览器视图。我该如何修改?或者我可以参考什么?非常感谢!

【问题讨论】:

    标签: angularjs d3.js drag-and-drop angularjs-ng-model ng-bind


    【解决方案1】:

    似乎 Angular 不知道它的范围正在由 d3 事件更新。

    我将$scope.$apply() 添加到您的on end 处理程序中,并且每次拖动事件完成后,视图中的显示都会按预期更新。

    var mainApp = angular.module("mainApp", []);
    
    mainApp.controller('Controller', function($scope) {
      $scope.data = [{
        'x': 30,
        'y': 50,
        'width': 90,
        'height': 70
      }];
    
      var drag = d3.drag()
        .on('drag', function(d) {
          d3.select(this)
            .attr('x', d.x = d3.event.x)
            .attr('y', d.y = d3.event.y)
    
        })
        .on('end', function(d) {
          arrayNum = this.id;
    
          // Ensure angular knows about the update to its scope
          $scope.$apply(function() {
            //update  coordinate x ,y to array
            $scope.data.splice(arrayNum, 1, {
              'x': d.x,
              'y': d.y,
              'width': d.width,
              'height': d.height
            });
          });
          console.log($scope.data);
        });
    
      //create SVG
      var svg = d3.select('.Content')
        .append('svg')
        .attr('width', 300)
        .attr('height', 300)
        .style('border', '1px solid #000');
    
      var container = svg.append('g');
    
      container.append('svg:image')
        .attr('xlink:href', 'dog.jpg')
        .attr('x', 0)
        .attr('y', 0);
    
      container.data($scope.data)
        .append('rect')
        .attr('x', function(d) {
          return d.x;
        })
        .attr('y', function(d) {
          return d.y;
        })
        .attr('width', function(d) {
          return d.width;
        })
        .attr('height', function(d) {
          return d.height;
        })
        .attr('id', function(d, i) {
          return i;
        })
        .style('cursor', 'pointer')
        .call(drag);
    });

    另外,请阅读this answer,以更好地了解为什么在使用 d3 时可能需要这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多