gpt4 book ai didi

javascript - d3.js 触摸并按住以创建从一个元素到另一个元素的直线

转载 作者:行者123 更新时间:2023-11-29 19:19:19 26 4
gpt4 key购买 nike

我正在尝试在 android 上使用 d3.js 创建一个可视化(使用 apache cordova),我在手机屏幕上显示一些元素(例如圆圈)并有可能在元素之间创建链接(例如线) .

它应该如何工作:

  1. 触摸并按住开始元素
  2. 拖到第二个元素
  3. 发布

现在应该在两个元素之间形成一个新链接。我可以使用鼠标事件相对轻松地实现这一点,但我很难使用触摸支持实现同样的目标。

这是展示我面临的问题的最小示例。

var width = 350,
height = 600,
colors = d3.scale.category10();

var nodeData =
[
{ id: 1, x: 50, y: 50 },
{ id: 2, x: 200, y: 50 },
{ id: 3, x: 125, y: 150 }
];

var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);


var node = svg.selectAll('g')
.data(nodeData)
.enter()
.append('g');

node.append('circle')
.attr('cx', function (d) { return d.x; })
.attr('cy', function (d) { return d.y; })
.attr('r', 30)
.attr('fill', 'red')
.on('touchstart', function (node) {
})
.on('touchend', function (node) {
});

node.append('text')
.attr('fill', 'white')
.attr('x', function (d) { return d.x; })
.attr('y', function (d) { return d.y; })
.text(function (d) { return d.id; });
<script src="https://d3js.org/d3.v3.min.js"></script>

在这个例子中,touchend 事件总是在与 touchstart 相同的元素上执行,我找不到一种方法来获取触摸顶部的元素操作已结束。

我刚开始使用 d3.js,所以非常感谢您的帮助。

干杯

最佳答案

您可以切换到使用命中(碰撞)检测:

 svg.on('touchmove', function() {
var p = d3.touches(this)[0];

endNode = undefined;
cs.each(function(d) {
var self = d3.select(this),
x = d.x - p[0],
y = d.y - p[1],
l = Math.sqrt(x * x + y * y),
r = 30;

if (l < r) {
endNode = d;
}
});
});

如果移动事件“击中”一个圆,endNode 将被定义。

然后在您的 touchend 事件中,检查我们是否在一个圆圈上开始和停止:

svg.on('touchend', function(){
if (startNode && endNode){
svg.append("path")
.style("fill", "none")
.style("stroke", "black")
.attr("d", "M" + startNode.x + "," + startNode.y + "L" + endNode.x + "," + endNode.y);
}
startNode = undefined;
endNode = undefined;
});

运行代码:

<!DOCTYPE html>
<html>

<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
<script>
var width = 350,
height = 600;
//colors = d3.scale.category10();

var nodeData = [{
id: 1,
x: 50,
y: 50
}, {
id: 2,
x: 200,
y: 50
}, {
id: 3,
x: 125,
y: 150
}];

var startNode, endNode;

var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);

svg.on('touchmove', function() {
var p = d3.touches(this)[0];

endNode = undefined;
cs.each(function(d) {
var self = d3.select(this),
x = d.x - p[0],
y = d.y - p[1],
l = Math.sqrt(x * x + y * y),
r = 30;

if (l < r) {
endNode = d;
}
});
});
svg.on('touchend', function(){
if (startNode && endNode){
svg.append("path")
.style("fill", "none")
.style("stroke", "black")
.attr("d", "M" + startNode.x + "," + startNode.y + "L" + endNode.x + "," + endNode.y);
}
startNode = undefined;
endNode = undefined;
cs.attr("fill", "red");
})

var node = svg.selectAll('g')
.data(nodeData)
.enter()
.append('g');

var cs = node.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', 30)
.attr('fill', 'red')
.on('touchstart', function(d) {
startNode = d;
});

node.append('text')
.attr('fill', 'white')
.attr('x', function(d) {
return d.x;
})
.attr('y', function(d) {
return d.y;
})
.text(function(d) {
return d.id;
});
</script>
</body>

</html>

关于javascript - d3.js 触摸并按住以创建从一个元素到另一个元素的直线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42754826/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com