2016-04-14 20 views
1

2 değer içeren basit bir veri kümesinden çok basit bir yığılmış yatay çubuk grafik oluşturmaya çalışıyorum.D3 - Shrink Lineer Scale Range

  1. Veri kümeleri değerlerini, sırasıyla, çubukların solunda ve sağında görüntülemek istiyorum. <svg>, 500px genişliğindedir ve grafikten 100 ila 400 görüntülenmesini istiyorum, böylece çubuklardan önce ve sonra <text>'u kullanabilirim. Bunun için aralığını [0, 500] ila [100, 400] arasında küçültmeye çalışıyorum ama sonuç beklendiği gibi değil.

  2. Ben de burada [66.852, 7550]

gibi basit bir veri kümesi kullanın böylece layout.stack() kullanmadan grafik çizmek isteyen bir Fiddle

//Width and height 
var w = 500; 
var h = 60; 

//Original data 
//var dataset = [66852, 7550] 
//changed to below to support layout.stack() 
var dataset = [ [{y:66852}], [{y:7550}] ]; 

//Set up stack method 
var stack = d3.layout.stack(); 

//Data, stacked 
stack(dataset); 

//Set up scales 
var xScale = d3.scale.linear() 
    .domain([0, d3.max(dataset, function(d) { 
      return d3.max(d, function(d) { 
       return d.y0 + d.y; 
      }); 
     }) 
    ]) 
    .range([100, 400]); 

var yScale = d3.scale.ordinal() 
    .domain(d3.range(dataset[0].length)) 
    .rangeRoundBands([0, h], 0.05); 

//Easy colors accessible via a 10-step ordinal scale 
var colors = d3.scale.category10(); 

//Create SVG element 
var svg = d3.select(".chart") 
    .attr("width", w) 
    .attr("height", h); 

// Add a group for each row of data 
var groups = svg.selectAll("g") 
    .data(dataset) 
    .enter() 
    .append("g") 
    .style("fill", function(d, i) { 
     return colors(i); 
    }); 

// Add a rect for each data value 
var rects = groups.selectAll('rect') 
    .data(function(d) { return d; }) 
    .enter() 
    .append("rect") 
    .attr("x", function(d, i) {  
     return xScale(d.y0);   
    }) 
    .attr("y", function(d, i) { 
     console.log('y: '+yScale(i)); 
     return yScale(i); 
    }) 
    .attr("width", function(d) { 
     console.log('width: '+xScale(d.y)); 
     return xScale(d.y); 
    }) 
    .attr("height", 10); 
olduğu

cevap

2

Sorun, ismine rağmen, xScale doğrusallığınızın doğrusal olmamasıdır (0 değeri 100'dür). Bu nedenle, genişlik için return xScale(d.y);'u kullandığınızda, her dikdörtgenin genişliğine 100 ekliyorsunuz (matematiksel terimlerle, kullanılan işlev xScale (z) = 0.00211 * z + 100: bu doğrusal değil, afin bir durumdur).


düzenleme, örnekler:

  • bir rect d.y0 başlayan = 0 olmalıdır X = 100
  • dy bir rect = 0 genişlik = 0
  • bir rect olmalıdır d.y0 = 71000 ile (toplamın yaklaşık yarısı) x = 250 (çizimin ortası)
  • dy = 71000 ile bir rect genişliği = 150 olmalıdır (çizimin genişliğinin yarısı)

=> Genişlik ve x konumu için doğrudan aynı ölçekte kullanılması mümkün değildir. Yani ya genişlik ve x hesaplamak için farklı işlevler kullanıyorsunuz ya da x için ek bir transform aldatıyorsunuz (aşağıdaki orijinal çözümüme bakın).


kolay çözüm, bir range (yerine [100,400] arasında) [0,300] arasında, ve arsa merkezi .attr("transform", "translate(100,0)") bir g çizim alanı içinde koymaktır.

İkinci seçenek (tercih ettiğiniz gibi geliyor): genişlik için xScale(d.y0+d.y) - xScale(d.y0) kullanın (yalnızca xScale(d.y) yerine). Bu, doğrudan sol ve sağ uç noktalar arasındaki mesafeyi hesaplar, yani genişliği verir. Herhangi bir ölçekle çalışması gerekir (zorunlu olarak doğrusal değil).

İkinci sorunuza gelince, bunu yapmanın başka bir genel yolunu bilmiyorum (kendi çizim prosedürünü yazmaktan başka, çok zor olmayacak). Ancak, basit bir diziyi kolayca düzenine dönüştürebilirsiniz:

var dataset = [66852, 7550] 
var layoutDataset = dataset.map(function(d){ return [{y:d}] }); 
+0

Cevabınız için teşekkür ederiz. Genişliği hesaplarken D3'ün neden menzilin başlangıç ​​değeri olarak 100 almamasını anlamakta zorluk çekiyorum. İdeal olarak, 0 ile 100 arasında eşleşmeli veya eşleşmelidir. Başka bir deyişle, [0, 500] gibi bir alanı, dönüştürmeyi kullanmak zorunda kalmadan [100, 300] gibi bir aralıkta nasıl eşleştirebilirim? – AlwaysALearner

+0

Umut şimdi daha açık :) – tarulen

+0

Çok! Tekrar teşekkürler! :) – AlwaysALearner