How do I create a gradient that intersects different rectangles in D3JS?
1 answer
You must install gradientUnits
in userSpaceOnUse
. According to the docs userSpaceOnUse :
... represent the values in the coordinate system that result from taking the user's current coordinate system in place at the time the gradient element is referenced
Below is a demo without userSpaceOnUse
which the result is not what you want:
var svg = d3.select("svg");
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "50%")
.attr("x2", "100%")
.attr("y2", "50%");
gradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", "Black")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "white")
.attr("stop-opacity", 1);
var g = svg.append("g")
.style("fill", "url(#gradient)");
var rects = g.selectAll("foo")
.data(d3.range(7))
.enter()
.append("rect")
.attr("y", 20)
.attr("x", (d, i) => 20 + 50 * i)
.attr("width", 40)
.attr("height", 40);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="400"></svg>
Now demo with userSpaceOnUse
:
var svg = d3.select("svg");
var gradient = svg.append("defs")
.append("linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("y1", "50%")
.attr("x2", "100%")
.attr("y2", "50%")
.attr("gradientUnits","userSpaceOnUse");
gradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", "Black")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "white")
.attr("stop-opacity", 1);
var g = svg.append("g")
.style("fill", "url(#gradient)");
var rects = g.selectAll("foo")
.data(d3.range(7))
.enter()
.append("rect")
.attr("y", 20)
.attr("x", (d, i) => 20 + 50 * i)
.attr("width", 40)
.attr("height", 40);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="400"></svg>
+3
source to share