我有一个简单的代码,在Ctrl +点击光标下添加一个新的矩形。默认缩放/平移时一切正常,但在缩放/平移后我们得到错误的坐标。
这是我迄今为止所尝试过的:
let width = 960,
height = 500
let data = {
nodes: [{
name: "node1",
x: 100,
y: 100,
height: 50,
width: 50
}, {
name: "node2",
x: 200,
y: 200,
height: 50,
width: 50
}]
}
let svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
let g = svg.append('g')
.attr('class', 'everything')
let zoom_handler = d3.zoom()
.on("zoom", zoomed)
zoom_handler(svg)
function zoomed() {
g.attr("transform", d3.event.transform)
}
function update(data) {
d3.selectAll('.nodes').remove()
let nodes = g.selectAll("node")
.data(data.nodes)
.enter()
.append('g')
.attr('class', 'nodes')
nodes
.append("rect")
.attr("class", "node")
.attr("width", d => {
return d.width
})
.attr("height", d => {
return d.height
})
.attr("x", d => {
return d.x
})
.attr("y", d => {
return d.y
})
.attr("fill", 'red')
}
update(data)
d3.select('body')
.on('click', () => {
if (d3.event.ctrlKey) {
addNode(d3.event.x, d3.event.y)
}
})
function addNode(x1, y1) {
data.nodes.push({
name: "nodeN",
x: x1,
y: y1,
height: 50,
width: 50,
})
update(data)
}
body {
width: 960px;
height: 500px;
position: relative;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
我知道公式'tx - x \ k',但我可以在哪里找到tx?或者也许我在这里做错了什么。 我该如何解决这个问题?
答案 0 :(得分:2)
您已经将变换矩阵应用于包含矩形的组。我们通过d3.event获得的坐标将已经应用了这些变换,因此变换矩阵将被应用两次以用于组中的新矩形。因此,您必须首先将反向变换矩阵应用于坐标,然后用于矩形。
工作代码段: -
let width = 960,
height = 500
let data = {
nodes: [{
name: "node1",
x: 100,
y: 100,
height: 50,
width: 50
}, {
name: "node2",
x: 200,
y: 200,
height: 50,
width: 50
}]
}
let svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
let g = svg.append('g')
.attr('class', 'everything')
let zoom_handler = d3.zoom()
.on("zoom", zoomed)
zoom_handler(svg)
function zoomed() {
g.attr("transform", d3.event.transform)
}
function update(data) {
d3.selectAll('.nodes').remove()
let nodes = g.selectAll("node")
.data(data.nodes)
.enter()
.append('g')
.attr('class', 'nodes')
nodes
.append("rect")
.attr("class", "node")
.attr("width", d => {
return d.width
})
.attr("height", d => {
return d.height
})
.attr("x", d => {
return d.x
})
.attr("y", d => {
return d.y
})
.attr("fill", 'red')
}
update(data)
d3.select('body')
.on('click', () => {
if (d3.event.ctrlKey) {
var svgEl = svg.node();
var pt = svgEl.createSVGPoint();
pt.x = d3.event.x;
pt.y = d3.event.y;
pt = pt.matrixTransform(g.node().getCTM().inverse());
addNode(pt.x, pt.y)
}
});
function addNode(x1, y1) {
data.nodes.push({
name: "nodeN",
x: x1,
y: y1,
height: 50,
width: 50,
})
update(data)
}
body{
margin: 0px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>