简体   繁体   English

如何使用d3.js将svg附加到prexisting svg?

[英]How to append an svg to an prexisting svg using d3.js?

is it possible to append another svg to a preexisting svg parent using d3.js? 是否可以使用d3.js将另一个svg附加到预先存在的svg父级?

I know that its possible by using an 'svg:image'-attribute. 我知道通过使用'svg:image'属性可以实现。 But unfortunately then i am loosing full control about the inner svg-child. 但不幸的是,我失去了对内部svg-child的完全控制。

The regarding dom node gets created by d3 but is not rendered and as a result the page stays blank. 关于dom节点由d3创建但不呈现,因此页面保持空白。

Hope somebody can help, thx in advance :) 希望有人可以提前帮助:)

Here's what I got: 这是我得到的:

Html CSS 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 使用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' } ]; }]); 

Your question is: "is it possible to append an SVG to an SVG using D3?" 您的问题是: “是否可以使用D3将SVG附加到SVG?” 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). 标题中的那个对象有点误导(但是,如果你真的在谈论一个<object>或甚至加载一个外部SVG,你做错了,以下解释就没用了。在这种情况下,答案像这样一个会更有用)。

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. 无论出于何种原因,您想要嵌套这些SVG(您可能不需要它),只需使用append方法,就像使用任何其他元素一样。

Here is a demo, have a look at the console: there is an SVG inside an SVG. 这是一个演示,看一下控制台:SVG里面有一个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> 

As you can see, our component will be code-driven, with nothing in the template except a div, which will serve as our container. 正如您所看到的,我们的组件将是代码驱动的,除了div之外,模板中没有任何内容,它将作为我们的容器。 The chart size will be inferred from the size of this element, which will be helpful in making the SVG react like a normal html node. 图表大小将从该元素的大小推断出来,这将有助于使SVG像普通的html节点一样做出反应。 Here is the main part of the code, the 'src/app/bar-chart/bar-chart.component.ts' file: 这是代码的主要部分,'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));
  }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM