Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3.js IE vs Chrome SVG not showing

I have a simple D3 donut diagram with a .mouseover() event that updates an SVG:text element at the center of the donut hole. It works great...

enter image description here

Until I encounter users with IE 9, 10 and 11. These browsers won't render the center label. Is there a way to accommodate IE and show the center label in both browsers?

enter image description here

The HTML page is based on HTML5BoilerPlate with the various shims to detect old browsers.

The D3 script seems pretty straight forward.

    d3.json("data/census.php", function(error, dataset) { 
    var h = 220,  w = 295;
    var outerRadius = h / 2, innerRadius = w / 4;
    var color = d3.scale.category20b();
    var svg= d3.select("#dailycensus")
                .append("svg")
                .data([dataset])
                .attr("width", w)
                .attr("height", h) 
                .append("svg:g")
                .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");

    var arc = d3.svg.arc()
                .innerRadius(innerRadius)
                .outerRadius(outerRadius);

    var pie = d3.layout.pie()
                .value(function(d,i) { return +dataset[i].Census; });

    var arcs = svg.selectAll("g.slice")
                .data(pie)
                .enter()
                .append("svg:g")
                .attr("class", "slice");

    var syssum = d3.sum(dataset, function(d,i) { return +dataset[i].Census; });

    var tip = d3.tip()
                .attr("class", "d3-tip")
                .html(String);

    var formatter = d3.format(".1%");

    svg.append("text")
            .attr("id", "hospital")
            .attr("class", "label")
            .attr("y", -10)
            .attr("x", 0)
            .html("Health System Census"); // Default label text
    svg.append("text")
            .attr("id", "census")
            .attr("class", "census")
            .attr("y", 40)
            .attr("x", 0)
            .html(syssum); // Default label value

    arcs.append("svg:path")
        .call(tip) // Initialize the tooltip in the arc context
        .attr("fill", function(d,i) { return color(i); }) // Color the arc
        .attr("d", arc)
        .on("mouseover", function(d,i) {
                tip.show( formatter(dataset[i].Census/syssum) );
// Update the doughnut hole label with slice meta data 
                svg.select("#hospital").remove();
                svg.select("#census").remove();
                svg.append("text")
                    .attr("id", "hospital")
                    .attr("class", "label")
                    .attr("y", -10)
                    .attr("x", 0)
                    .html(dataset[i].Facility);
                svg.append("text")
                    .attr("id", "census")
                    .attr("class", "census")
                    .attr("y", 40)
                    .attr("x", 0)
                    .html(+dataset[i].Census);
                })

        .on("mouseout", function(d) { 
                tip.hide();
// Return the doughnut hole label to the default label
                svg.select("#hospital").remove(); 
                svg.select("#census").remove();
                svg.append("text")
                    .attr("id", "hospital")
                    .attr("class", "label")
                    .attr("y", -10)
                    .attr("x", 0)
                    .html("Health System Census");
                svg.append("text")
                    .attr("id", "census")
                    .attr("class", "census")
                    .attr("y", 40)
                    .attr("x", 0)
                    .html(syssum);
                })
like image 204
Colin Avatar asked Dec 12 '22 02:12

Colin


2 Answers

Replace all the .html calls with .text calls. Generally innerHTML is for HTML things although browsers are giving it SVG support as everybody keeps expecting it to work.

like image 89
Robert Longson Avatar answered Dec 28 '22 23:12

Robert Longson


It's not immediately clear what is causing the issue, however setting the .text property instead resolves the issue after testing with Fiddler:

svg.append("text")
    .attr("id", "hospital")
    .attr("class", "label")
    .attr("y", -10)
    .attr("x", 0)
    .text(dataset[i].Facility);
svg.append("text")
    .attr("id", "census")
    .attr("class", "census")
    .attr("y", 40)
    .attr("x", 0)
    .text(+dataset[i].Census);
})

After investigating the <text /> elements directly in the Developer Tools you can see that setting the .innerHTML property doesn't render the results you'd expect, however .textContent does.

If this is working as expected in both Chrome and Firefox, I'll gladly open up an interop bug for the IE team to look into. We've been doing some SVG work lately, so I may find that this has already been discussed.

like image 31
Sampson Avatar answered Dec 29 '22 00:12

Sampson