【问题标题】:d3js. Coordinates after zoom and pan. How to calculate it?d3js。缩放和平移后的坐标。如何计算它?
【发布时间】:2018-07-29 10:57:53
【问题描述】:

我有一个简单的代码,它在 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?或者我在这里做错了什么。 我该如何解决这个问题?

【问题讨论】:

    标签: javascript d3.js svg


    【解决方案1】:

    您已经将一个变换矩阵应用于包含矩形的组。我们通过 d3.event 获得的坐标将已经应用了这些变换,因此变换矩阵将两次应用于组中的新矩形。所以你必须先将逆变换矩阵应用于坐标,然后再用于矩形。

    工作代码sn-p:-

    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>

    【讨论】:

    • 效果更好,但是关于光标的翻译仍然很小。
    猜你喜欢
    • 2016-11-11
    • 2016-07-23
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    相关资源
    最近更新 更多