D3 v4将数据扩展到范围

时间:2017-08-26 10:19:47

标签: d3.js range scale

数据未正确缩放到范围。

我将一个svg附加到div,

var svg = d3.select("#box")
          .append("svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom);

然后是那个svg的小组。

 // create group
    var group = svg.append("g")
      .attr("class", "main_group")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

然后缩放x轴,

var x = d3.scaleLinear()
      .domain(0, d3.max(function(d) {
        return d.x_pos
      })).range([0, width]);

宽度设置为,

  var margin = {
            top: 50,
            right: 50,
            bottom: 50,
            left: 50
          },
          width = 600 - margin.left - margin.right, // width=500
          height = 600 - margin.top - margin.bottom; // height=500

当我将x_pos值更改为大于800时,渲染的rect位于svg之外。在x_pos = 525的那一刻,矩形的左上角是可见的。

  { 
        // "x_pos": "800",
        "x_pos": "525",
        "y_pos": "300",
        "name": "Dd"
      },

我希望数据中的x_pos值始终缩放到[0,width]范围。

为什么数据没有缩放到范围?

github和gh-pages demo



    svg {
      border: 2px solid gray;
    }

<!DOCTYPE html>
<meta charset="utf-8">

<body>
  <div id="box">
  </div>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    data = [{
        "x_pos": "100",
        "y_pos": "400",
        "name": "Aa"
      },
      {
        "x_pos": "200",
        "y_pos": "200",
        "name": "Bb"
      },
      {
        "x_pos": "300",
        "y_pos": "100",
        "name": "Cc"
      },
      {
        // "x_pos": "300",
        "x_pos": "525",
        "y_pos": "300",
        "name": "Dd"
      },
      {
        "x_pos": "0",
        "y_pos": "0",
        "name": "Ee"
      }
    ]

    data.forEach(function(d) {
      d.x_pos = +d.x_pos;
      d.y_pos = +d.y_pos;
    });

    var margin = {
        top: 50,
        right: 50,
        bottom: 50,
        left: 50
      },
      width = 600 - margin.left - margin.right, // width=500
      height = 600 - margin.top - margin.bottom; // height=500

    var x = d3.scaleLinear()
      .domain(0, d3.max(function(d) {
        return d.x_pos
      })).range([0, width]);

    var y = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return d.y_pos
      })]).range([height, 0]);

    var svg = d3.select("#box")
      .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom);

    // create group
    var group = svg.append("g")
      .attr("class", "main_group")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // bind the data
    var boxes = group.selectAll("boxes")
      .data(data)
      .enter();

    // add rects
    boxes.append("rect")
      .attr("class", "boxes")
      .attr("x", function(d) {
        return d.x_pos
      })
      .attr("y", function(d) {
        return d.y_pos
      })
      .attr("rx", "5px")
      .attr("width", 60)
      .attr("height", 20)
      .attr("stroke", "darkgray")
      .attr("fill", "lightblue");

    // add text
    boxes.append("text")
      .attr("class", "legend_text")
      .attr("x", function(d) {
        return d.x_pos
      })
      .attr("y", function(d) {
        return d.y_pos
      })
      .attr("dx", "0.5em")
      .attr("dy", "1.0em")
      .style("font-weight", "bold")
      .text(function(d) {
        return d.name;
      });

    // add text coordinates
    boxes.append("text")
      .attr("class", "legend_text")
      .attr("x", function(d) {
        return d.x_pos
      })
      .attr("y", function(d) {
        return d.y_pos
      })
      .attr("dx", "-2.5em")
      .attr("dy", "-.5em")
      .style("font-weight", "bold")
      .text(function(d) {
        return "(" + d.x_pos + ", " + d.y_pos + ")";
      });
  </script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

这里的问题非常简单:你没有使用任何比例来定位矩形:

.attr("x", function(d) {
    return d.x_pos
})

解决方案:使用您的比例。

.attr("x", function(d) {
    return x(d.x_pos)
    //     ^--- scale here
})

此外,您没有正确设置域名。它应该是:

var x = d3.scaleLinear()
    .domain([0, d3.max(data, function(d) {
        return d.x_pos
    })]).range([0, width]);

以下是包含这些更改的代码:

svg {
      border: 2px solid gray;
    }
<!DOCTYPE html>
<meta charset="utf-8">

<body>
  <div id="box">
  </div>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    data = [{
        "x_pos": "100",
        "y_pos": "400",
        "name": "Aa"
      },
      {
        "x_pos": "200",
        "y_pos": "200",
        "name": "Bb"
      },
      {
        "x_pos": "300",
        "y_pos": "100",
        "name": "Cc"
      },
      {
        // "x_pos": "300",
        "x_pos": "525",
        "y_pos": "300",
        "name": "Dd"
      },
      {
        "x_pos": "0",
        "y_pos": "0",
        "name": "Ee"
      }
    ]

    data.forEach(function(d) {
      d.x_pos = +d.x_pos;
      d.y_pos = +d.y_pos;
    });

    var margin = {
        top: 50,
        right: 50,
        bottom: 50,
        left: 50
      },
      width = 600 - margin.left - margin.right, // width=500
      height = 600 - margin.top - margin.bottom; // height=500

    var x = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return d.x_pos
      })]).range([0, width]);

    var y = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return d.y_pos
      })]).range([height, 0]);

    var svg = d3.select("#box")
      .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom);

    // create group
    var group = svg.append("g")
      .attr("class", "main_group")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // bind the data
    var boxes = group.selectAll("boxes")
      .data(data)
      .enter();

    // add rects
    boxes.append("rect")
      .attr("class", "boxes")
      .attr("x", function(d) {
        return x(d.x_pos)
      })
      .attr("y", function(d) {
        return y(d.y_pos)
      })
      .attr("rx", "5px")
      .attr("width", 60)
      .attr("height", 20)
      .attr("stroke", "darkgray")
      .attr("fill", "lightblue");

    // add text
    boxes.append("text")
      .attr("class", "legend_text")
      .attr("x", function(d) {
        return x(d.x_pos)
      })
      .attr("y", function(d) {
        return y(d.y_pos)
      })
      .attr("dx", "0.5em")
      .attr("dy", "1.0em")
      .style("font-weight", "bold")
      .text(function(d) {
        return d.name;
      });

    // add text coordinates
    boxes.append("text")
      .attr("class", "legend_text")
      .attr("x", function(d) {
        return x(d.x_pos)
      })
      .attr("y", function(d) {
        return y(d.y_pos)
      })
      .attr("dx", "-2.5em")
      .attr("dy", "-.5em")
      .style("font-weight", "bold")
      .text(function(d) {
        return "(" + d.x_pos + ", " + d.y_pos + ")";
      });
  </script>