Manitoba
Manitoba

Reputation: 8702

Javascript in a SVG file

I have a special request as I want to generate a SVG directly inside the SVG file ;) So far I've made the following code with generate SVG tags but nothing appears on screen. I might have made something wrong but I don't know where as it doesn't throw any error.

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet" id="content">
  <defs>
    <style type="text/css"><![CDATA[
      @font-face {font-family: 'Futura-Heavy'; src: url(../public/css/FuturaStd/FuturaStd-Heavy.otf) format('opentype');}
      @font-face {font-family: 'Futura-Light'; src: url(../public/css/FuturaStd/FuturaStd-Light.otf) format('opentype');}
      @font-face {font-family: 'Bryant-Regular'; src: url(../public/css/Bryant/Bryant_Pro/BryantPro-Regular.otf) format('opentype');}

      .title{
        font-family: 'Futura-Heavy', 'Helvetica Neue', sans-serif, Helvetica;
        font-size: 14pt;
        stroke: none;
        fill: white;
        letter-spacing: 2px;
        text-anchor: middle;
      }

      .subtitle{
        font-family: 'Bryant-Regular', 'Helvetica Neue', sans-serif, Helvetica;
        font-size: 14pt;
        stroke: none;
        fill: grey;
        letter-spacing: 2px;
      }
    ]]></style>
  </defs>
  <script type="text/javascript"><![CDATA[
    var data = {
      "measures" : {
        "avg" : 0.68,
        "value" : 0.2
      },
      "config" : {
        "width" : 150,
        "height" : 180,
      },
      "titles" : {
        "right_eye" : "RIGHT EYE",
        "left_eye" : "LEFT EYE",
        "as_of" : "AS {0}% OF PEOPLE"
      }
    };
    var width = data.config.width || 1500;                          // Longueur totale
    var height = data.config.height || 1000;                        // Hauteur totale
    var widthVis = 330;                                                       // Longueur de la visualisation
    var heightVis = 300;                                                      // hauteur de la visualisation
    var heightBar = 25;                                                       // Hauteur du cadre
    var color = data.measures.color || ["#FFC400", "#18B4DC"];  // couple de couleurs
    var widthBar = widthVis * 0.8;                                      // Longueur du cadre
    data.config.host = data.config.host || '../public';         // Path to resources

    var format_string = function() {
      var mString = arguments[0];
      for (var i=1; i<arguments.length; i++) {
        var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");
        mString = mString.replace(regEx, arguments[i]);
      }
      return mString;
    };

    var svg = document.getElementById('content');
    svg.setAttribute('height', height +'px');
    svg.setAttribute('width', width +'px');
    svg.setAttribute('viewBox', '0 0 ' + widthVis + ' ' + heightVis);

    var viz = document.createElement('g');
    viz.setAttribute('id', 'viz');
    viz.setAttribute('transform', 'translate(' + widthVis * 0.1 + ')');
    svg.appendChild(viz);

    // Create gradient
    var defs = document.getElementsByTagName('defs')[0];
    var categoryGradient = document.createElement('linearGradient');
    categoryGradient.setAttribute('id', 'categoryRelativeGradient');
    categoryGradient.setAttribute('x1', '0%');
    categoryGradient.setAttribute('x2', '100%');
    categoryGradient.setAttribute('y1', '0%');
    categoryGradient.setAttribute('y2', '0%');
    defs.appendChild(categoryGradient);
    var stop1 = document.createElement('stop');
    stop1.setAttribute('offset', '0%');
    stop1.setAttribute('stop-color', color[0]);
    stop1.setAttribute('stop-opacity', 1);
    categoryGradient.appendChild(stop1);
    var stop2 = document.createElement('stop');
    stop2.setAttribute('offset', (data.measures.avg*100) + '%');
    stop2.setAttribute('stop-color', color[0]);
    stop2.setAttribute('stop-opacity', 1);
    categoryGradient.appendChild(stop2);
    var stop3 = document.createElement('stop');
    stop3.setAttribute('offset', (data.measures.avg*100) + '%');
    stop3.setAttribute('stop-color', color[1]);
    stop3.setAttribute('stop-opacity', 1);
    categoryGradient.appendChild(stop3);
    var stop4 = document.createElement('stop');
    stop4.setAttribute('offset', '100%');
    stop4.setAttribute('stop-color', color[1]);
    stop4.setAttribute('stop-opacity', 1);
    categoryGradient.appendChild(stop4);

    // Create legend
    var forme = document.createElement('g');
    forme.setAttribute('id', 'path');
    forme.setAttribute('transform', 'translate(0, ' + heightVis * 0.6 + ')');
    viz.appendChild(forme);
    var circle1 = document.createElement('circle'); // Round corners
    circle1.setAttribute('cx', 0);
    circle1.setAttribute('cy', 0);
    circle1.setAttribute('r', heightBar / 2);
    circle1.setAttribute('fill', color[0]);
    forme.appendChild(circle1);
    var circle2 = document.createElement('circle'); // Round corners
    circle2.setAttribute('cx', widthBar);
    circle2.setAttribute('cy', 0);
    circle2.setAttribute('r', heightBar / 2);
    circle2.setAttribute('fill', color[1]);
    forme.appendChild(circle2);
    var rect1 = document.createElement('rect'); // Frame
    rect1.setAttribute('x', 0);
    rect1.setAttribute('y', - heightBar / 2);
    rect1.setAttribute('height', heightBar);
    rect1.setAttribute('width', widthBar);
    rect1.setAttribute('fill', 'url(#categoryRelativeGradient)');
    forme.appendChild(rect1);
    var circle3 = document.createElement('circle'); // Extreme points
    circle3.setAttribute('cx', 0);
    circle3.setAttribute('cy', 0);
    circle3.setAttribute('r', heightBar / 4);
    circle3.setAttribute('fill', 'black');
    forme.appendChild(circle3);
    var circle4 = document.createElement('circle'); // Extreme points
    circle4.setAttribute('cx', widthBar);
    circle4.setAttribute('cy', 0);
    circle4.setAttribute('r', heightBar / 4);
    circle4.setAttribute('fill', 'black');
    forme.appendChild(circle4);
    var dotted_line; // Dotted line
    for(var index = widthBar / 20; index < widthBar; index += widthBar / 20) {
      dotted_line = document.createElement('circle');
      dotted_line.setAttribute('cx', index);
      dotted_line.setAttribute('cy', 0);
      dotted_line.setAttribute('r', heightBar / 12);
      dotted_line.setAttribute('fill', 'black');
      forme.appendChild(dotted_line);
    }

    // Textual information
    var legend = document.createElement('g');
    legend.setAttribute('id', 'legend');
    legend.setAttribute('transform', 'translate('+(data.measures.value < 0.5 ? 0 : widthBar)+', ' + heightVis * 0.15 + ')');
    viz.appendChild(legend);
    var rect_width = data.measures.value < 0.5 ? data.titles.left_eye.length * 15 : data.titles.right_eye.length * 15;
    var legend_title = document.createElement('g');
    legend_title.setAttribute('transform', 'translate('+(data.measures.value < 0.5 ? 0 : -rect_width)+', 0)');
    legend.appendChild(legend_title);
    var rect2 = document.createElement('rect'); // Back rectangle
    rect2.setAttribute('x', 0);
    rect2.setAttribute('y', 0);
    rect2.setAttribute('height', 40);
    rect2.setAttribute('width', rect_width);
    rect2.setAttribute('fill', 'black');
    legend_title.appendChild(rect2);
    var text1 = document.createElement('text'); // Legend text
    text1.setAttribute('class', 'title');
    text1.setAttribute('x', rect_width - 30);
    text1.setAttribute('y', 27);
    text1.setAttribute('height', 40);
    text1.setAttribute('width', rect_width);
    text1.setAttribute('fill', 'white');
    text1.setAttribute('stroke', 'none');
    text1.setAttribute('text-anchor', (data.measures.value < 0.5 ? 'begin' : 'end'));
    text1.appendChild( document.createTextNode(data.measures.value < 0.5 ? data.titles.left_eye : data.titles.right_eye) );
    legend_title.appendChild(text1);

    // Legend sub-text
    var as_of_text = data.titles.as_of.toString();
    var as_of_text_part1 = as_of_text.substr(0, as_of_text.indexOf("%") + 1);
    var as_of_text_part2 = as_of_text.substr(as_of_text.indexOf("%") + 1, as_of_text.length);
    as_of_text_part1 = format_string(as_of_text_part1, (data.measures.value < 0.5 ? data.measures.avg*100 : ((1 - data.measures.avg)*100).toFixed()));
    var subtext1 = document.createElement('text');
    subtext1.setAttribute('class', 'subtitle');
    subtext1.setAttribute('x', (data.measures.value < 0.5 ? 5 : - 5));
    subtext1.setAttribute('y', 65);
    subtext1.setAttribute('fill', 'black');
    subtext1.setAttribute('text-anchor', (data.measures.value < 0.5 ? 'begin' : 'end'));
    subtext1.appendChild( document.createTextNode(as_of_text_part1) );
    legend.appendChild(subtext1);
    var subtext2 = document.createElement('text');
    subtext2.setAttribute('class', 'subtitle');
    subtext2.setAttribute('x', (data.measures.value < 0.5 ? 5 : - 5));
    subtext2.setAttribute('y', 85);
    subtext2.setAttribute('fill', 'black');
    subtext2.setAttribute('text-anchor', (data.measures.value < 0.5 ? 'begin' : 'end'));
    subtext2.appendChild( document.createTextNode(as_of_text_part2) );
    legend.appendChild(subtext2);

    // Vertical line
    var line = document.createElement('line');
    line.setAttribute('class', 'gaugeMark');
    line.setAttribute('x1', 0);
    line.setAttribute('x2', 0);
    line.setAttribute('y1', 0);
    line.setAttribute('y2', heightVis * 0.45);
    line.setAttribute('fill', 'black');
    line.setAttribute('stroke', 'black');
    legend.appendChild(line);
  ]]></script>
</svg>

I got a white screen with this code while in the Chrome developer console I got something that looks to be a valid SVG.

Could you help me to solve that issue ? I'm almost certain I'm not that far from the solution.

Thanks

Upvotes: 1

Views: 192

Answers (1)

Robert Longson
Robert Longson

Reputation: 124229

SVG elements must be created in the SVG namespace so you need to use createElementNS rather than createElement to create them e.g.

var viz = document.createElementNS('http://www.w3.org/2000/svg', 'g');

Upvotes: 3

Related Questions