I'm trying to add an svg image with '.svg' extension to my chart (another svg image created with d3).
This is the code:
d3.select("#chart1 svg")
.append("svg:image")
.attr("xlink:href", "img/icons/sun.svg")
.attr("width", 40)
.attr("height", 40)
.attr("x", 228)
.attr("y",53);
As you can see I'm setting "xlink:href" attribute, but d3 changes this to href in the browser:
<image href="img/icons/sun.svg" width="40" height="40" x="228" y="53"></image>
In fact, this code works perfectly if I use png extension. Any idea?
The code should work as is - here you can see an example of attaching an .svg file to d3:
http://jsfiddle.net/am8ZB/
Don't forget that it's possible the picture is actually there but you just can't see it-
you should inspect the page using the browser developer tools to see whether the picture has been placed out of the view area (due to your x/y values, for example).
more info on #chart1 would help in this case.
Related
I tried to fill rectangles with images. While images appear in Chrome, they do not appear in safari. I do not get any error messages. So I am really confused as to why this is the case, please help me! Alternatively, if you can help with filling rectangles with custom pictures, I'd also happy to hear from you!
function initRectElements(svg, data) {
imgUrl = "image/star/5.png";
d3.select(svg).append("defs")
.append("pattern")
.attr("id", "rating")
.attr("width", rectwidth)
.attr("height", rectheight)
.append("image")
.attr("xlink:href", imgUrl)
var sel = d3.select(svg)
.selectAll('rect.token')
.data(data);
sel.enter().append('rect')
.classed('token', true);
sel.exit().remove();
d3.select(svg).selectAll('rect.token')
.attr('x', function (d){return d
.x})
.attr('y', function (d){return d
.y})
.attr("width", rectwidth)
.attr("height", rectheight)
.attr('fill', "url(#rating)")
}
When you are using custom properties with images - Safari interprets images url another way, for example:
Chrome shows all images, but Safari logs "not allowed to load local resource"
Another example:
Chrome doesn't show all images, but Safari works well
The problem is direction, I don't know why but when you using custom properties and set url - safari add one more dot (".") in your url direction.
you can try the things like
1.-- Add the field !DOCTYPE at the top of your html document or
2.-- if you have image with URL like background-image:url("http://adf.co.us/dm/gs.png");
Then you have to add
image:url("http://www.adf.co.us/dm/gs.png");
i hope it can be helpful for you.
Here is my problem. My graph currently looks like this: Which is dandy. However, I want the black squares on top to be filled with pictures. Luckily I have a CSS file that has pictures linked with classes. I also have a JSON file that contains all the class names. All those class names are assigned to the squares and I can see the picture in the inspect element on Chrome. The only issue is the pictures don't appear in the square. (Also my axises broke, but that is secondary concern). CSS, JSON
This is where I'm assigning classes and creating the rectangles.
svg.selectAll(".div")
.data(data.chartData, function(d){return d.vNm;})
.enter().append("rect")
.attr("x", function(d){
return x(d.vNm);
})
.attr("y", function(d){
return (y(d.values.reduce(function(sum, d){
return sum + d.amount;
}, 0))) - 64.5;
})
.attr("width", 43)
.attr("height", 43)
.attr("class", function(d){return d.vId;})
.style("fill", function(d) { return segColor(d.data.type); });
One approach to solve your problem is to use html elements like div for the images above the chart instead of svg elements, so you can use the full power of css.
Luckily you don't need to calculate the position of those html elements by yourself, there are some libraries that help you position the images correctly above the bars in the chart.
Check out https://popper.js.org/ for example, you can just call its API for each bar you render using d3.js:
var popper = new Popper(barElement, onPopper, {
placement: 'top'
});
SVG elements do not follow exactly the same CSS rules as typical HTML elements.
In your case, background-image doesn't work.
The least painful way to achieve the effect would be to embed an <image> tag after the <rect>:
<image width="100" height="100" xlink:href="data:image/png;base64,...">
It means that you have to modify your JSON to store the image's base64 data in there instead of CSS.
I'm using the solution proposed here How to add an image to an svg container using D3.js, like this
svg.selectAll()
.data(chart.data.values)
.enter()
.append('svg:image')
.attr('class', 'logo-legend')
.attr('x', function (d, i) {
return d.position;
}
)
.attr('y', 251)
.attr('xlink:href', function (d, i) {
return d.fileName;
});
Which works on Chrome, but it's not working on FF and Safari. I can see on firebug that the images are being created on the html, but they are just not showing. Any idea why?
I can see that on Chrome the element created is
<image class="logo-legend" x="46.5" y="251" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/img/services/logo.png"></image>
While on FF is
<image class="logo-legend" x="46.5" y="251" href="/img/services/logo.png">
The W3 spec requires explicit height/width attributes. From the docs (bolding mine):
There are some important things to take note of (referenced from the
W3 specs):
If you do not set the x or y attributes, they will be set to 0.
If you do not set the height or width attributes, they will be set to
0.
Having a height or width attribute of 0 will disable rendering of the
image.
Given access to suitable topojson and bitmaps, I use the topoJSON file to generate a SVG viz via D3js. Then I append a bitmap to it via :
// Append bitmap
svg.append("image")
.attr("xlink:href", "./myimage.png")
.attr("width", width)
.attr("height", height)
.attr("class", "bg");
But this actually just add a link toward the image. Also, when I select the dataviz DOM, and save it as SVG, I don't have the bitmap binary, but just the bitmap's link.
Is it possible, and how to really embed my .png binary into my SVG DOM via D3js or javascript ?
See also: https://rugger-demast.codio.io/front/_location_map-en-wikiatlas.html , where you can try to download the SVG.
This example shows how to draw an image to a canvas element and use the .toDataURL function to get a snapshot of this canvas into a string that you can then use as the xlink:href attribute:
http://bl.ocks.org/emeeks/707681f1f5b4a2063d6e
I'm trying to create something on JSfiddle regarding a question about d3, but I was ambushed by an unexpected problem - the "g" element I am creating inside an "svg" is refusing to accept any dimensions I give it!
I have tried using inline styling, classes (including "!important"), but nothing seems to work. The dimensions are stuck at 0,0 and inspection shows width and height are "auto" (why?!)
This seems like a trivial issue but for the life of me I can't seem to get the "g" element to accept width and height values
see JSFiddle: http://jsfiddle.net/sangil/uKLU3/
<g> is an autosizing container. It has no dimensions itself but instead it always automatically sizes itself to contain all its contents.
The reason you're not seeing anything is that SVG (unlike html) does not size things using styles but using attributes instead. So you want
g.append("rect")
.attr("width", "300px")
.attr("height", "200px")
.style("fill", "steelblue");