score:2

Accepted answer

In your fiddle, you're appending g to your svg and assigning it your variable svg:

var svg = d3.select("#priceWithMilestones")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform",
     "translate(" + margin.left + "," + margin.top + ")");

It looks like getSVGString() expects the root node, and not a g element. You should probably change your code so that svg reflects the root svg element, and create another variable to store the g element, but for a quick and dirty fix, you can change

var svgString = getSVGString(svg.node());

to

var svgString = getSVGString(d3.select('svg').node());

And should save. Updated fiddle: https://jsfiddle.net/c19664p3/8/

Edit: As for exported styles, it looks like you can't refer to selectors outside of the svg when declaring selecting. Additionally it looks like it has to consist of exactly just an id or a class. See my other answer for a more lax CSS rule exporter.

So changing this:

#priceWithMilestones .line {
  fill: none;
  stroke: #14da9e;
  stroke-width: 2px;
}

to:

.line {
  fill: none;
  stroke: #14da9e;
  stroke-width: 2px;
}

exports the line style for just the svg. Updated fiddle: https://jsfiddle.net/c19664p3/10/

score:1

After looking at getCSSStyles, it looks like it only checks for rules that match exactly the id or the class of the root svg and its child elements. I think this is a more forgiving implementation:

function getCSSStyles( parentElement ) {
    var nodesToCheck = [ parentElement ], i;

    // Add all the different nodes to check
    var childNodes = parentElement.getElementsByTagName("*");
    for (i = 0; i < childNodes.length; i++) {
        nodesToCheck.push(childNodes[i]);
    }

    // Extract CSS Rules
    var extractedCSSRules = [];
    for (i = 0; i < document.styleSheets.length; i++) {
        var s = document.styleSheets[i];

        try {
            if (!s.cssRules) continue;
        } catch( e ) {
            if (e.name !== 'SecurityError') throw e; // for Firefox
            continue;
        }

        var cssRules = s.cssRules;
        var ruleMatches;
        for (var r = 0; r < cssRules.length; r++) {
            ruleMatches = nodesToCheck.reduce(function (a, b) {
                return a || b.matches(cssRules[r].selectorText);
            }, false);
            if (ruleMatches)
                extractedCSSRules.push(cssRules[r].cssText);
        }
    }
    return extractedCSSRules.join(' ');
}

You still need to use rules internal to the svg (e.g. you still need to change #priceWithMilestones .line to .line in the CSS), but for future projects, I think it should catch more elements.

Updated fiddle with all of the changes: https://jsfiddle.net/c19664p3/12/


More Query from same tag