Lewis Carville
Lewis Carville

Reputation: 127

Javascript function won't build an SVG on IE11

I'm creating Google Analytic like graphs using SVGs to plot the data along points. I've sourced a function that will accept an array of points and build them into a path element which is inserted into an SVG on a HTML page. This function has been successful across Chrome, Firefox, Edge and Safari, but when it gets to IE11 it doesn't even output the element.

I believe the compatibility issue lies within the svgPath(); function. I've read that IE11 doesn't support ES6 javascript, and I'm wondering if someone with a better understanding of IE11 and javascript could help diagnose what's the cause of the issue.

FYI if i copy the path code out of the DOM on a browser where it works and directly place it in the HTML it does work on IE11. So the issue seems to be entirely on the javascript function and not the SVG not displaying for IE11.

Javascript:

var points = [
    [5, 10],
    [10, 40],
    [40, 30],
    [60, 5],
    [90, 45],
    [120, 10],
    [150, 45],
    [200, 10]
];

// Render the svg <path> element 
// I:  - points (array): points coordinates
//     - command (function)
//       I:  - point (array) [x,y]: current point coordinates
//           - i (integer): index of 'point' in the array 'a'
//           - a (array): complete array of points coordinates
//       O:  - (string) a svg path command
// O:  - (string): a Svg <path> element
var svgPath = function svgPath(points, command) {
  // build the d attributes by looping over the points
  var d = points.reduce(function (acc, point, i, a) {return i === 0 ? 'M ' +
    point[0] + ',' + point[1] :
    acc + ' ' + command(point, i, a);},
  '');
  return '<path d="' + d + '" fill="none" stroke="grey" />';
};

// Svg path line command
// I:  - point (array) [x, y]: coordinates
// O:  - (string) 'L x,y': svg line command
var lineCommand = function lineCommand(point) {return 'L ' + point[0] + ' ' + point[1];};

var svg = document.querySelector('.svg');
svg.innerHTML = svgPath(points, lineCommand);

HTML:

<svg version="1.1" 
    xmlns="http://www.w3.org/2000/svg" 
    width="1000" 
    height="200" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    viewBox="0 0 200 50" 
    preserveAspectRatio="xMidYMid meet" 
    class="svg">

    </svg>

The string the function should be returning, but isn't on IE11:

<path d="M 5,10 L 10 40 L 40 30 L 60 5 L 90 45 L 120 10 L 150 45 L 200 10" fill="none" stroke="grey"></path>

Screenshot of Graph in Chrome: https://i.sstatic.net/Qj51y.jpg

Screenshot of Graph in IE11: https://i.sstatic.net/BOgNf.jpg

And finally the source from where I got the javascript function: https://medium.com/@francoisromain/smooth-a-svg-path-with-cubic-bezier-curves-e37b49d46c74 https://codepen.io/francoisromain/pen/dzoZZj

Upvotes: 0

Views: 947

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101820

As Robert said, you can't use innerHTML to create SVG elements in IE 11. You have to create the elements yourself. To create an SVG <path> element, you use:

document.createElementNS("http://www.w3.org/2000/svg", "path");

Then you add the attributes you want using setAttribute().

var points = [
    [5, 10],
    [10, 40],
    [40, 30],
    [60, 5],
    [90, 45],
    [120, 10],
    [150, 45],
    [200, 10]
];

// Render the svg <path> element 
// I:  - points (array): points coordinates
//     - command (function)
//       I:  - point (array) [x,y]: current point coordinates
//           - i (integer): index of 'point' in the array 'a'
//           - a (array): complete array of points coordinates
//       O:  - (string) a svg path command
// O:  - (string): a Svg <path> element
var svgPath = function svgPath(svg, points, command) {
  // build the d attributes by looping over the points
  var d = points.reduce(function (acc, point, i, a) {return i === 0 ? 'M ' +
    point[0] + ',' + point[1] :
    acc + ' ' + command(point, i, a);},
  '');
  var path = document.createElementNS(svg.namespaceURI, "path");
  path.setAttribute("d", d);
  path.setAttribute("fill", "none");
  path.setAttribute("stroke", "grey");
  return path;
};

// Svg path line command
// I:  - point (array) [x, y]: coordinates
// O:  - (string) 'L x,y': svg line command
var lineCommand = function lineCommand(point) {return 'L ' + point[0] + ' ' + point[1];};

var svg = document.querySelector('.svg');
svg.appendChild( svgPath(svg, points, lineCommand) );
<svg version="1.1" 
    xmlns="http://www.w3.org/2000/svg" 
    width="1000" 
    height="200" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    viewBox="0 0 200 50" 
    preserveAspectRatio="xMidYMid meet" 
    class="svg">

</svg>

Upvotes: 1

Related Questions