Here's how HTML page's contents look.
<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<object type="image/svg+xml" data="Map-edited.svg"></object>
<script src="script.js"></script>
</body>
</html>
And here's how script.js
looks.
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("Hello");
var svg= d3.select("object").select("svg");
svg.selectAll('g')
.on("mouseover",function(){
return tooltip.style("visibility","visible");
})
.on("mousemove",function(){
var offset= 20;
var topPosition= (event.pageY-offset)+"px";
var leftPosition= (event.pageX+offset)+"px";
return tooltip.style("top",topPosition).style("left",leftPosition);
})
.on("mouseout", function(){
return tooltip.style("visibility","hidden");
});
When I open my HTML page, I see the SVG element with all the g
elements in it. When I mouseover each g
element, no tooltip appears. But if I replace object
with the svg
tag and its contents, the tooltip works. How do I make d3 select an SVG in an object
tag?
You need to access the <object>
contentDocument
in order to access its contained elements.
To do this, you also need to wait until your <object>
has loaded its content.
I'm not too much into d3, so it might not be the best d3 way of doing, but at least it works:
(but not in StackSnippet's null origined iframes...)
fetch('https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg')
.then(r => r.blob())
.then(b => obj.data = URL.createObjectURL(b));
obj.onload = function() { // wait for the svg has loaded
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("Hello");
var obj = this; // we're in the object's load event handler.
var svg = d3.select(obj.contentDocument) // get the contentDocument
.select("svg"); // then get the svg inside
svg.selectAll('g')
.on("mouseover", function() {
return tooltip.style("visibility", "visible");
})
.on("mousemove", function() {
var event = d3.event;
var offset = 20;
var topPosition = (event.pageY - offset) + "px";
var leftPosition = (event.pageX + offset) + "px";
return tooltip.style("top", topPosition).style("left", leftPosition);
})
.on("mouseout", function() {
return tooltip.style("visibility", "hidden");
});
};
<script src="https://d3js.org/d3.v4.min.js"></script>
<object id="obj" type="image/svg+xml"></object>
I have no experience with d3 but this might help. You need to wait untill your window is fully loaded.
// object of my SVG
<object id="fridge" data={FridgePicture} ></object>
window.onload = function() {
// Get the fridgeObject by ID
var fridgeObj = document.getElementById("fridge");
// Get the SVG document inside the Object tag
var fridgeDoc = fridgeObj.contentDocument;
// From here you can get an item you wish e.g:
var rightDoor = fridgeDoc.getElementById("RightDoor");
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With