Inspired by the ability to use svg images as data elements, as this block demonstrates, I wanted to take it a level further and use SVG images (SVG paths), so that I could also adjust their stroke color & thickness.
Here is a screenshot of the block I have linked above:
The code uses an image, instead of an SVG path. I mimicked the code, pointing my equivalent of .attr("xlink:href", "https://github.com/favicon.ico")
to an svg image instead. E.g., .attr("xlink:href", "../images/my_logo.svg")
, where my_logo.svg
is an icon, similar to what is shown in the example above, but with a valid svg element. E.g., the my_logo.svg
element starts something like this:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="900.000000pt" height="900.000000pt" viewBox="0 0 900.000000 900.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,900.000000) scale(0.100000,-0.100000)">
<path d="M4280 8997 c-3 -2 -54 -7 -115 -10 -684 -37 -1449 -290 -2080 -690
-621 -393 -1182 -990 -1525 -1622 -24 -44 -53 -98 -65 -120 -44 -81 -139 -294
. . .
2310 880 278 21 516 20 785 -6z" stroke="red" stroke-width="2" fill="red" />
. . .
However, I am reading this SVG in incorrectly, so that it is treated as an image. I am copying the example in the block mentioned above, which does things like:
node.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
Specifically, in my case I am trying to make a scatterplot, so my code looks like:
var points = svg.selectAll('image').data(data)
.enter().append('image').classed('point', true)
.attr("xlink:href", "../images/my_logo.svg")
This obviously brings the SVG in as an "image", which does not allow for me to adjust the stroke width or color or these things which I wish to adjust. For instance, if I look at the elements in the console, using d3.selectAll("image")
, I'll see that I have access to x
, y
, width
, height
, etc., just as I would with a normal image, not a truly flexible SVG path element.
You, of course, can't modify an SVG that's brought in as an image. You can, however, load the SVG via AJAX and manipulate and inject it from there. You may be better off using a format that is not strictly SVG so that it's easier to modify and inject. For example, an SVG fragment (just the contents of the <svg>
element) would be directly injectable and then could be modified through CSS.
Here is a full example to demonstrate how this can be done, using d3.xhr
.