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>

Script.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

Re 1.: はい、それが最善の方法です。

また、D3 は、そのようなスケールを「フリップ」して幅をそれにフィードすると、ベーコンを保存しないことに注意してください。これは負になります。SVG の高さ属性にそれらを使用すると、それらは違法な SVG コンテンツとしてフラグが立てられ、ブラウザは毛玉を吐き出します(あなたが望むものを表示しません)。

Re 2 .:負の幅/高さを修正したら、クリッピング長方形で s をラップすることで、「領域外のプロット」を防ぐことができます。これは、それらを別のグループに配置することで実行できます。これにより、出力領域に一致するクリッピング四角形が割り当てられます。

#1については、メーリングリストへの質問への返信も参照してください。

http://bl.ocks.org/3671490

すべてのバグが修正され、適切な四角形が表示されます。

スタイルの問題: 最初にドメイン空間で絶対座標を計算するのではなく、xScale/yScale を 1 回呼び出して幅と高さを変換し、スケールを介して両方を変換して幅/高さを計算するため、コードは線形軸でのみ機能します。出力スペース。新しいアプローチが対数空間でも機能することを示すために、代わりに対数/対数スケールを使用した上記の要点のコピーを次に示します。

http://bl.ocks.org/3671592

コードは、すべての計算が明示的に行われ、.attr() 呼び出しの外側に移動される「不変条件」がないという点で「大雑把」です: x1/y1/x2/y2 は、各 .attr() が 2 つ必要であるため、複数回計算されます。この種のことは、通常、データを d3.selection.data() に供給する前に、データを設定する (事前計算/並べ替え/交換/必要なものは何でも) ことによって「解決」されます。

得られた教訓: SVG を使用する場合、スケールに完全に依存しないようにするには、さらに多くの作業を行う必要があります。より高速なコードが必要な場合は、出力が有効な SVG を生成するようにデータを準備する必要があります (ここでは、「処理済み」入力 = [{X:80,Y:80,W:10,H:-60]])。 、特に幅と高さの正の値 (または同様に x2 > x1 および y2 > y1 )

于 2012-09-08T04:02:03.717 に答える