How to append an svg to an prexisting svg using d3.js?

10,973

Your question is: "is it possible to append an SVG to an SVG using D3?" That object in the title is a bit misleading (However, if you're really talking about an <object> or even loading an external SVG, you're doing it wrong, and the following explanation would be useless. In that case, answers like this one will be more useful).

The answer is yes. For whatever reason you want to nest those SVGs (you probably don't need it), just use the append method as you would with any other element.

Here is a demo, have a look at the console: there is an SVG inside an SVG.

var svg = d3.select("body").append("svg");
svg.append("text")
  .attr("y", 20)
  .text("this text is in the outer SVG");
var innerSVG = svg.append("svg");
innerSVG.append("text")
  .attr("y", 50)
  .text("this text is in the inner SVG");

var mySVG = (new XMLSerializer()).serializeToString(svg.node());
console.log(mySVG)
<script src="https://d3js.org/d3.v4.min.js"></script>
Share:
10,973

Related videos on Youtube

luQ
Author by

luQ

Updated on June 04, 2022

Comments

  • luQ
    luQ almost 2 years

    is it possible to append another svg to a preexisting svg parent using d3.js?

    I know that its possible by using an 'svg:image'-attribute. But unfortunately then i am loosing full control about the inner svg-child.

    The regarding dom node gets created by d3 but is not rendered and as a result the page stays blank.

    Hope somebody can help, thx in advance :)

    Here's what I got:

    Html CSS

      #svg-main-wrapper {
        position: absolute;
        min-width: 100%;
        min-height: 100%;
        bottom: 0;
        padding: 0;
        margin: 0;
      }
      
      
      <div id="svg-main-wrapper">
        <div svg-container svg-src="svgContainer[0].url" position="svgContainer[0].position">
        </div>    
      </div>

    Javascript

    angular.module('app', ['ui.bootstrap'])
      .directive('svgContainer', function() {
        return {
          restrict: 'A',
          template: function() {
            var parent = angular.element('body');
            return '<svg class="svg-container" width="' + parent.width() + '" height="' + parent.height() + '" viewBox=" 0 0 ' + parent.width() + ' ' + parent.height() + '"preserveAspectRatio ="xMinYMax meet"></svg>';
          },
          scope: {
            svgSrc: '=',
            position: '='
          },
          link: function(scope, element, attrs) {
    
            var parent = angular.element('#svg-main-wrapper');
    
            var x = 0;
            var y = parent.height() - 400;
    
            var svg = d3.select(element[0]);
            var g = svg.append('g');
    
            var innersvg = g.append('svg')
              .attr('xlink:href', scope.svgSrc)
              .attr('preserveAspectRatio', scope.position)
              .attr('width', parent.width())
              .attr('height', 400)
              .attr('transform', 'translate(' + x + ',' + y + ')');
    
          },
          replace: true
        };
      })
    
      .controller('ctrl', ['$scope', '$window', function($scope, $window) {
    
        $scope.svgContainer = [
          {
            id: 0,
            short_name: 'left',
            url: './images/complete.svg',
            position: 'none'
          }
          ];
      }]);

    • anbnyc
      anbnyc almost 7 years
      When you refer to the "svg:image" attribute, did you try using an image element -- g.append('image')? What was wrong with that approach?
    • luQ
      luQ almost 7 years
      The inner SVG element will be another complex SVG graphic. If it's just an image tag, iam not able to further manipulate it's child nodes
  • Gerardo Furtado
    Gerardo Furtado almost 7 years
    Are you going to draw that inner SVG or do you want to import it already made? In that last case, check the link in my answer.
  • Arun jai
    Arun jai about 5 years
    @GerardoFurtado the above code works. I want to append input checkbox. How to do that ?? Thanks in advance
  • Gerardo Furtado
    Gerardo Furtado about 5 years
    @Arunjai It's not clear what you want. Please post this as a new question, with all relevant details.
  • Arun jai
    Arun jai about 5 years
    Hi @GerardoFurtado, Like the above code appends text right like that I want to append checkbox. how to do that. if this is not clear I will post a new question.
  • Gerardo Furtado
    Gerardo Furtado about 5 years
    @Arunjai It's very different. Besides that, I cannot answer a question in the comments section, so please post it as a new question.