如何在页面中心对齐d3.linearScale()?

时间:2017-12-02 17:40:49

标签: javascript html css d3.js svg

我正在尝试创建一个2D笛卡尔坐标系,其原点位于svg的中心。基本上是这样的: How I'd like to have it... 我目前的方法是转换轴,使它们的原点位于中间。

  // 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,以便向您展示我是如何创建坐标轴的。

2 个答案:

答案 0 :(得分: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>
&#13;
&#13;
&#13;

由于Stack代码段窗口非常小(并且您正在动态获取窗口的尺寸),y轴将非常短,而x轴将更长。

答案 1 :(得分:0)

好的我自己弄清楚了。关键是使用宽度与高度的关系。 更新的小提琴是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]);