javascript - 在 D3 中创建缩放功能

标签 javascript d3.js

我有一个功能,当按下一个按钮时(几个按钮代表几种动物类型),该动物类型 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 轴的缩放功能?

最佳答案

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

以下源代码来自 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>

关于javascript - 在 D3 中创建缩放功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56315855/

相关文章:

javascript - toDateString() 无法将 unix 时间戳转换为人类可读的格式?

javascript - JSON 将级别转换为数组 (Javascript)

javascript - 在 selenium 中选择 SVG 标签内的 g

javascript - D3 map 缩放后如何重新缩放

javascript - 如何使用外部 html 获取 div 的边距?

javascript - matchMedia removeListener 不起作用?

javascript - Node.js Sequelize getter/setter RangeError

javascript - 如何在页面之间移动时显示加载

javascript - D3js 折线图 Y 轴上的不同刻度大小

javascript - 如何将 d3.js v5 模块导入 polymer 3 元素?