如何使用d3.js将svg附加到一个现有的svg?

时间:2017-07-13 15:19:56

标签: javascript html angularjs d3.js svg

是否可以使用d3.js将另一个svg附加到预先存在的svg父级?

我知道可以使用'svg:image'属性。 但不幸的是,我失去了对内心svg孩子的完全控制。

关于dom节点由d3创建,但未呈现,因此页面保持空白。

希望有人可以提前帮忙:)

这是我得到的:

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'
      }
      ];
  }]);

2 个答案:

答案 0 :(得分:3)

您的问题是:&#34;是否可以使用D3将SVG附加到SVG?&#34; 标题中的对象有点误导(但是,如果您真的在谈论<object>或甚至加载外部SVG,那么您做错了,以下解释将毫无用处。在这种情况下,答案如{ {3}}会更有用。)

答案是肯定的。无论出于何种原因,您想要嵌套这些SVG(您可能不需要它),只需使用append方法,就像使用任何其他元素一样。

这是一个演示,看一下控制台:SVG中有一个SVG。

&#13;
&#13;
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)
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如您所见,我们的组件将是代码驱动的,模板中除div外没有任何内容,而div将用作我们的容器。图表大小将从此元素的大小推断出,这将有助于使SVG像普通html节点一样做出反应。这是代码的主要部分,即“ src / app / bar-chart / bar-chart.component.ts”文件:

 private createChart(): void {
    d3.select('svg').remove();
    const element = this.chartContainer.nativeElement;
    const data = this.data;
    const svg = d3.select(element).append('svg')
        .attr('width', element.offsetWidth)
        .attr('height', element.offsetHeight);
    const contentWidth = element.offsetWidth - this.margin.left - this.margin.right;
    const contentHeight = element.offsetHeight - this.margin.top - this.margin.bottom;
    const x = d3
      .scaleBand()
      .rangeRound([0, contentWidth])
      .padding(0.1)
      .domain(data.map(d => d.letter));
    const y = d3
      .scaleLinear()
      .rangeRound([contentHeight, 0])
      .domain([0, d3.max(data, d => d.frequency)]);
    const g = svg.append('g')
      .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
    g.append('g')
      .attr('class', 'axis axis--x')
      .attr('transform', 'translate(0,' + contentHeight + ')')
      .call(d3.axisBottom(x));
    g.append('g')
      .attr('class', 'axis axis--y')
      .call(d3.axisLeft(y).ticks(10, '%'))
      .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '0.71em')
        .attr('text-anchor', 'end')
        .text('Frequency');
    g.selectAll('.bar')
      .data(data)
      .enter().append('rect')
        .attr('class', 'bar')
        .attr('x', d => x(d.letter))
        .attr('y', d => y(d.frequency))
        .attr('width', x.bandwidth())
        .attr('height', d => contentHeight - y(d.frequency));
  }
}

链接网:https://tienanhvn.blogspot.com/2019/06/create-responsive-angular-d3-charts.html