How to Showcase a Circular Shape within an SVG Using D3.js

I've been working on my Angular app and have made some progress. However, I'm having trouble getting a circle to show up on the SVG. Can anyone help me figure out what I'm doing wrong?

  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");
  }

The HTML template and CSS code are simple:

<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;
}

Despite my efforts, all I see is "Zoom Pan" and a blank area. Any ideas on what's going wrong?

Answer №1

If you are working with Angular, it is recommended to avoid using D3 selectors and instead stick to Angular's built-in DOM manipulation features. Angular simplifies the process by providing its own markup for manipulating the DOM.

// component
createCircle() { 
  this.circle = {
    cx: document.body.clientWidth / 2,
    cy: 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.cy"
        [attr.r]="circle.r" />
    </g>
  </svg>
</figure>
      

Answer №2

In my personal experience, if you do not specify the height and width of an SVG in pixels, it is necessary to utilize 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)

Answer №3

Here is a functioning demonstration of the code, showcasing the circle in action. To begin with, it must be structured as a class and an angular component.

Explore the live example on stackblitz

This snippet shows 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");

  }
}

Additionally, here is the template associated with the component:

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

I highly recommend always including a minimal functional example.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Determining the state of a button based on a property's values

Is it possible to conditionally display a button based on the value of the sendSMS property of the logged-in user in AngularJS? How can I achieve this using ng-show in the HTML? I'm uncertain if I correctly assigned the value for the sendSMS property ...

Is there a way to access the HTML and CSS source code without using the inspect feature

I'm working on a project that involves an "edit box" where users can write text, add emojis, change the background color, insert images, and more. After users finish creating their content, I want them to be able to send it via email. This means I ne ...

What is the best way to optimize a search for objects with extensive field arrays?

Recently, I've been working with an object schema that includes an array field to store ids for objects from a separate collection. This array has the potential to contain thousands of ids. Up until now, I have been excluding this field using .select( ...

Dynamic menu bar accompanied by primary content

I'm facing an issue with my active navigation bar. Whenever I open the hamburger menu, the main content remains fixed and does not move along with the open navigation menu. I tried searching online for a solution but couldn't find anything helpfu ...

Creating an array based on specific conditions being satisfied (Using Javascript)

I am struggling with a coding problem involving adding users to groups. The goal is to add each user to a group array, with a maximum of 3 users per group. If a group reaches 3 users, it should be moved to another array that collects all the groups. I then ...

What is the solution for getting rid of the "clear sort" state in an angular-ui-grid column header?

I am looking for information on how to remove the default behavior where the 3rd click disables sort and stays "neutral" on sortable headers. Having a disable sort state seems flawed as it does not change the sort order. How can I eliminate the 3rd state ...

What's causing the member to be undefined?

client.on('raw', (e) => { if (e.t === 'MESSAGE_REACTION_ADD' && e.d.message_id === '813150433651851265' && e.d.emoji.name === "✅" ) { const guild = client.guilds.cache.get(e.d.gui ...

Updating An Angular Application from version 11 to version 12 Challenge

Once I completed installing all the required dependencies as per: https://update.angular.io/ I executed the command 'ng serve' in the terminal and encountered the following errors: ./node_modules/leaflet/dist/images/marker-icon.png:1:0 - Error: ...

changing the core JavaScript of a keyboard plugin

To access the demo, click on this link: . You can find the main javascript file at https://raw.githubusercontent.com/Mottie/Keyboard/master/js/jquery.keyboard.js. Is there a way to switch the positions of the accept and cancel buttons? ...

Steps to set up datetimepicker with varying date ranges for several input fields

I am having trouble getting a new date range for each text box in my form. It seems to only return the date range from the last textbox, even though I have made the textbox IDs dynamic. I have both start and end dates for each textbox and I have calculated ...

Chrome Developer Tools - Array Length Discrepancies

While exploring Chrome DevTools, I came across an inconsistency that caught my attention. The screenshot above shows the issue I encountered. Initially, it indicated that the object contained a Body and a Head, with the head being an array of length 1. Ho ...

Documenting React Native Components: Best Practices and Tips

How can I add comments to a React Component? import React, { useState } from 'react'; import { Text, TextInput, View } from 'react-native'; import PropTypes from "prop-types"; const PizzaTranslator = ({ pizzaEmoji = ' ...

Convert a string with the characters '"' retrieved from a MySQL database into JSON

After creating a JSON object and storing it in MySQL, I encountered an issue when trying to retrieve and parse it. When I stringify the JSON object, the properties are being enclosed in double quotes causing issues when parsing the retrieved string. Below ...

Discovering the closest date among the elements in an array

Currently, I am facing an issue while trying to identify the highest date within an array of objects which have varying dates assigned to each one. The code seems to be functioning well when the dates are above January 1st, 1970, however, any date prior to ...

Steps to modify the ShapeGeometry in three.js

As a beginner in three.js, I encountered an issue where updating a ShapeGeometry wasn't working as expected. This resulted in me having to remove and re-add the ShapeMesh every time. this.mesh.geometry.dispose() this.mesh.material.dispose() ...

Setting the value for a textbox using Jquery's .val() function works, while .attr() does not have the

//unable to get it working $("#TextBoxID1").attr("value","HI Value Change") //works perfectly fine $("#TextBoxID2").val("HI Value Change") <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script> <input type= ...

How to modify the appearance of the md-tab-header component in Angular2

Currently, I am working on a project that was passed down to me by a former colleague. It is a gradual process of discovery as I try to address and resolve any issues it may have. One particular element in the project is a md-tab-header with a .mat-tab-he ...

Preventing a page refresh in Angular 2 on an ASPX page: Strategies for success

The use of the pagemethod is successful, but I encountered an issue with the webmethod causing the page to refresh, which defeats the purpose of using Angular 2. Is there a way to prevent the form from refreshing the page? index.aspx <body> &l ...

Discovering the significance of a JavaScript object within a collection

Greetings! I am a newcomer to the world of JavaScript and could really use some assistance with a specific issue that I'm currently facing. Essentially, I have an array that is storing objects, each of which has an id and a variable i which is a numb ...

Manipulate sibling elements using jQuery's addClass and remove methods

I have implemented a function that adds the class active to elements when they reach the top of the browser, ensuring that the next element will scroll in over the top. While this works smoothly in Chrome, I am encountering some jumping behavior when testi ...