The horizontal bar graph is not aligned properly

My project involves creating a dynamic horizontal bar chart to display data from a CSV file. However, I've encountered an issue where an extra space appears without any corresponding data. I specifically want to only show the top 10 values (students) along with their respective keys (counties), but it seems like an additional entry is being included.

Upon closer inspection, it's evident that there is an unwanted space and a small rectangle at the top of the chart. My goal is to eliminate both of these elements for a cleaner presentation.

    // Parsing the Data
    d3.csv("FA18_geographic.csv", function(data) {  

        data.sort(function(a,b) {
          return d3.descending(+a.students, +b.students);
        });


        // Finding the Maximum Student Count by County
        var max = d3.max(data, function(d) { return +d.students;} );

        var map = d3.map(data, function(d){return d.students; });
        pmax = map.get(max);



        // Adding the X axis
        var x = d3.scaleLinear()
        .domain([0, +pmax.students+500])
        .range([ 0, width]);
        svg.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x))
        .selectAll("text")
          .attr("transform", "translate(-10,0)rotate(-45)")
          .style("text-anchor", "end");


        // Setting up the Y axis
        var count = 0
        var y = d3.scaleBand()
        .range([ 0, height ])
        .domain(
            data.map(function(d) { // Displaying only the top 10 counties
                count = count+1
                if (count<=10){
                return d.county;
             }})
            )
        .padding(.3);
        svg.append("g")
        .call(d3.axisLeft(y));



        // Generating the Bars                      // There might be an issue here???
        svg.selectAll("rect.bar")
        .data(data)
        .enter()
        .append("rect")
        .attr("x", x(0) )
        .attr("y", function(d) { return y(d.county); })
        .attr("width", function(d) { return x(d.students); })
        .attr("height", y.bandwidth() )
        .attr("fill", "#79200D");

    });

</script>

Answer №1

The root of the issue lies within this code snippet:

.domain(data.map(function(d) { //only show top 10 counties
    count = count + 1
    if (count <= 10) {
        return d.county;
    }
}))

The problem is not related to D3, but rather a JavaScript limitation: you cannot skip iterations using Array.prototype.map.

To illustrate this, let's look at a simple example where we attempt to return items only if count is less than 5:

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let count = -1;

const domain = data.map(function(d) {
  count += 1;
  if (count < 5) {
    return d
  };
});

console.log(domain)

As evident, multiple values are returned as undefined. The single empty tick in the visualization occurs because D3 band scale treats all those values as a singular undefined (band scales require unique domain values).

There are various solutions available. One option is to utilize Array.prototype.reduce:

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let count = -1;

const domain = data.reduce(function(acc, curr) {
  count += 1;
  if (count < 5) {
    acc.push(curr)
  };
  return acc;
}, []);

console.log(domain)

Alternatively, you can incorporate a filter after the initial map, or use a forEach loop to populate the array.

Lastly, some additional pointers:

  1. A separate count variable is unnecessary since Array.prototype.map provides an index parameter (the second argument), similar to Array.prototype.reduce (the third argument).
  2. Instead of count = count + 1, utilize count += 1 for more concise code;
  3. In JavaScript arrays, indexing starts at zero. To counteract this, initialize count as -1 instead of 0.

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

What steps can be taken to resolve an error message?

I needed to create an error message in a distinctive color using CSS when a user enters a letter instead of a number in a form. I successfully implemented this feature, however, I encountered an issue where the error message remains visible even after th ...

Modify the hash URL in the browser address bar while implementing smooth scrolling and include the active class

I have implemented a smooth scroll technique found here: https://css-tricks.com/snippets/jquery/smooth-scrolling/#comment-197181 $(function() { $('a[href*=#]:not([href=#])').click(function() { if (location.pathname.replac ...

The functionality of filtering a list based on the selected value from a drop-down menu is malfunctioning

When the page initially loads, there is a dropdown with the default placeholder "Select Person Type" and a checkbox list displaying all persons by default. An angular filter is used to display only the selected type of persons from the dropdown (working p ...

Is there a single code that can transform all standard forms into AJAX forms effortlessly?

When manipulating my 'login' form, I love using this code to submit it to the specified url and display the response in the designated id. The method of submission is defined as well. It's a great solution, but is there a way to streamline ...

Enhance the functionality of the custom transaction form in NetSuite by incorporating new actions

I'm currently working on incorporating a new menu option into the "Actions" menu within a custom transaction form in NetSuite. While I can successfully see my selection in the Actions Menu on the form, I'm running into an issue with triggering th ...

updating the name of an HTML element with jQuery

Encountering a problem with setting the class for each li in a group of li tags: function pathContents(fileList) { var $list = $('<ul/>'); $.each(fileList, function (_, file) { $('<li/>').prop('class', &apos ...

Executing functions on Angular scope within Underscore Template

Having an underscore template being invoked from an Angular controller, there is a dropdown in the template and an onchange function called on the dropdown. Despite several attempts to get the method triggered in the onchange event, using this code <se ...

Top spot for locating resolve functions in AngularJS

I'm currently in the process of setting up resolves for my admin panel routes and I'm pondering the best way to store them without cluttering my router with methods. Here's what I have so far: when('/admin', { templateUrl: &ap ...

Refreshing State in ReactJS

My problem involves resetting the errorText back to its original state. Each time the form is submitted with errors, it keeps adding all previous errors to the end. 1st interaction with a blank form "Errors: Email is invalid. Password is invalid." 2nd i ...

Utilize NodeJS to dynamically alter the text outputted on an HTML page

For educational purposes, I am designing a website where users can sign in by entering their name on the login page. After signing in, they will be redirected to the home page which displays a personalized welcome message using their name. I have included ...

The JQuery parseFloat() function seems to be consistently returning "NAN" whenever it is used with the .text property

I am currently encountering an issue with parsing the text property of an input element identified by the id currency-converter. My goal is to convert this text into a floating-point value so that I can proceed with applying mathematical operations to conv ...

Updates to Vue.js data are not being properly reflected in the template

This is my unique text <template> <div class="unique_class"> <div class="unique_wrapper"> <div v-for="(h, index) in heights" :key="index" class="each_bar" v-bind:style="{ height: h + 'px' }"></div> ...

Ways to implement modifications in child component through parent?

In my Angular application, I have a file upload feature where the file upload component is a child component and the app component serves as the parent component. The app.component.html (Parent) contains a single line of code that calls the child componen ...

Sorting JSON data in EJS based on categories

Hello, I am facing a dilemma. I need to apply category filtering to a JSON file but I am unsure of how to proceed with it. For instance, I wish to filter the 'vida' category along with its description and price. I seem to be stuck at this junctu ...

Tips for accessing JSON data stored as keys within a JavaScript object

I'm facing an issue with my Node.js lambda function that involves parsing JSON data received from an external application. The JSON data seems to be malformed and arrives as an object key, shown below: console.log(req.body) This results in: { &apo ...

How can I change the color of a cube in Three.js?

I'm currently working on developing a basic 3D game using three.js. My goal is to create colored cubes, but I'm encountering an issue where all the cubes are displaying the same color. My cube creation code looks like this: var geometry = new ...

Steps to open a URL link within a div without navigating away from the current page

I want to create an interactive icon that, when clicked, expands like a browser window. Inside this expanded div, I would like to display a URL that I provide. How can I accomplish loading a new URL within my original index.html without leaving the page or ...

Testing D3js functionality within a React component with the help of Jest and Enzyme

Issue: Upon running my code, the SVG successfully appends to the outer div on the component and displays on the page as expected. However, while testing, the SVG fails to append to the outer div. Technology Stack: I am currently attempting to test my d3js ...

Unable to scroll to the top of the page

Here is my code snippet - ($("div[id$='fixedDataDiv']")[0]).scrollTop(0); This piece of code gets executed when I switch tabs in Internet Explorer 8. An error message pops up saying - Microsoft JScript runtime error: Object doesn't sup ...

What is the best way to pass JavaScript object literals from a Node.js server to the frontend browser?

In Node, I am working with JavaScript object literals containing methods in the backend. For example: const report = { id: 1, title: 'Quarterly Report for Department 12345', abstract: 'This report shows the results of the sales ...