2

尝试 D3,但有一些问题。不确定忍受坐标系的最佳方法是什么。请在下面找到来源。

编辑:小提琴在这里

  1. yScale -> .range([ height - padding, padding]);我用代替模拟了倒置坐标.range([ padding - height - padding]);。这是最好的方法吗。如果 svg 中的所有对象都需要正确定向,是否最好应用于最外面的元素?

    var svg = d3.select("#chart").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
    .append("g") <---

  2. 较大的矩形({"X":100, "Y": 100, "W":40, "H": 40})在轴之外。所以,我做错了什么。

高度赞赏使该图表包含在轴内并具有适当的缩放和方向的任何帮助。

索引.html

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
    <script type="text/javascript" src="d3.v2.min.js"></script>
    <link type="text/css" rel="stylesheet" href="style.css"/>
  </head>
  <body>
    <div id="chart"></div>
    <script type="text/javascript" src="script.js"></script>
  </body>
</html>

脚本.js

var margin = {top: 10, right: 20, bottom: 20, left: 10},
    width = 960 - margin.right - margin.left, 
    height = 480 - margin.top - margin.bottom
    padding = 40; 


var data = [
    {"X":10, "Y": 10, "W":10, "H": 10}, 
    {"X":100, "Y": 100, "W":40, "H": 40}
]

var xScale = d3.scale.linear()
         .domain([0, d3.max(data, function(d) { return d.X; })])
     .range([padding, width - padding]),
    yScale = d3.scale.linear()
         .domain([0, d3.max(data, function(d) { return d.Y; })])
     .range([  height -  padding, padding]);

var xAxis = d3.svg.axis().scale(xScale).orient("bottom"),
    yAxis = d3.svg.axis().scale(yScale).orient("left");


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

svg.selectAll("rect")
        .data(data)
      .enter().append("rect")
        .attr("x", function(d) { return xScale(d.X); }) 
        .attr("y", function (d) { return  yScale(d.Y); })
        .attr("width", function (d) { return  (d.W); })
        .attr("height", function (d) { return  (d.H); })

//Create X axis
svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(0," + (height - padding) + ")")
    .call(xAxis);

//Create Y axis
svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + padding + ",0)")
    .call(yAxis);
4

1 回答 1

3

回复 1.:是的,这是最好的方法。

另请注意,当您“翻转”这样的比例然后将宽度输入其中时,D3 不会保存您的培根,这将是负面的:当使用 SVG 高度属性时,那些将被标记为非法 SVG 内容和浏览器会吐一个毛球(不显示你想要的)。

Re 2.:一旦你纠正了你的负宽度/高度,那么你可以通过将你的 s 包裹在一个剪切矩形中来防止“在区域之外绘图”;这可以通过将它们放在一个单独的组中来完成,然后分配一个与您的输出区域匹配的剪切矩形。

对于#1,另请参阅回复您对邮件列表的问题:

http://bl.ocks.org/3671490

已修复所有错误并显示正确的矩形。

样式问题:您的代码只能使用线性轴,因为您通过一次调用 xScale/yScale 转换宽度和高度,而不是先计算域空间中的绝对坐标,然后通过比例转换两者以计算宽度/高度输出空间。为了证明新方法也适用于对数空间,这里是上述要点的副本,使用对数/对数比例:

http://bl.ocks.org/3671592

代码是“粗略”的,因为所有计算都是明确完成的,并且没有“不变量”移动到 .attr() 调用之外:x1/y1/x2/y2 被计算多次,因为每个 .attr() 需要其中两个。这类事情通常是通过在将数据提供给 d3.selection.data() 之前设置数据(预先计算/排序/交换/任何需要的)来“解决”的。

经验教训:在使用 SVG 时,您需要做更多的工作才能完全与规模无关;如果您想要更快的代码,则需要准备数据,以便输出生成有效的 SVG(此处:'processed' input = [{X:80,Y:80,W:10,H:-60]]) ,特别是宽度和高度的正值(或类似地 x2 > x1 和 y2 > y1 )

于 2012-09-08T04:02:03.717 回答