d3v4 - 缩放(相当于d3.zoom.x)

Pet*_*uju 8 javascript zooming d3.js d3v4

我正在将我的d3代码从v3迁移到v4,并且在找到d3.zoom.x,d3.zoom.y属性的等效代码时遇到问题.

这是代码的一小部分,包括最重要的元素:

            this.init = function(obj, def) {

            /* X-axis */
            x = d3.scaleTime()
                .range([0, width]);


            xAxis = d3.axisBottom(x)
                .ticks(ticks);

            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")");

            /* Y-axis */
            for (var i = 0; i < 1; i++) {
                // Returns the y and yAxis as arrays
                createYAxis(i);
            }

            initZoom();

        };
            // Zoom trigger
            var drawUpdXY = function(){
                setPause(true);
                drawUpd();
                zoomY.y(y[0]);
                zoomX.x(x);


            zoom = d3.zoom()
                .on("zoom", drawUpdXY);

            zoomX = d3.zoom()
                .on("zoom", drawUpdX);

            zoomY = d3.zoom()
                .on("zoom", drawUpdY);
            };     
Run Code Online (Sandbox Code Playgroud)

我试过用它来代替"zoom.x(x); zoom.y(y [0])"

      xAxis.scale(d3.event.transform.rescaleX(x));
      yAxis[0].scale(d3.event.transform.rescaleY(y[0]));
Run Code Online (Sandbox Code Playgroud)

但是,这些只会重新调整轴的大小,使数据不受影响.

Aus*_*n A 2

我无法谈论 d3 v3 如何处理缩放,因为我最近才开始使用 D3,但下面的代码应该可以为您指明正确的方向。我会尽力描述正在发生的事情。我欢迎更正、改进和更好的解释。

首先,MCVE

<html>

<head>
  <meta charset="UTF-8">
  <title>Energy Visualizer</title>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://d3js.org/d3-color.v1.min.js"></script>
  <script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
  <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
  <style>
    body {
      background-color: #4e5965;
    }
  </style>
  </svg>
</head>

<body>
  <div class="chart" />
  <script>
    var svg = d3.select(".chart").append("svg")
      .attr("width", 200)
      .attr("height", 200);

    var data = [{
      "x": 2,
      "y": 8,
      "color": "green"
    }, {
      "x": 4,
      "y": 6,
      "color": "red"
    }];

    var width = svg.attr("width");
    var height = svg.attr("height");

    x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]);
    y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]);

    var circles = svg.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("cx", function(d) {
        return x_scale(d.x);
      })
      .attr("cy", function(d) {
        return y_scale(d.y);
      })
      .attr("r", 5)
      .attr("fill", function(d) {
        return d.color
      });

    var xAxis = d3.axisBottom(x_scale);
    var yAxis = d3.axisRight(y_scale);

    var x_axis = svg.append("g").call(xAxis);
    var y_axis = svg.append("g").call(yAxis);
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

这只是一个带有红色和绿色圆圈的简单散点图。您可以看到我如何分解 x 轴和 y 轴的组成部分。这会发挥作用d3.zoom()

接下来,让我们添加一个缩放组件。

<html>

<head>
  <meta charset="UTF-8">
  <title>Energy Visualizer</title>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://d3js.org/d3-color.v1.min.js"></script>
  <script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
  <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
  <style>
    body {
      background-color: #4e5965;
    }
  </style>
  </svg>
</head>

<body>
  <div class="chart" />
  <script>
    var svg = d3.select(".chart").append("svg")
      .attr("width", 200)
      .attr("height", 200);

    var zoom = d3.zoom()
      .on("zoom", zoomed);

    svg.call(zoom);

    var data = [{
      "x": 2,
      "y": 8,
      "color": "green"
    }, {
      "x": 4,
      "y": 6,
      "color": "red"
    }];

    var width = svg.attr("width");
    var height = svg.attr("height");

    x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]);
    y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]);

    var circles = svg.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("cx", function(d) {
        return x_scale(d.x);
      })
      .attr("cy", function(d) {
        return y_scale(d.y);
      })
      .attr("r", 5)
      .attr("fill", function(d) {
        return d.color
      });

    var xAxis = d3.axisBottom(x_scale);
    var yAxis = d3.axisRight(y_scale);

    var x_axis = svg.append("g").call(xAxis);
    var y_axis = svg.append("g").call(yAxis);


    function zoomed() {
      var new_x_scale = d3.event.transform.rescaleX(x_scale);
      var new_y_scale = d3.event.transform.rescaleY(y_scale);

      x_axis.transition()
        .duration(0)
        .call(xAxis.scale(new_x_scale));

      y_axis.transition()
        .duration(0)
        .call(yAxis.scale(new_y_scale));

      circles
        .attr("cx", function(d) {
          return new_x_scale(d.x)
        })
        .attr("cy", function(d) {
          return new_y_scale(d.y)
        });

    }
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

在这里,您可以看到图表允许放大、缩小以及跨两个轴拖动。我相信您只需要单轴缩放,因此在这种情况下,只需重新缩放 x 轴和每个圆位置的 x 分量。

最后一个片段正在做我认为你想要的事情。

<html>

<head>
  <meta charset="UTF-8">
  <title>Energy Visualizer</title>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://d3js.org/d3-color.v1.min.js"></script>
  <script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
  <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
  <style>
    body {
      background-color: #4e5965;
    }
  </style>
  </svg>
</head>

<body>
  <div class="chart" />
  <script>
    var svg = d3.select(".chart").append("svg")
      .attr("width", 200)
      .attr("height", 200);

    var zoom = d3.zoom()
      .on("zoom", zoomed);

    svg.call(zoom);

    var data = [{
      "x": 2,
      "y": 8,
      "color": "green"
    }, {
      "x": 4,
      "y": 6,
      "color": "red"
    }];

    var width = svg.attr("width");
    var height = svg.attr("height");

    x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]);
    y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]);

    var circles = svg.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("cx", function(d) {
        return x_scale(d.x);
      })
      .attr("cy", function(d) {
        return y_scale(d.y);
      })
      .attr("r", 5)
      .attr("fill", function(d) {
        return d.color
      });

    var xAxis = d3.axisBottom(x_scale);
    var yAxis = d3.axisRight(y_scale);

    var x_axis = svg.append("g").call(xAxis);
    var y_axis = svg.append("g").call(yAxis);


    function zoomed() {
      var new_x_scale = d3.event.transform.rescaleX(x_scale);

      x_axis.transition()
        .duration(0)
        .call(xAxis.scale(new_x_scale));

      circles
        .attr("cx", function(d) {
          return new_x_scale(d.x)
        });

    }
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)