d3.js学習ノート(3)zoomを用いてスケールと平行移動

2836 ワード

zoomは文字通りスケールの意味ですが、d 3のzoomはスケールできるほか、平行移動もできます.この2つの操作はいつも区別されていないからです.
まず、表示領域全体ですべての要素がスケールおよびパンされるわけではありません.たとえば、座標軸、背景などです.これらはスケールおよびパンする必要はありません.zoom要素を設定する場合は、除外する必要があります.最良の方法はsvgのgラベルを使用してグラフィック要素をグループ化し、スケーリングする必要があるgラベルを1つのgラベルに入れ、他のgラベルを1つのgラベルに入れたり、分けたりすることです.
この例のコードではsvgGraphContainerは、スケーリングするグラフィック要素を配置するコンテナですので、他の要素を追加するときに使用します.
d3.select(svgGraphContainer).append('path')

ここに線を追加し、他の図形であればこの方法でsvgGraphContainerの下に追加します.ただし、座標軸とバックグラウンドはsvgGraphContainerに追加せず、svgルートノードまたは他のノードの下に追加します.
d 3.zoom()に追加
.on('zoom', () => {
          this.svgGraphContainer.attr('transform', d3.event.transform) //       
          this.axises.xContainer.call(this.axises.x.scale(d3.event.transform.rescaleX(this.axises.xScale))) //       zoom  
          this.axises.yContainer.call(this.axises.y.scale(d3.event.transform.rescaleY(this.axises.yScale)))
        })

ここでtransformには、ズームと平行移動の2つの機能が含まれており、中キーローラのズーム、左キードラッグで平行移動します.以前のバージョンでは、zoom応答関数にtranslateとscaleをそれぞれ設定する必要がありましたが、v 4版からは使用されず、直接統合されています.
https://stackoverflow.com/questions/38459765/d3-zoom-and-pan-upgrade-to-version-4
TransformはsvgGraphContainerに設定する必要があります.svgに設定すると、svg全体のアスペクトはzoomによって変化しますが、必ずしも平行移動機能はありません.
その後、スケールの割合を再設定する、d 3.zoom()にはスケール調整機能が付属しており、この機能参照
https://bl.ocks.org/mbostock/db6b4335bf1662b413e7968910104f0f
これにより、スケール中に座標軸のtickと文字がスケールとともに調整されます.
最後にzoomを特定の要素ではなくsvg全体に配置して、グラフィック要素領域全体で機能することを保証します.
import * as d3 from 'd3'
export default {
  data () {
    return {
      width: 0,
      height: 0,
      svgGraphContainer: null,
      splines: { node: null, lineGenerator: null, lines: [] },
      polylines: { node: null, lineGenerator: null, lines: [] },
      symbols: { node: null, lines: [] },
      svg: null,
      axises: {
        node: null,
        x: null,
        xScale: null,
        xContainer: null,
        y: null,
        yScale: null,
        yContainer: null },
      dragHandler: null,
      zoomHandler: null
    }
  },
  mounted () {
    this.addZoomBehavior()
  }
  methods: {
    addZoomBehavior () {
      this.zoomHandler = d3.zoom()
        .scaleExtent([0.1, 10]) // zoom limit
        .translateExtent([[-100, -100], [this.width + 90, this.height + 100]]) // translate limit
        .on('zoom', () => {
          this.svgGraphContainer.attr('transform', d3.event.transform)
          this.axises.xContainer.call(this.axises.x.scale(d3.event.transform.rescaleX(this.axises.xScale)))
          this.axises.yContainer.call(this.axises.y.scale(d3.event.transform.rescaleY(this.axises.yScale)))
        })
      this.svg.call(this.zoomHandler)
    }
  }
}

このサンプルコードはvue単一ファイルコンポーネントから来ているので、ここでthisはvueコンテキストコンポーネント自体を指します.