如何在不使用d3.behavior.zoom()的情况下手动放大d3.js中的某个点?

时间:2019-05-12 09:17:04

标签: d3.js graph zoom

由于我已经实现了平移和轴拖动,因此我也想手动实现缩放功能。到目前为止,我的代码是:

const zoomXY = () => {
    const intensity = 0.035

    // how to implement the correct translation(s) before/after scaling below?
    let tX = tempXScale.invert(mousePoint[0] - plotWidth / 2),
        tY = tempYScale.invert(mousePoint[1] - plotHeight / 2)

    let wheelSign = Math.sign(wheelDelta),
        eX = xDomain[1] - xDomain[0],
        eY = yDomain[1] - yDomain[0],
        tempXMin = xDomain[0] + wheelSign * (eX * intensity),
        tempXMax = xDomain[1] - wheelSign * (eX * intensity),
        tempYMin = yDomain[0] + wheelSign * (eY * intensity),
        tempYMax = yDomain[1] - wheelSign * (eY * intensity)

    tempXDomain = [(tempXMin > 0.001 ? tempXMin : 0.001), tempXMax]
    tempYDomain = [tempYMin, tempYMax]

    tempXScale.domain(tempXDomain)
    tempYScale.domain(tempYDomain)

    redrawX()
    redrawY()
    redrawLines()
}

const mouseWheelPlot = (e) => {
    d3.select('.focus').style('display', 'none')

    mousePoint = d3.clientPoint(e.target, e)
    wheelDelta = e.deltaY
    zoomXY()

    onSetXDomain(tempXDomain)
    onSetYDomain(tempYDomain)
}

就目前而言,这是非常“ hack”的缩放功能,因为它只能任意扩大/缩小x和y比例,然后重新绘制图元素。我希望能够在d3中“放大一点”,类似于here中讨论的此功能。

1 个答案:

答案 0 :(得分:0)

我想出了-这是一个实施方案,以防有人需要。

const zoomXY = () => {
  const mX = mousePoint[0],
        mY = mousePoint[1],
        sX = tempXScale.invert(mX),
        sY = tempYScale.invert(mY)

  /*
   ** Scale
   */
  const wheelSign = Math.sign(wheelDelta),
        percentage = 0.025

  let eX = xDomain[1] - xDomain[0],
      eY = yDomain[1] - yDomain[0]

  tempXDomain = [
    xDomain[0] + wheelSign * (eX * percentage),
    xDomain[1] - wheelSign * (eX * percentage)
  ]

  tempYDomain = [
    yDomain[0] + wheelSign * (eY * percentage),
    yDomain[1] - wheelSign * (eY * percentage)
  ]

  tempXScale.domain(tempXDomain)
  tempYScale.domain(tempYDomain)

  /*
   ** Translate
   */
  let dX = sX - tempXScale.invert(mX),
      dY = sY - tempYScale.invert(mY)

  tempXDomain = [
    tempXDomain[0] + dX > 0.001 ? tempXDomain[0] + dX : 0.001,
    tempXDomain[1] + dX
  ]

  tempYDomain = [
    tempYDomain[0] + dY,
    tempYDomain[1] + dY
  ]

  tempXScale.domain(tempXDomain)
  tempYScale.domain(tempYDomain)

  redrawX()
  redrawY()
  redrawLines()
}

const mouseWheelPlot = (e) => {
  d3.select('.focus').style('display', 'none')

  mousePoint = d3.clientPoint(e.target, e)
  wheelDelta = e.deltaY
  zoomXY()

  onSetXDomain(tempXDomain)
  onSetYDomain(tempYDomain)
}