Renderer2在使用d3 js时无法渲染SVG元素 - Angular 4。

8

在查看以下链接后

使用D3.js和Angular 2

我明白我们不应该直接操纵DOM。因此,我开始研究如何使用Angular 4的Renderer2。

于是我开始编写一些代码将svg添加到DOM中。以下是我的代码片段。

HTML代码

<div class="row">
 <div class="col-12">
   <div #myBarGraph id="host"></div>
 </div>
</div>

Component.ts

export class BarGraphComponent implements OnInit {
 host:any;
 svg:any;
 @ViewChild('myBarGraph') myBarGraph:ElementRef;

 constructor(private renderer:Renderer2) { }

 ngOnInit() {
  //some logic
 }

 // called on some drop down selection
 teamSelection(){
  //some logic
   this.host = this.mybarGraph.nativeElement;
   buildSVG();
 }

 buildSVG():void {
   this.svg = this.renderer.createElement('svg');
   this.renderer.setAttribute(this.svg,'width','600');
   this.renderer.setAttribute(this.svg,'height','400');
   this.renderer.setAttribute(this.svg,'background-color','blue');
   this.renderer.appendChild(this.host,this.svg); 
 }
}

上面的代码能够将svg元素添加到DOM中。但令我惊讶的是,它实际上没有显示出svg元素!
我确实参考了以下问题:
  1. Angular2渲染器:Svg矩形已呈现但未在页面上显示
  2. Angular2在运行时不呈现SVG
但目前为止还没有找到合适的答案。
以下是问题的截图 problem 正如你在上面看到的,svg存在于DOM中,但它没有显示在网页中。任何帮助都将不胜感激。
2个回答

15

this.renderer.createElement('svg', 'svg') 创建的是 HTML 元素而不是 SVGElement,因为 Angular 不知道你想要的是 svg:svg。

尝试使用 this.renderer.createElement('svg', 'svg'),其中第二个参数是命名空间。每个 svg 元素都必须以相同的方式创建,例如:

let rect = this.renderer.createElement('rect', 'svg')
this.renderer.appendChild(svg, rect)

0

您已经正确地向视图中添加了一个具有高度和宽度的svg元素。但是,svg元素没有background-color属性。您可以将其视为画布,在其上叠加具有形状和颜色的其他元素。

您需要向此视图添加另一个元素才能看到任何内容。从svg中删除background-color属性,然后,由于您已将svg元素添加到视图中,因此可以使用d3向视图添加一个矩形:

d3.select(this.svg)
  .append('rect')
  .attr('x', 0)
  .attr('y', 0)
  .attr('width', 600)
  .attr('height', 400)
  .attr('fill', 'blue');

或者,您可以只需执行以下操作:

@Component({
  selector: 'bar-chart',
  template: `
    <div class='bar-chart' #barChart></div>
  `
})
export class BarChartComponent implements OnInit {

  @ViewChild('barChart')
  public chart: ElementRef;

  public svg: any;

  private width: number = 600;
  private height: number = 400;

  ngOnInit() {
    this.svg = d3.select(this.chart.nativeElement)
      .append('svg')
      .attr('width', this.width)
      .attr('height', this.height);

    this.svg
      .append('rect')
      .attr('x', 0)
      .attr('y', 0)
      .attr('width', this.width)
      .attr('height', this.height)
      .attr('fill', 'blue');
  }
}

感谢您为回答这个问题所做的努力,是的,我已经看到SVG元素具有background-color样式属性的示例。另外,我忘记提到我确实通过您发布的替代方法来显示SVG。但是,如果您按照我在问题中描述的第一个链接,他们建议使用渲染器而不是直接将SVG绑定到DOM。 - Srinivas Valekar
@SrinivasValekar,有一些带有背景颜色样式的SVG元素示例,但我认为这不是一个好的做法,因为它并不被所有浏览器普遍支持。 - lemmingworks
@SrinivasValekar 我已经阅读了这些链接,但我的观点是,在某个阶段,您必须使用d3与DOM进行交互。我没有看到使用Renderer2添加初始svg元素,然后使用d3与DOM进行交互的任何优势,而不是使用d3将svg添加到nativeElement公开的DOM中。 - lemmingworks
你实际上不需要d3来与DOM交互,因为你已经有了Angular。这个想法是使用d3进行数学计算,而使用Angular进行渲染和交互。 - mvnukov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接