Home > Software design >  Displaying a circle inside an SVG with D3.js
Displaying a circle inside an SVG with D3.js

Time:11-16

I have come so far as the following, in my Angular app. However, the circle does not get drawn on the 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:

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

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

svg {
    position: absolute;
    top: 0;
    left: 0;
}

I only get the "Zoom Pan" and an empty area... What am I missing?

CodePudding user response:

When using angular, I suggest you ditch the D3 selectors and just use angular. Angular already has DOM manipulation markup so you don't need to use D3 to do it.

// 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>
      

CodePudding user response:

If you're not setting the svg height and width in pixels, in my experience, you need to use a viewBox.

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