D3: Cannot append simple path to svg container

409
January 26, 2017, at 5:24 PM

I am not succeding in appending a path on a simple svg container. It considers my "path" element as a text instead.

Here is my code:

// Create the SVG 
var tracer = {}; 
tracer.$container = document.getElementById('container'); 
 
tracer.$svg = $('<svg class="svg-d3-table" style="width:100%; height:100%">'); 
tracer.$container.append(tracer.$svg); 
 
// Specify the path points 
var pathInfo = [{x:0, y:60}, 
                {x:50, y:110}, 
                {x:90, y:70}, 
                {x:140, y:100}]; 
 
// Specify the function for generating path data              
var pathLine = d3.line() 
                 .x(function(d){return d.x;}) 
                 .y(function(d){return d.y;}) 
                 .curve(d3.curveBasis);  
 
// Append path 
tracer.$svg.append("path") 
           .attr("d", pathLine(pathInfo)) 
           .attr("stroke", "white") 
           .attr("stroke-width", 8) 
           .attr("fill", "none");

Instead of having a new path element as

<path d="M314,352L314,352C314,352,314,352,..."></path>

It comes with the following:

<svg class="svg-d3-table" style="..." d="M0,60L8.3,68.3.7,...">path</svg>

What am I missing?

PS: Sorry, I come from c++ and can be struggled with some very basic js operations.

Thank you very much. Kind Regards.

Answer 1

As others have pointed out in the comments, avoid mixing jquery and d3.

The root of your problems though is that your tracer.$svg is a jquery selector but you are treating it as a d3 selector. While both of them have an append method, they are two wholly different beasts (and as @altocumulus points out, jquery don't play so nice manipulatively SVG).

Here's your code as I would write it with just d3:

<!DOCTYPE html> 
<html> 
 
<head> 
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
</head> 
 
<body> 
  <div id="container" style="background-color: steelblue"></div> 
  <script> 
    // Create the SVG 
    var tracer = {}; 
    tracer.$container = d3.select('#container'); 
 
    tracer.$svg = tracer.$container.append("svg") 
      .attr("class", "svg-d3-table") 
      .style("width", "100%") 
      .style("height", "100%"); 
 
    // Specify the path points 
    var pathInfo = [{ 
      x: 0, 
      y: 60 
    }, { 
      x: 50, 
      y: 110 
    }, { 
      x: 90, 
      y: 70 
    }, { 
      x: 140, 
      y: 100 
    }]; 
 
    // Specify the function for generating path data              
    var pathLine = d3.line() 
      .x(function(d) { 
        return d.x; 
      }) 
      .y(function(d) { 
        return d.y; 
      }) 
      .curve(d3.curveBasis); 
 
    // Append path 
    tracer.$svg.append("path") 
      .attr("d", pathLine(pathInfo)) 
      .attr("stroke", "white") //<-- need a color? 
      .attr("stroke-width", 8) 
      .attr("fill", "none"); 
  </script> 
</body> 
 
</html>

Answer 2

Thanks to altocumulus:

jquery's append not working with svg element? Is exactly the kind of information I was looking for better understanding of manipulating DOM (but still shows me how much front-end development can be akward).

Thank to Gerardo Furtado:

Indeed the need of different lib leads easily to confusing behavior and makes JS hard to handle when working on an existing project (how to determine namespace by reading code, avoid collision...)

I handled my problem by only managing my svg using D3 as you adviced:

tracer.$svg = tracer.capsule.$svg = d3.select("#" + tracer.defaultName) 
                                        .append("svg") 
                                        .attr("width", "100%") 
                                        .attr("height", "100%") 
                                        .attr("id", tracer.defaultName + "-svg") 
                                        .attr("class", "svg-d3-table") 
                                        .attr("xmlns", "http://www.w3.org/2000/svg");

Thank you for your comments.

READ ALSO
Creating focus on element that&#39;s behind a different element

Creating focus on element that's behind a different element

allI'm a beginner trying to create my own website

335
How to wait for one function to execute before executing second function in microsoft bot framework?

How to wait for one function to execute before executing second function in microsoft bot framework?

I am calling a function which processes the user input message and then sends a response accordingly in microsoft bot framework's nodejs SDK

373
Google Maps Script error in Onion.js

Google Maps Script error in Onion.js

This morning I just started getting a google maps script error

464
How to move mail to junk folder - Thunderbird

How to move mail to junk folder - Thunderbird

I have some problem with move incoming email to junk folderI'm writing Thunderbird extension and I use function CopyMessage() from nsIMsgMessageService to move incoming mail to junk folder

369