【问题标题】:Creating a zoom function in D3在 D3 中创建缩放功能
【发布时间】:2019-05-27 02:57:46
【问题描述】:

我有一个功能,当按下一个按钮(几个按钮代表几种动物类型)时,该动物类型 SVG 会使用其相应的数据进行更新。我正在尝试复制 this zoom 函数,但在用我的代码实现它时遇到问题。有几个像这样在全球范围内使用的 SVG(每种动物类型一个):

let x = d3.scaleLinear()
  .domain([0, 1000])
  .range([ 0, width ]);

var xAxis = d3.axisBottom(x);

svgReptile.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)

const yAxis = d3.scaleLinear()
  .domain([0, 220])
  .range([ height, 0])

svgReptile.append("g")
  .call(d3.axisLeft(yAxis))

当按下其中一个动物按钮时,将调用以下函数。

 function update(animal, whatSVG, xAxis, yAxis, color) {   

      const points = whatSVG
        .selectAll("circle")
        .data(data);

      points.enter()
        .append("circle")
        .attr("cx", function(d) {
          return xAxis(d.state);
        })
        .attr("cy", function(d) {
          return yAxis(d.percentage);
        })
        .merge(points)
        .attr("r", 3)
        .attr("cx", function(d) {
          return xAxis(d.decade)
        })
        .attr("cy", function(d) {
          return yAxis(d.count)
        })
        .style("fill", function (d) { return colour(d.animal) } );

      points.exit()
        .attr('r', 0)
        .remove();

    }

问题:

我如何实现一种缩放功能,在像上面链接的那样缩放(或任何类似的东西)时扩展 x 轴?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    我认为您正在寻找问题最后一行的“画笔缩放”。

    以下源代码来自d3 graph gallery中的示例

    十字准线允许您选择要扩展的区域。如果您点击链接,则其上方有一个标题为“带轴缩放”的图形,但它不会按照您描述的方式放大,它只是移动轴,但不会用它放大图形内容。也许两者都有用!

    希望对你有帮助

    // set the dimensions and margins of the graph
    var margin = {top: 10, right: 20, bottom: 20, left: 20},
        width = 500 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom;
    
    // append the svg object to the body of the page
    var Svg = d3.select("#brushZoom")
      .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform",
              "translate(" + margin.left + "," + margin.top + ")");
    
    //Read the data
    d3.csv("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/iris.csv", function(data) {
    
      // Add X axis
      var x = d3.scaleLinear()
        .domain([4, 8])
        .range([ 0, width ]);
      var xAxis = Svg.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x));
    
      // Add Y axis
      var y = d3.scaleLinear()
        .domain([0, 9])
        .range([ height, 0]);
      Svg.append("g")
        .call(d3.axisLeft(y));
    
      // Add a clipPath: everything out of this area won't be drawn.
      var clip = Svg.append("defs").append("svg:clipPath")
          .attr("id", "clip")
          .append("svg:rect")
          .attr("width", width )
          .attr("height", height )
          .attr("x", 0)
          .attr("y", 0);
    
      // Color scale: give me a specie name, I return a color
      var color = d3.scaleOrdinal()
        .domain(["setosa", "versicolor", "virginica" ])
        .range([ "#440154ff", "#21908dff", "#fde725ff"])
    
      // Add brushing
      var brush = d3.brushX()                 // Add the brush feature using the d3.brush function
          .extent( [ [0,0], [width,height] ] ) // initialise the brush area: start at 0,0 and finishes at width,height: it means I select the whole graph area
          .on("end", updateChart) // Each time the brush selection changes, trigger the 'updateChart' function
    
      // Create the scatter variable: where both the circles and the brush take place
      var scatter = Svg.append('g')
        .attr("clip-path", "url(#clip)")
    
      // Add circles
      scatter
        .selectAll("circle")
        .data(data)
        .enter()
        .append("circle")
          .attr("cx", function (d) { return x(d.Sepal_Length); } )
          .attr("cy", function (d) { return y(d.Petal_Length); } )
          .attr("r", 8)
          .style("fill", function (d) { return color(d.Species) } )
          .style("opacity", 0.5)
    
      // Add the brushing
      scatter
        .append("g")
          .attr("class", "brush")
          .call(brush);
    
      // A function that set idleTimeOut to null
      var idleTimeout
      function idled() { idleTimeout = null; }
    
      // A function that update the chart for given boundaries
      function updateChart() {
    
        extent = d3.event.selection
    
        // If no selection, back to initial coordinate. Otherwise, update X axis domain
        if(!extent){
          if (!idleTimeout) return idleTimeout = setTimeout(idled, 350); // This allows to wait a little bit
          x.domain([ 4,8])
        }else{
          x.domain([ x.invert(extent[0]), x.invert(extent[1]) ])
          scatter.select(".brush").call(brush.move, null) // This remove the grey brush area as soon as the selection has been done
        }
    
        // Update axis and circle position
        xAxis.transition().duration(1000).call(d3.axisBottom(x))
        scatter
          .selectAll("circle")
          .transition().duration(1000)
          .attr("cx", function (d) { return x(d.Sepal_Length); } )
          .attr("cy", function (d) { return y(d.Petal_Length); } )
    
        }
    
    
    
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
    
    
    
    <div id="brushZoom"></div>

    【讨论】:

    • 也可能感兴趣:d3 zooming api
    • 是的,我已阅读此内容,谢谢。虽然它很有帮助,但我一直在努力使用全局 svg 和单击按钮时更新 svg 的功能来实现这一点
    • @JimmyNeedles 那么真正的问题是什么?换源? (您的问题中没有包含)
    • 基本上在我上面制作的功能中制作缩放功能(如您链接的那个)。我已经尝试实现您链接的确切一个,在必要时更改变量名,但我遇到的问题源于全局拥有多个 svg
    • @JimmyNeedles 您是否使用 d3 成功创建了缩放图,并且仅使用一个源(不尝试多个源)?
    猜你喜欢
    • 1970-01-01
    • 2017-06-14
    • 2021-01-26
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2021-10-19
    • 2021-04-07
    相关资源
    最近更新 更多