简体   繁体   English

使用 D3.js 在 SVG 内显示一个圆圈

[英]Displaying a circle inside an SVG with D3.js

I have come so far as the following, in my Angular app.在我的 Angular 应用程序中,我已经做到了以下几点。 However, the circle does not get drawn on the svg .但是,圆圈​​不会绘制在svg What am I doing wrong that the circle does not show?我做错了什么,圆圈没有显示?

  svg: any;
  margin = 50;
  width = 350 - (this.margin * 2);
  height = 300 - (this.margin * 2);

  ngOnInit(): void {
    this.createSvg();
    this.createCircle();
  }

  createSvg(): void {
    this.svg = d3
      .select("figure#zoom-pan")
      .append("svg")
      .attr("width", "100%")
      .attr("height", "100%")
      .append("g")
      .attr("transform", "translate(" + this.margin + "," + this.margin + ")");
  }

  createCircle(): void {
      this.svg
        .append("circle")
        .attr("cx", document.body.clientWidth / 2)
        .attr("cy", document.body.clientHeight / 2)
        .attr("r", 50)
        .style("fill", "#B8DEE6")
  }

  ngAfterViewInit() {
    let svg = d3
      .select("svg")
      .call(d3.zoom().on("zoom", (event) => {
        svg.attr("transform", event.transform);
      }))
      .append("g");
  }

My html template and css code are quite simple:我的html模板和css代码非常简单:

<h3 class="center">Zoom Pan</h3>
<figure id="zoom-pan" class="center"></figure>
<ng-content></ng-content>

.center {
    display: flex;
    justify-content: center;
}

figure#zoom-pan {
    margin: 0;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

I only get the "Zoom Pan" and an empty area... What am I missing?我只得到“Zoom Pan”和一个空白区域......我错过了什么?

When using angular, I suggest you ditch the D3 selectors and just use angular.使用 angular 时,我建议您放弃 D3 选择器而只使用 angular。 Angular already has DOM manipulation markup so you don't need to use D3 to do it. Angular 已经有 DOM 操作标记,所以你不需要使用 D3 来完成它。

// component
createCircle() { 
  this.circle = {
    cx: document.body.clientWidth / 2,
    cx: document.body.clientHeight / 2,
    r: 50
  }
}

// component template
<figure>
  <svg
    [height]="height + (margin * 2)"
    [width]="width + (margin * 2)"
  >
    <g [attr.transform]="'translate(' + margin + ',' + margin + ')">
      <circle *ngIf="circle"
        [attr.cx]="circle.cx"
        [attr.cy]="circle.cx"
        [attr.r]="circle.r" />
    </g>
  </svg>
</figure>
      

If you're not setting the svg height and width in pixels, in my experience, you need to use a viewBox.如果您没有以像素为单位设置 svg 高度和宽度,根据我的经验,您需要使用 viewBox。

this.svg = d3
  .select("figure#zoom-pan")
  .append("svg")
  .attr("width", "100%")
  .attr("height", "100%")
  .attr("viewBox", "0 0 " + this.width + " " + this.height)

I made a working example of this code, displaying the circle.我制作了此代码的一个工作示例,显示了圆圈。 First of all it needs to be a class and a angular component.首先它需要是一个类和一个角度组件。

Check out the working example at stackblitz 在 stackblitz 查看工作示例

This is the typescript for the component:这是组件的打字稿:

import { Component, OnInit } from '@angular/core';
import * as d3 from 'd3';

@Component({
  selector: "ng-content",
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit  {
  svg: any;
  margin = 50;
  width = 350 - this.margin * 2;
  height = 300 - this.margin * 2;

  ngOnInit(): void {
    this.createSvg();
    this.createCircle();
  }

  createSvg(): void {
    this.svg = d3
      .select("figure#zoom-pan")
      .append("svg")
      .attr("width", "100%")
      .attr("height", "100%")
      .append("g")
      .attr("transform", "translate(" + this.margin + "," + this.margin + ")");
  }

  createCircle(): void {
    this.svg
      .append("circle")
      .attr("cx", document.body.clientWidth / 2)
      .attr("cy", document.body.clientHeight / 2)
      .attr("r", 50)
      .style("fill", "#B8DEE6");
  }

  ngAfterViewInit() {
    let svg = d3
      .select("svg")
      .call(
        d3.zoom().on("zoom", (event) => {
          svg.attr("transform", event.transform);
        })
      )
      .append("g");

  }
}

And the template:和模板:

<h3 class="center">Zoom Pan</h3>
<figure id="zoom-pan" class="center"></figure>

I suggest to provide always a minimal working example .我建议始终提供一个最小的工作示例

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

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