【问题标题】:How to align d3.linearScale()in the center of the page?如何在页面中心对齐 d3.linearScale()?
【发布时间】:2017-12-03 07:52:59
【问题描述】:

我正在尝试创建一个 2D 笛卡尔坐标系,其原点位于 svg 的中心。基本上是这样的: 我目前的方法是平移轴,使它们的原点位于中间。

  // Add the x Axis
  svg.append("g")
      .attr("transform", "translate(" + 0 + "," + height/2 + ")")
      .call(d3.axisBottom(x).ticks(100));

  // Add the y Axis
  svg.append("g")
      .attr("transform", "translate(" + width/2 + "," + 0 + ")")
      .call(d3.axisLeft(y).ticks(100));
      });

但是,我需要手动调整范围以使 y 轴居中。每个屏幕尺寸所需的值都不同,这就是为什么我需要帮助弄清楚如何始终让我的坐标轴在每个屏幕上居中。

  var x = d3.scaleLinear().range([width/2-5*width,width/2+5*width]).domain([-50, 50]); 
  var y = d3.scaleLinear().range([height/2-5*height,height/2+3.244*width]).domain([50,  -50]); //the value 3.244 is the problem, it changes on every screen

我创建了一个Fiddle,以便向您展示我是如何创建坐标轴的。

【问题讨论】:

    标签: javascript html css d3.js svg


    【解决方案1】:

    我没有关注所有这些复杂且不必要的数学(例如,在您原来的小提琴中,您为什么使用幻数?没有它也可以工作:https://jsfiddle.net/smftm5sv/)。

    将笛卡尔平面的原点设置在 SVG 的中心非常简单。首先,您可以按照自己的方式定义范围......最简单的选项就是:

    var x = d3.scaleLinear().range([0, width]);
    var y = d3.scaleLinear().range([0, height]);
    

    其次,要在笛卡尔平面中对齐两个轴,只需将比例的零值传递给每个平移(y(0)x(0))。即使在 xy 轴的不同域中也适用,前提是起始值和结束值具有相同的绝对值:

    svg.append("g")
        .attr("transform", "translate(0"," + y(0) + ")")
        .call(d3.axisBottom(x));
    
    svg.append("g")
        .attr("transform", "translate(" + x(0) + ",0)")
        .call(d3.axisLeft(y));
    

    这是进行这些更改的代码(另外,我正在摆脱 jQuery,你不需要带有 D3 的 jQuery):

    var width = window.innerWidth;
    var height = window.innerHeight;
    var padding = 10;
    
    
      var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .call(d3.zoom().on("zoom", function() {
          svg.attr("transform", d3.event.transform);
        }))
        .append("g");
    
      var viewport = svg.append('g');
    
      var x = d3.scaleLinear().range([0 + padding, width - padding]).domain([-50, 50]); 
      var y = d3.scaleLinear().range([0 + padding, height - padding]).domain([50, -50]);
    
      // Add the x Axis
      svg.append("g")
        .attr("transform", "translate(" + 0 + "," + y(0) + ")")
        .call(d3.axisBottom(x));
    
      // Add the y Axis
      svg.append("g")
        .attr("transform", "translate(" + x(0) + "," + 0 + ")")
        .call(d3.axisLeft(y));
    <script src="https://d3js.org/d3.v4.min.js"></script>

    由于 Stack sn-p 窗口非常小(并且您正在动态获取窗口的尺寸),y 轴会很短,而 x 轴会更长。

    【讨论】:

      【解决方案2】:

      好吧,我自己想通了。关键是使用宽度与高度的关系。 更新后的小提琴是here

        var x = d3.scaleLinear().range([width/2-5000*width/height,width/2+5000*width/height]).domain([-50, 50]);
        var y = d3.scaleLinear().range([height/2-5000*width/height,height/2+5000*width/height]).domain([50,  -50]);
      

      【讨论】:

        猜你喜欢
        • 2012-02-15
        • 1970-01-01
        • 2012-12-31
        • 2016-11-25
        • 2015-03-03
        • 2016-06-20
        • 2020-01-27
        • 2019-10-14
        • 1970-01-01
        相关资源
        最近更新 更多