Javascript D3.js与坐标系

Javascript D3.js与坐标系,javascript,d3.js,Javascript,D3.js,正在尝试D3,但有一些问题。不确定什么是忍受坐标系的最好方法。 请在下面找到来源 编辑:小提琴 我通过yScale->.range([height-padding,padding])模拟了反转坐标而不是.range([padding-height-padding])。这是最好的办法吗。如果svg中的所有对象都需要正确定向,那么最好应用于最外层的元素吗 var svg=d3.选择(“图表”).追加(“svg”) .attr(“宽度”,宽度+边距。右+边距。左) .attr(“高度”,高度+边距。顶

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

编辑:小提琴

  • 我通过
    yScale->.range([height-padding,padding])模拟了反转坐标
    而不是
    .range([padding-height-padding])。这是最好的办法吗。如果svg中的所有对象都需要正确定向,那么最好应用于最外层的元素吗

    var svg=d3.选择(“图表”).追加(“svg”)
    .attr(“宽度”,宽度+边距。右+边距。左)
    .attr(“高度”,高度+边距。顶部+边距。底部)

    .append(“g”)Re 1.:是的,那是最好的方法

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

    Re 2.:修正负宽度/负高度后,可以通过将负宽度/负高度包裹在剪切矩形中来防止“在区域外打印”;这可以通过将它们放在一个单独的组中来实现,然后为该组分配一个与输出区域匹配的剪裁矩形

    关于#1,请参见回复邮件列表中您的问题:

    已修复所有错误并显示正确的rect

    样式问题:当您通过单个调用xScale/yScale转换宽度和高度时,您的代码只能使用线性轴,而不是首先计算域空间中的绝对坐标,然后通过scale转换这两个坐标以计算输出空间中的宽度/高度。为了说明新方法在日志空间中也有效,下面是使用日志/日志比例的上述要点的副本:

    代码是“粗略”的,因为所有的计算都是显式完成的,并且没有将任何“不变量”移到.attr()调用之外:x1/y1/x2/y2要计算多次,因为每个.attr()都需要两个。这类问题通常通过在将数据馈送到d3.selection.data()之前设置数据(预计算/排序/交换/任何需要的内容)来“解决”

    经验教训:在使用SVG时,您需要做更多的工作才能完全不受缩放影响;如果您想要更快的代码,则需要准备数据,以便输出将生成有效的SVG(此处:“已处理”输入=[{X:80,Y:80,W:10,H:-60]]),特别是宽度和高度的正值(或者类似地,宽度为x2>x1,高度为y2>y1)

    <!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>
    
    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);