gpt4 book ai didi

javascript - 在单击的文本元素上绘制箭头?

转载 作者:行者123 更新时间:2023-11-28 16:36:05 25 4
gpt4 key购买 nike

我正在尝试使单个单词/短语可点击,并且在选择两个单词/短语后,提供一个选项以从一个单词到另一个单词画一条线(带箭头)。我怎样才能在 d3 中实现这一目标?

这是一个 fiddle我可以选择文本的地方(只需选择文本范围或双击单词)。现在我需要做的就是在选定的文本元素上启用“单击”并从一个元素绘制一个箭头到另一个元素。有什么建议吗?

这是目前的代码:

body = d3.select('body')

svg = body.append('svg')
.attr('height', 600)
.attr('width', 600);

var g = svg.append('g').attr("transform" ,"scale(0)");

rect = g.append('rect')
.attr('width', 300)
.attr('height', 300)
.attr('x', 40)
.attr('y', 100)
.style('fill', 'none')
.attr('stroke', 'black')

text = g.append('foreignObject')
.attr('x', 50)
.attr('y', 130)
.attr('width', 280)
.attr('height', 280)
.append("xhtml:body")
.html('<p style="width: 280px;">This is some information about whatever where I want two words to be clickable individually and then provide a way to drag from one word to another to draw an arrow</p>').on('click', function() {
console.log(d3.select(this).text());
});

g.transition().duration(500).attr("transform" ,"scale(1)");

d3.selectAll("p").on("mouseup", checkSelection)
.on("keyup", checkSelection);

function checkSelection(d,i) {
var selection = document.getSelection();

if (selection.isCollapsed) return;

var range = selection.getRangeAt(0);
highlightRange(range);
}

function highlightRange(range) {
var newNode = document.createElement("div");
newNode.setAttribute(
"style",
"background-color: yellow; display: inline;"
);
range.surroundContents(newNode);
}

最佳答案

使用 d3 拖动行为在选择之间绘制连接线。为绘制连接路径创建一个虚拟路径,如果拖动在选择处结束则绘制一条线。

JS

svg.append("defs").append("marker")
.attr("id", "arrowhead")
.attr("refX", 9)
.attr("refY", 2)
.attr("markerWidth", 6)
.attr("markerHeight", 4)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0,0 V 4 L6,2 Z");

var dummy = svg.append("line")
.attr("class","dummy")
.style("display","none")
.attr("marker-end", "url(#arrowhead)");

var drag = d3.behavior.drag()
.on("dragstart", function(){
var x= d3.event.sourceEvent.x, y= d3.event.sourceEvent.y;
dummy.attr("x1",x)
.attr("y1",y).attr("x2",x)
.attr("y2",y)
.style("display","block");
})
.on("drag", function(d,i) {
var x= d3.event.sourceEvent.x, y= d3.event.sourceEvent.y;
dummy.attr("x2",x)
.attr("y2",y)
})
.on("dragend",function(){
var isSelected = d3.select(d3.event.sourceEvent.target).classed("selected");
if(isSelected && d3.event.sourceEvent.target!=this){
var x1=dummy.attr("x1"), y1=dummy.attr("y1"),
x2=dummy.attr("x2"), y2=dummy.attr("y2");
svg.append("line")
.attr("class","connector")
.attr("x1",x1)
.attr("y1",y1)
.attr("x2",x2)
.attr("y2",y2)
.attr("marker-end", "url(#arrowhead)");
}
dummy.style("display","none");
});

function highlightRange(range) {
var newNode = document.createElement("div");
d3.select(newNode).attr("class","selected").call(drag);
range.surroundContents(newNode);
}

样式

::selection {
background-color:yellow;
}
.dummy{
stroke: black;
fill:none;
stroke-width: 2px;
stroke-dasharray: 5 5;
}
.connector{
stroke: steelblue;
fill:none;
stroke-width: 2px;
}
.selected{
background-color: yellow;
display: inline;
}

已更新 JSFiddle

关于javascript - 在单击的文本元素上绘制箭头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28284646/

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