Ani Menon
Ani Menon

Reputation: 28209

Fill 'rect' background with 2 colors in d3

This is the current code which fills skyblue in the background:

var rect=d3.select("svg")
  .append("rect")
  .attr("width", 1250)
  .attr("height", 100)
  .style("fill","skyblue");

Example fiddle

I want to fill a part of the rectangle(mean of the values being the split) with a different color.

We may do something like this(in html): fiddle

How could I do this in d3?

Upvotes: 1

Views: 2870

Answers (3)

rmoestl
rmoestl

Reputation: 3155

You could try to dynamically build a gradient with "hard" stops in the SVG's defs section and use this gradient on rect like this fill="url(#IdOfYourGradient)"

What I mean by hard stops is to define two stops for the two colors at the position of the boundary.

<defs>
      <linearGradient id="Gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="50%"/>
        <stop class="stop3" offset="50%"/>
        <stop class="stop4" offset="100%"/>
      </linearGradient>
      <style type="text/css"><![CDATA[
        .stop1, stop2 { stop-color: red; }
        .stop3, stop4 { stop-color: blue; }
      ]]></style>
 </defs>

Here's more about gradients in SVG.

Upvotes: 5

Ani Menon
Ani Menon

Reputation: 28209

This is what I finally used: (This is a derivative of rmoestl's answer)

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<svg width="520" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
      <linearGradient id="Gradient1">
        <stop class="stop1" offset="0%"/>
        <stop class="stop2" offset="60%"/>
        <stop class="stop3" offset="100%"/>
      </linearGradient>
      
      <style type="text/css"><![CDATA[
        #rect1 { fill: url(#Gradient1); }
        .stop1 { stop-color: skyblue; }
        .stop2 { stop-color: white; stop-opacity: 1; }
        .stop3 { stop-color: blue; }
      ]]></style>
  </defs>
 
  <rect id="rect1" x="10" y="10" width="500" height="200"/>
  
  
</svg>

Upvotes: 0

ozil
ozil

Reputation: 7117

You need to append two rect to have one rect with two color experience. Like below

var rect = d3.select("svg")
  .append("rect")
  .attr("width", 100)
  .attr("height", 100)
  .style("fill", "skyblue");
	
	var rect1 = d3.select("svg")
  .append("rect")
	.attr("x",100)
  .attr("width", 100)
  .attr("height", 100)
  .style("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg></svg>

Update
You need to find the width of svg

var svgWidth = d3.select("svg").node().getBoundingClientRect().width; //svg width
var rect1Width = svgWidth * 40 / 100;  // 40% width of svg for rect1  

Below is complete example

var svgWidth = d3.select("svg").node().getBoundingClientRect().width;
var rect1Width = svgWidth * 40 / 100;
var rect = d3.select("svg")
   .append("rect")
   .attr("width", rect1Width)
   .attr("height", 100)
   .style("fill", "skyblue");

var rect1 = d3.select("svg")
   .append("rect")
   .attr("x", rect1Width)
   .attr("width", svgWidth - rect1Width)
   .attr("height", 100)
   .style("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="200" height="100"></svg>

Upvotes: 0

Related Questions