D3js / AngularJS - 拖动和数据绑定矩形的坐标
D3js / AngularJS - drag and data bind the rect's coordinates
我想绑定rect的坐标x,y(记录为"Coordinate ")。并拖动矩形,希望记录(坐标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。
但它不适用于浏览器视图。我该如何修改?或者我可以参考什么?非常感谢!
似乎 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 时可能需要这样做。
我想绑定rect的坐标x,y(记录为"Coordinate ")。并拖动矩形,希望记录(坐标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。 但它不适用于浏览器视图。我该如何修改?或者我可以参考什么?非常感谢!
似乎 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 时可能需要这样做。