2016-09-30 10 views
0

横棒グラフを作成しました。d3js:条件に応じて変数に基づいて各バーに複数の色を追加する

各バーの幅は、オブジェクト変数ボリュームに基づいています。その後、私はスタックバーの代わりに各バーを作成する必要が実現し、2つのカテゴリは、変数がVOL1 & VOL2VOL1 + VOL2 = ボリュームをしているオブジェクト。

VOL1 & VOL2値の代わりに、あなたは(a)のデータを配置する必要があり、通常積み上げ棒法に基づく に各バー 2色を割り当てるための直接的な方法がある場合、私は思っていた

(b)x、y、y0を定義する(c)各配列バーに異なる色を割り当てます。

データ構造:

var data = [ 
{ "merchant": "A", 
    "volume": 100, 
    "vol1": 48, 
    "vol2": 52 
}, 
{...}, 
{...} 
]; 

チャートを描画する特定のコードがある:要するに

var bar = d3.select(".mainGroup").selectAll(".bar") 
      .data(data_merchantTop100Vol); 

    bar.attr("x", 0) 
     .attr("y", d => y(d.merchant)) 
     .attr("height", y.rangeBand()) 
     .transition().duration(50) 
     .attr("width", d => x(d.volume)); 

    bar.enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", 0) 
     .attr("y", d => y(d.merchant)) 
     .attr("height", y.rangeBand()) 
     .transition().duration(50) 
     .attr("width", d => x(d.volume)) 
     // THIS PART IS TO FILL 2 COLORS TO THE 2 SECTIONS OF EACH BAR 
     // .style("fill", function(d) { 
     //  if(d.Vol1) { return "blue"} 
     //  else if (d.vol2) { return "red"}; 
     // }) 

、Iは、IF条件着色法の代わりに典型的に使用して、水平積層バーを作成しますスタックバー法。アイデアのインスピレーション:http://www.d3noob.org/2013/01/select-items-with-if-statement-in-d3js.html

現在の水平棒グラフ:
enter image description here

望ましい結果:
enter image description here

+0

だから、あなたは値 'vol1'と' vol2'の割合に基づいて満たされている単一 'rect'で終わるしたいですか?または、各バーが色で塗りつぶされている2つの 'rect 'が必要ですか? – Mark

+0

値 'vol1'と' vol2'の%に基づいて塗りつぶされた単一の 'rect'です。私は2つの 'rect'を持っている場合、それは典型的な積み重ね棒法になります。 :) – Shawn

+0

あなたが本当にそれを望むなら、それは可能ですが、@mpbastosは以下の通りです。 2つの矩形を使用する方がずっと簡単です。 – Mark

答えて

2

あなたは右の割合を使用してgradientsで四角形を埋めるために試みることができるが、これはオーバーソリューションが複雑になります。最も簡単な方法は、各色ごとに1つの長方形を使用することです。あなたは、このためにデータを再配置する必要はありません。

// Vol1 bars 
    bar.enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", 0) 
     .attr("y", d => y(d.merchant)) 
     .attr("height", y.bandwidth()) 
     .transition().duration(50) 
     .attr("width", d => x(d.vol1)) 
    .style("fill", "blue") 

// Vol2 bars 
    bar.enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", d => x(d.vol1)) 
     .attr("y", d => y(d.merchant)) 
     .attr("height", y.bandwidth()) 
     .transition().duration(50) 
     .attr("width", d => x(d.vol2)) 
    .style("fill", "red") 
+0

ありがとうございました、解決策:) – Shawn

1

あなたが本当に、本当にあなたが割合に色を分割することができ、カスタムグラデーションを設定する必要があるだろう、1つのバーでこれを行う場合:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
</head> 
 

 
<body> 
 

 
    <script> 
 
    var data = [{ 
 
     volume: Math.random() * 400, 
 
     vol1: Math.random() * 400, 
 
     vol2: Math.random() * 400 
 
    }, { 
 
     volume: Math.random() * 400, 
 
     vol1: Math.random() * 400, 
 
     vol2: Math.random() * 400 
 
    }, { 
 
     volume: Math.random() * 400, 
 
     vol1: Math.random() * 400, 
 
     vol2: Math.random() * 400 
 
    }, { 
 
     volume: Math.random() * 400, 
 
     vol1: Math.random() * 400, 
 
     vol2: Math.random() * 400 
 
    }]; 
 

 
    var height = 400, 
 
     width = 600, 
 
     color1 = "orange", 
 
     color2 = "steelblue", 
 
     barHeight = 20; 
 

 
    var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width', width) 
 
     .attr('height', height); 
 

 
    var defs = svg.append("defs"); 
 

 
    var g = svg.selectAll("g") 
 
     .data(data) 
 
     .enter() 
 
     .append("g") 
 

 
    g.append("rect") 
 
     .attr("width", function(d) { 
 
     return d.volume 
 
     }) 
 
     .attr("height", barHeight) 
 
     .attr("x", 10) 
 
     .attr("y", function(d, i) { 
 
     return i * (barHeight + 5); 
 
     }) 
 
     .style("fill", function(d, i) { 
 

 
     var p = (d.vol1/(d.vol1 + d.vol2)) * 100, 
 
      grad = defs.append("linearGradient") 
 
      .attr("id", "grad_" + i); 
 

 
     grad.append("stop") 
 
      .attr("offset", "0%") 
 
      .attr("stop-color", color1); 
 
     grad.append("stop") 
 
      .attr("offset", (p) + "%") 
 
      .attr("stop-color", color1); 
 
     grad.append("stop") 
 
      .attr("offset", (p) + "%") 
 
      .attr("stop-color", color2); 
 
     grad.append("stop") 
 
      .attr("offset", "100%") 
 
      .attr("stop-color", color2); 
 

 
     return "url(#grad_" + i + ")"; 
 
     }); 
 
     
 
    g.append("text") 
 
     .attr("x", function(d) { 
 
     return d.volume + 12 
 
     }) 
 
     .attr("y", function(d, i) { 
 
     return (i * (barHeight + 5)) + 13; 
 
     }) 
 
     .text(function(d){ 
 
     var p1 = (d.vol1/(d.vol1 + d.vol2)) * 100, 
 
      p2 = (d.vol2/(d.vol1 + d.vol2)) * 100; 
 
     
 
     return Math.round(p1) + "% and " + Math.round(p2) + "%"; 
 
     }) 
 
     .style("stroke", "none") 
 
     .style("fill", "black") 
 
     .style("font-family", "arial") 
 
     .style("font-size", "12px"); 
 
    </script> 
 

 
</body> 
 

 
</html>

+0

ありがとう!あなたのコードを分析して理解します – Shawn

関連する問題