簡體   English   中英

使用 d3 調整窗口大小的 SVG 翻譯組定位

[英]SVG Translate Group positioning on window resize with d3

使用 d3 enter, update 模式時,我看到一些奇怪的轉換行為。 我創建了一組 (svg:g) 文本 (svg:text) 項目。 當我最初使用.enter.append('g').attr('transform',function(d){...translate...}這些項目相對於 SVG 的頂部。但是,當我在窗口調整大小后更新組,這些組是相對於它們最外面的容器。

我的數據是一組嵌套的對象 (d3.nest)

var myData=[{
    key:f,
    values:[{
      group:f,
      text:'foo'
    }]
  },
  {
    key:b,
    values:[{
      group:'b',
      text:'bar'
    },{
      group:'b',
      text:'baz'
    }]
  }
.....
]

我的輸入/更新模式是:

// EDIT Some JS to add shapes first
var shapeCont = d3.select('#shapesAtTheTop');
var shapes = shapeCont.selectAll('rect')
  .data([50,50]);
shapes.exit().remove();
shapes.enter().append('rect')
  .attr('width',function(d){return window.innerWidth*(d/100)})
  .attr('x', function(d,i){return i*window.innerWidth*(d/100)})
  .attr('y',0)
  .attr('height',95);
// END EDIT
// Now add the text
var textgroupLeft = window.width/50, textGrouptop = 100;
function translateGroup(datum, i){
  var x = textGroupLeft * i;
  var y = textGroupTop;
  return 'translate('+x+' '+y+')';
}
var textContainer = d3.select('g.textContainer');
var txtg = textContainer.selectAll('g').data(myData,function(d){return d.key;});
// UPDATE
txtg.attr('transform',translateGroup);
// REMOVE
txtg.exit().remove();
// NEW
txtg.enter().append('g')
  .classed('textGroup',true')
  .attr('transform',transelateGroup)

var txt = d3.selectAll('g.textGroup').selectAll('text')
  .data(function(d){retrun d.values;},
    function(dataum){return JSON.stringify(dataum);})
// REMOVE
.....
// UPDATE
.....
// NEW
.....

我的 HTML/SVG 是:

<svg>
  <g id="shapesAtTop">
  ..... add polygons with positions in the first 100px high ....
  </g>
  <g id="textBelow" class="textContainer">
  </g>
</svg>

是切換坐標系嗎? 如果是為什么?

很難看出你哪里出錯了。 您可以通過在 HTML 中或使用 D3 以編程方式在 SVG 中的 #textBelow 組上顯式定義翻譯來解決此問題。 一旦該組具有正確的垂直位置,就可以更輕松地平移任何嵌套對象。

您確定要應用的翻譯的代碼很難遵循。 我建議使用 d3 BandScale來處理從您要轉換的對象索引到像素值的映射。

下面的代碼段使用 D3 v4 演示了這兩種方法。 如果您需要使用以前版本的 D3,則比例尺的名稱不同,您必須更加小心 selection.enter(),因為您沒有獲得 selection.merge() 方法。

 var data = [{key:'a'}, {key:'b'}] var width = 500 //px update(data,width) setTimeout(function (){update(data,200)}, 2000) function update(data, width) { //create a band scale to assist with layout var scale = d3 .scaleBand() .domain(d3.range(data.length)) .range([0, width]) // padding ratio of total width .padding(0.1); // append/modify shapes var shapeCont = d3.select("#shapesAtTop"); var shapes = shapeCont.selectAll("rect").data(data); // remove any unused nodes shapes.exit().remove(); // enter shapes.enter() // add new rectangles .append("rect") // merge selection with any existing nodes .merge(shapes) // set all rect attributes .attr("x", function(d, i) { return scale(i); }) .attr("y", 0) .attr("height", 95) .attr("width", scale.bandwidth()); //append/modify text group elements var textContainer = d3.select('#textBelow'); var txtg = textContainer.selectAll('g') .data(data, function(d) { return d? d.key : this.id }); // remove any unused nodes txtg.exit().remove() // enter txtg.enter() .append('g') .classed('textGroup', true) // add some text to new elements .call( function (g) { g.append('text').text('I am text')}) // merge exisiting and new .merge(txtg) .attr('transform', function(d, i) { return 'translate(' + scale(i) + ')' }) }
 svg { width: 100%; height: 500px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script> <svg> <g id="shapesAtTop"> </g> <g id="textBelow" class="textContainer" transform="translate(0,120)"> </g> </svg>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM