Reputation: 1069
I have a D3 Force Layout that works fine on FireFox and Chrome but none of the foreign objects that I append to the SVG nodes for labels appear in the Safari Browser. The code is below. What is wrong? When I look the foreign objects in the FireFox/Chrome inspectors, it shows the html that I append to the foreign object. But when I look in the Safari inspector, the html isn't there at all.
EDIT: here is a simplified jsfiddle of the problem. If you open it in Chrome or Firefox, it works fine. If you open it in Safari, it doesn't.
nodeTxt = svg.selectAll(".nodetxt")
.data(nodeTxtData)
.enter()
.append("foreignObject")
.attr("class", "nodeTxt")
.attr({
"width": function(d) { return d.radius; },
"height": function(d) { return d.radius; }
})
.style({
"font-size": function(d) { return d.radius/4 + "px";},
"border-radius": function(d) { return d.count * 2;},
"-webkit-border-radius": function(d) { return d.count * 2;},
"-moz-border-radius": function(d) { return d.count * 2;},
"position": "relative",
"pointer-events": "none"
})
.html(function(d) {
var uID = d.name.replace(/([.*+?^=!;:$%&'," "{}()|\-[\]\/\\])/g, "").substring(0,25);
if (uID !== null) {
return '<div class="htmlDiv" id=' + uID + ' style="width:' + d.count * 4 + 'px; height:' + d.count * 4 + 'px;' +
'border-radius:' + d.count * 2 + 'px;' + '-webkit-border-radius:' + d.count * 2 + 'px;' +
'-moz-border-radius:' + d.count * 2 + 'px;">' + d.name + '</div>';
} else {
console.log(d);
return '<div id="bad"></div>';
}
})
.attr({
"transform": function(d) {
var uID = d.name.replace(/([.*+?^=!;:$%&'," "{}()|\-[\]\/\\])/g, "").substring(0,25);
if(uID !== null){
var w1 = (parseInt(d3.select(this).style("width"), 10) / 2),
w2 = d.count * 2,
y = -d.count * 2,
x = (w1 > w2) ? -w1 : -w2;
return "translate(" + x + "," + y + ")";
} else {
return "translate(0,0)";
}
},
"opacity": 1
});
Upvotes: 2
Views: 2099
Reputation: 36
A bit old, but I hope this could help:
Adding position: fixed
to the element inside foreignObject
solves the positioning, but not the scale. To solve the scale I added this:
d3.zoom().on('zoom', event => {
// zoom stuff...
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if (isSafari) {
d3.selectAll(NODE_SELECTOR).style('transform', `scale(${transform.k})`);
}
});
Also the element inside foreignObject
should have: transform-origin: 0px 0px
Upvotes: 1