I wanted to create a circular crop an image to use in conjunction with a svg circle, and decided on filling the svg circle with a pattern. I have it working for the single case:
defs.append("svg:pattern")
.attr("id", "story1")
.attr("width", 200)
.attr("height", 100)
.attr("patternUnits", "userSpaceOnUse")
.append("svg:image")
.attr("xlink:href", 'ml-image4.png')
.attr("width", 200)
.attr("height", 100)
.attr('x',0)
.attr('y',0);
var circle1 = svg.append("circle")
.attr("cx", 100)
.attr("cy", 50)
.attr("r", 40)
.style("fill", "#fff")
.style("fill", "url(#story1)")
.style('stroke','#000')
.style('stroke-width', 5);
Then I got all gung-ho and tried to adapt for a programmatic implementation, but it didn't pan out so well. I'm hoping there is a way to do it, because my end goal is to have an application that uses many pictures as patterns. It will be like a little gallery where each svg circle is spaced out across the page using .attr('x', function(d,i) { return 100+i*200})
) and each circle referencing a different pattern. The pattern id is a data member, so I was trying to do this: .style('fill',function(d) {return "url(#"+d.id+")"; })
. I'm not exactly sure why it didn't work; to my eyes it seems functional-ish. I did get the error:
Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Element': 'svg:pattern' is not a valid selector.
Here is my adaptation for programmatic def patterns and a quick look at my data:
var data = [
{'id':'story1', 'Title':'Title1', 'Date':'03/10/2017','Icon':'Icon1.png', 'Link':'www.link1.com/'},
{'id':'story2', 'Title':'Title2', 'Date':'12/15/2017','Icon':'Icon2.png', 'Link':'www.link2.com/'}
];
var defs = svg.append('svg:defs');
defs.selectAll(null)
.data(data)
.enter()
.append('svg:pattern')
.attr('id',function(d) {return d.id; })
.attr('width', 200)
.attr('height', 100)
.attr('patternUnits', 'userSpaceOnUse')
.append('svg:image')
.attr('xlink:href', function(d) {return d.Icon})
.attr('width', 200)
.attr('height', 100)
.attr('x',0)
.attr('y',0);
svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d,i) {return 100+i*200})
.attr('cy', 50)
.attr('r',40)
.style('fill',function(d) {return "url(#"+d.id+")"; })
.style('stroke','#000')
.style('stroke-width',3);
Question
Judging by the error, my adaptation seems to be flawed. What can I tweak to get programmatic patterns for svg circles here? In my humble opinion, my approach isn't all that different from the simple case at the very beginning of the post (1 pattern 1 circle), all I was trying to do was scale it up so I can use d3.selectAll()
using my data.