Using D3.js to generate a set quantity of elements

I am attempting to generate a specific number of elements using D3, extracting this information from a json file. Essentially, if the json data provided is n, I aim to display n elements within my svg.

This snippet showcases my code:

    // Setting up the dimensions of the svg element
    var w = 1000;
    var h = 50;

    // Establishing the dataset
    d3.json("people.json", function(dataset) {

    // Cycling through the json data
    for(var i=0; i<dataset.length; i++) {

                var svg = d3.select("body").append("svg")
                    .attr("width", w)
                    .attr("height", h);

            // Looping through the value
            for(var j=0; j<dataset[i].age; j++) {

                svg.selectAll("rect")
                        .data(dataset)
                        .enter()
                        .append("rect")
                        .attr("width", 20)
                        .attr("height", 20)
                        .attr("x", function(d, j) { return j * 55 })
            }

        }

    });

This represents an example of my json file (featuring arbitrary age values):

  [{
    "name": "Larry",
    "last": "Page",
    "country": "USA",
    "city": "Mountain View",
    "age": 32
  }, {
    "name": "Sergey",
    "last": "Bean",
    "country": "USA",
    "city": "Mountain View",
    "age": 37
  }, {
    "name": "Bill",
    "last": "Gates",
    "country": "USA",
    "city": "Seattle",
    "age": 60
  }, {
    "name": "Mark",
    "last": "Zuckemberg",
    "country": "USA",
    "city": "Palo Alto",
    "age": 35
  }, {
    "name": "Sergio",
    "last": "Marchionne",
    "country": "Italy",
    "city": "Milan",
    "age": 65
  }
]

The anticipated outcome should resemble the following ( [-] --> svg rectangle)

  1. Larry Page: [-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-]

  2. Sergey Bean: [-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-]

and so forth...

Could you assist me in identifying any errors in my approach?

Appreciate it!

Answer №1

To implement the pure D3 approach without using any for-loops, as suggested by Gerardo Furtado in his comment on Stack Overflow, you can follow this code snippet:

d3.select("body").selectAll("svg")
  .data(dataset)              // Bind the entire dataset
  .enter().append("svg")      // Append one svg per object in dataset
  .selectAll("rect")
    .data(function(d) {       // Inherit data from svg by mapping of objects
      // Create an array of number of required rects
      return d3.range(d.age).map(function(d) { return d*15; }); 
    })
    .enter().append("rect")   // Append rects per svg
      .attr("x", function(d) {
        return d;             // Calculate position based on mapped data
      });

This code snippet is sufficient to draw the desired graph (ignoring attributes). For a complete example with all values set, refer to the following code snippet:

var dataset =   [{
    "name": "Larry",
    "last": "Page",
    "country": "USA",
    "city": "Mountain View",
    "age": 32
  }, {
    "name": "Sergey",
    "last": "Bean",
    "country": "USA",
    "city": "Mountain View",
    "age": 37
  }, {
    "name": "Bill",
    "last": "Gates",
    "country": "USA",
    "city": "Seattle",
    "age": 60
  }, {
    "name": "Mark",
    "last": "Zuckemberg",
    "country": "USA",
    "city": "Palo Alto",
    "age": 35
  }, {
    "name": "Sergio",
    "last": "Marchionne",
    "country": "Italy",
    "city": "Milan",
    "age": 65
  }
];

// Setting the size of the svg element
var w = 1000;
var h = 50;

// Including the dataset
//d3.json("people.json", function(dataset) {

  d3.select("body")
    .selectAll("svg")
    .data(dataset)              // Bind the entire dataset
    .enter().append("svg")      // Append one svg per object in dataset
      .attr("width", w)
      .attr("height", h)
    .selectAll("rect")
      .data(function(d) {       // Inherit data from svg by mapping of objects
        // Create an array of number of required rects
        return d3.range(d.age).map(function(d) { return d*15; }); 
      })
      .enter().append("rect")   // Append rects per svg
        .attr("width", 10)
        .attr("height",10)
        .attr("x", function(d) {
          return d;             // Position was calculated in above mapping in data()
        });


//});
<script src="https://d3js.org/d3.v4.js"></script>

Answer №2

Here's a way to achieve it:

var dataset = [{
  "name": "John",
  "last": "Doe",
  "country": "USA",
  "city": "New York",
  "age": 45
}, {
  "name": "Jane",
  "last": "Smith",
  "country": "Canada",
  "city": "Toronto",
  "age": 30
}, {
  "name": "Michael",
  "last": "Johnson",
  "country": "UK",
  "city": "London",
  "age": 50
}];

// Setting up the svg element dimensions
var w = 800;
var h = 400;
var itemH = 15;
var itemW = 5;
var padding = 2;

// Append the svg element
var svg = d3.select("body").append("svg")
  .attr("width", w)
  .attr("height", h);

// Add groups for each data point in the dataset
var group = svg.selectAll("g")
  .data(dataset)
  .enter()
  .append('g');

// Iterate over each group
group.each(function(d, i) {

  var age = d.age;

  var self = d3.select(this);

  // Positioning the group vertically
  self.attr('transform', function() {
    return 'translate(0,' + (i * (itemH + padding)) + ')';
  });

  // Adding rectangles based on age
  d3.range(age).forEach(function(i) {
    self.append('rect')
      .attr('width', itemW)
      .attr('height', itemH)
      .attr('x', function() {
        return i * (itemW + padding);
      });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


<body></body>

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

Accessing a specific child div within a parent div using JavaScript and CSS

Struggling to target and modify the style of the child div within id="videoContainer" <div id="videoContainer"> <div style="width: 640px; height: 360px"> <------- this is the target <video src ...

Is there a way to use javascript to ensure that CSS variables stick even when overwritten by onclick events?

I have successfully implemented a method to change CSS variables using advice found here. However, I am running into an issue where the changes do not persist. After clicking on a navigation link, the styles momentarily switch to the new values but quickly ...

Issue with jsPDF: PNG file is either incomplete or corrupted

I'm encountering an issue while attempting to pass Image data to the addImage function. I have tried downgrading the versions of jspdf and html2canvas, as well as experimenting with different ways to import the two libraries, but the problem still per ...

Switching React Icons when Clicked

I'm struggling to understand this. I want the React icons below to be filled and remain filled when clicked, changing back to outlined when another is clicked. Here's the code: import { useState } from "react"; import { Link } from "react-router- ...

Using Jquery selectors along with variables to perform targeted search operations

I need assistance creating a JQuery selector that can automatically add an active class to a specific list item based on a variable. The variable sv will hold either 'dom-site' or 'int-site', which correspond to the id of a list item i ...

What is the process for validating dates using JavaScript?

I'm currently working on a birthday validation form using JavaScript and I'm facing some issues. For instance, the date 40/40/2012 should be considered invalid but no alert is being triggered. Here is the JavaScript code: function validateBirth ...

Having trouble retrieving accurate data in jQuery ajax post success when running on localhost with XAMPP

I am currently working on an ajax post using jQuery to send data to a php file and facing an issue with getting the correct data in the success function. Below are my code snippets: JAVASCRIPT $.ajax({ url: "ajax/chart-kpi-trend.php", data: { ...

Is there a way to incorporate an additional property into an existing JSON object within Azure Functions using C#?

In the Azure function, my input consists of ServiceBus queue properties The code is designed to retrieve all properties: using System.Net; using Newtonsoft.Json; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter ...

Executing Puppeteer on a Cloud Platform and Transferring Its Output to JavaScript

Running a puppeteer script on Heroku has been successful with buildpacks sorted out. However, the plan is to eventually move it to a personal server and run it on a 5-minute loop. The main issue faced is encountering a timeout (H12 error on Heroku) when it ...

.env file cannot be utilized in JavaScript

Currently, I am working on a project where both the front-end and server are located in one directory. I am using a .env file in the root directory, and the structure of the project looks like this: project frontend (directory) server (directory) .env (fi ...

Is there a way to utilize a cookie in order for the website to recognize that I have already agreed to the terms?

It's common for websites to ask for cookie and privacy acceptance upon loading, especially in the EU. I'm looking for a way to automatically accept these cookies so I don't have to constantly click "accept all" every time I open Chrome. My ...

Merging SCSS and CSS into a unified file using WebPack

Trying to grasp webpack as a beginner is proving to be quite challenging for me. I'm struggling with the concept of merging multiple scss and css files together using webpack, after transpiling the sass. Unlike gulp, where I could easily transpile sa ...

Is it possible for me to return a function reference as a response to an API call?

Is it possible to return a function reference or function as a response to an API call from an Express server when using AngularJS as the front-end framework? I attempted to send the response object like this: {per: true, listEvnts: events} where events i ...

Is it possible to turn off GPU rasterization for a particular SVG element in Google Chrome?

There is a peculiar issue with the SVG graphic displayed on my webpage. On some computers, the complex linearGradient filling a Rect does not display all the Stops correctly, while on other computers it appears fine. I discovered that if I disable "GPU ra ...

Display the URL with proper formatting in the print function

I am trying to create a table with clickable URLs in a "Link" column, but the URLs are too long and I want to show a custom title instead. So far, I have used the following code: str = "Test Title"; link = str.link("https://my_long_url.com/v1.0/ui/index. ...

What is the best approach to implementing a blur function for a specific input within a parent component?

I have created a custom input field as a separate component. I want to include multiple input fields in the parent component using directives: <app-input ...></app-input> My goal is to pass the blur event/function to the parent component speci ...

To toggle between two scope variables within a view when one is not defined

In my application, I am utilizing two scope variables: $scope.banner and $scope.defaultBanner. The banner is fetched using a service, but in cases where the banner file does not exist, the variable will be empty as the service returns nothing. My goal is ...

What could be the reason for the appearance of Next.js compile indicator in my final production build?

Upon completing the development and deployment of a Next.js website, I observed that the black compile indicator continued to appear in the bottom-right corner of my browser, similar to its presence during local development. The indicator can be viewed he ...

Update the value of a table cell with jQuery

I need assistance with changing the value of a td when a specific button is clicked. I have attempted various methods but none seem to be working. Ideally, I want the column to display only USD values when the "Show USD" button is clicked, and display on ...

Tips for refreshing a template with a click event

Problem Statement I currently have a piece of code that involves updating the results-box with a randomly chosen selection. I need to know how to modify the template when a @click event occurs. <template> <div class="container"> <but ...