Saya mencoba melakukan zooming melalui kuas seperti di blok ini https://bl.ocks.org/FrissAnalytics/539a46e17640613eeb94598aad0c92d

Perbedaannya adalah saya perlu mendefinisikan nilai sumbu secara manual karena pembesaran, karena saya harus menjaga jarak antara kutu tetap sama (seperti scaleOrdinal, tetapi saya melakukannya dengan scaleLinear). Saya terjebak dengan menyikat - ini berfungsi dengan baik ketika memperbesar melalui kuas pertama kali, tetapi jika saya ingin masuk lebih dalam, zoom tertinggal - skala menghitung dengan baik, tetapi terjemahan berjalan di mana saja, tetapi tidak di kanan.

Ada biola saya (agak berantakan, saya menelepon getRange beberapa kali untuk menentukan batas) https://jsfiddle.net/Celeritas/y2u06kpm/2/

Jadi saya punya kode ini sekarang untuk acara brush_end

function brush_endEvent() {
  const s = d3.event.selection;

  if (!s && lastSelection !== null) {
    //this doing the same thing
    let scaleX = lastTransform.rescaleX(x);
    let scaleY = lastTransform.rescaleY(y);

    gxAxis.call(xAxis.scale(scaleX));
    gyAxis.call(yAxis.scale(scaleY));

    //here I getting the current domain for zoomed area, which will set with the equal distance between ticks
    getRange({
      x1: scaleX.domain()[0],
      x2: scaleX.domain()[scaleX.domain().length - 1],
      y1: scaleY.domain()[0],
      y2: scaleY.domain()[scaleY.domain().length - 1],
    })

    let kWidth = Math.ceil(tickTextWidth / (width / t.length)) + 1
    let kHeight = Math.ceil(tickTextHeight / (height / b.length))

    //im redefining domains manually
    scaleX.domain(t)
    scaleY.domain(b)

    xAxis.tickValues(t.filter((e, i) =>  i % kWidth === 0)).tickFormat(d3.format('d'))
    yAxis.tickValues(b.filter((e, i) =>  i % kHeight === 0)).tickFormat(d3.format('d'))
    xAxis2.tickValues(t.filter((e, i) =>  i % kWidth === 0)).tickFormat(d3.format('d'))
    yAxis2.tickValues(b.filter((e, i) =>  i % kHeight === 0)).tickFormat(d3.format('d'))

    let totalX = Math.abs(lastSelection.x2 - lastSelection.x1);
    const originalPoint = [scaleX.invert(lastSelection.x1), scaleY.invert(lastSelection.y1)];

    const tt = d3.zoomIdentity.scale(((width * lastTransform.k) / totalX));
    // BUT HERE im not doing rescale, cause im already redefine domain earlier
    //scaleX = tt.rescaleX(x);
    //scaleY = tt.rescaleY(y);

    canvasChart
      .transition()
      .duration(200)
      .ease(d3.easeLinear)
      .call(zoom_function.transform,
        d3.zoomIdentity
          .translate(scaleX(originalPoint[0]) * -1, scaleY(originalPoint[1]) * -1)
          .scale(tt.k));
    lastSelection = null;

  } else {
    brushSvg.call(brush.move, null);
  }
}

Jadi saya putus asa, saya tidak mengerti, bagaimana mengatur zoom ke posisi yang tepat setelah menyikat. Terima kasih atas bantuannya!

0
Sol 27 Maret 2020, 16:42

1 menjawab

Jawaban Terbaik
d3.zoomIdentity
          .translate(x(originalPoint[0]) * -1, y(originalPoint[1]) * -1)
          .scale(tt.k)

Nah, kesalahannya ada di x-y untuk zoom. Itu harus asli, domain yang tidak diubah skalanya

0
Sol 30 Maret 2020, 09:14