Skip to content

Instantly share code, notes, and snippets.

@biovisualize
Last active September 9, 2021 16:57
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save biovisualize/373c6216b5634327099a to your computer and use it in GitHub Desktop.
Save biovisualize/373c6216b5634327099a to your computer and use it in GitHub Desktop.
d3.selection.appendHTML and appendSVG

Parse and append an HTML or SVG string. I use it a lot for appending a template, instead of generating it with d3.

d3.select('.container').appendHTML('<div><svg><g><rect width="50" height="50" /></g></svg></div>');

Unlike using .html, .appendHTML can append multiple elements

d3.select('.container').html('<span id="a"></span>');
d3.select('.container').html('<span id="b"></span>'); // will replace content
d3.select('.container').appendHTML('<span id="c"></span>'); // will append content

You can append HTML or SVG using the right method

var svg = d3.select('.container')
    .appendHTML('<svg xmlns="http://www.w3.org/2000/svg"><g><circle class="circle1" cx="50" cy="50" r="50"></circle></g></svg>')
    .select('g');

svg.appendSVG('<circle class="circle2" cx="20" cy="20" r="20"></circle>');
svg.appendSVG('<rect width="30" height="30"></rect>');

And it can be used with the enter/update/exit pattern

d3.select('.container').selectAll('div.test')
    .data([0, 1, 2])
  .enter().appendHTML('<div class="test"><p></p></div>')
    .select('p')
    .text(function(d){ return d; });
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.js"></script>
<style>
div, svg {
border: 1px solid silver;
margin: 10px;
}
rect {
fill: skyblue;
}
.circle1 {
fill: orange;
}
.circle2 {
fill: lime;
}
</style>
</head>
<body>
<div class="container"></div>
<script>
d3.selection.prototype.appendHTML =
d3.selection.enter.prototype.appendHTML = function(HTMLString) {
return this.select(function() {
return this.appendChild(document.importNode(new DOMParser().parseFromString(HTMLString, 'text/html').body.childNodes[0], true));
});
};
d3.selection.prototype.appendSVG =
d3.selection.enter.prototype.appendSVG = function(SVGString) {
return this.select(function() {
return this.appendChild(document.importNode(new DOMParser()
.parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + SVGString + '</svg>', 'application/xml').documentElement.firstChild, true));
});
};
d3.select('.container').appendHTML('<svg><g><rect width="50" height="50" /></g></svg>');
var svg = d3.select('.container')
.appendHTML('<svg xmlns="http://www.w3.org/2000/svg"><g><circle class="circle1" cx="50" cy="50" r="50"></circle></g></svg>')
.select('g');
svg.appendSVG('<circle class="circle2" cx="20" cy="20" r="20"></circle>');
svg.appendSVG('<rect width="30" height="30"></rect>');
</script>
</body>
</html>
@frbl
Copy link

frbl commented Oct 28, 2019

this helped me a lot, thanks!

@pdMa2s
Copy link

pdMa2s commented Dec 23, 2020

Is there any way to make this work with d3 version 6 ?

@sahibnasirov
Copy link

should be select(".class").append().html(string) or select(".class").insert().html(string)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment