D3 with Y-axis flipped

After creating a bar plot, I noticed that my Y axis is reversed and the scale seems off. I've been struggling to figure it out on my own. Here's a link to the Jsfiddle with the code.

If you want to give it a shot somewhere else, here is the code:

var w = 700;
var h = 400;
var margin = 40;

var dataset = [
{key:1,value:4000},
{key:2,value:3500},
{key:3,value:4400},
{key:4,value:3250},
{key:5,value:4785},
{key:6,value:3600},
{key:7,value:3200}
];


var key = function(d) {
    return d.key;
};

var value = function(d) {
    return d.value;
};
console.log(dataset);

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

var xScale = d3.scale.ordinal()
                .domain(d3.range(dataset.length+1))
                .rangeRoundBands([40, w], 0.05); 

var yScale = d3.scale.linear()
                     .domain([0, 5000])
                     .range([0, h-40]);
                
var x_axis = d3.svg.axis().scale(xScale);
var y_axis = d3.svg.axis().scale(yScale).orient("left");


d3.select("svg")
    .append("g")
        .attr("class","x axis")
        .attr("transform","translate(0,"+(h-margin)+")")
    .call(x_axis);
        
d3.select("svg")
    .append("g")
        .attr("class","y axis")
        .attr("transform","translate("+margin+",0)")
    .call(y_axis);
    
//Create bars
svg.selectAll("rect")
   .data(dataset, key)
   .enter()
   .append("rect")
   .attr("x", function(d, i) {
        return xScale(i);
   })
   .attr("y", function(d) {
        return h - yScale(d.value);
   })
   .attr("width", xScale.rangeBand())
   .attr("height", function(d) {
        return yScale(d.value)-margin;
   })
   .attr("fill", function(d) {
        return "rgb(96, 0, " + (d.value * 10) + ")";
   })

    //Tooltip
.on("mouseover", function(d) {
    //Get this bar's x/y values, then augment for the tooltip
    var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2;
    var yPosition = parseFloat(d3.select(this).attr("y")) + 14;
    
    //Update Tooltip Position & value
    d3.select("#tooltip")
        .style("left", xPosition + "px")
        .style("top", yPosition + "px")
        .select("#value")
        .text(d.value);
    d3.select("#tooltip").classed("hidden", false)
})
.on("mouseout", function() {
    //Remove the tooltip
    d3.select("#tooltip").classed("hidden", true);
})  ;

//Create labels
svg.selectAll("text")
   .data(dataset, key)
   .enter()
   .append("text")
   .text(function(d) {
        return d.value;
   })
   .attr("text-anchor", "middle")
   .attr("x", function(d, i) {
        return xScale(i) + xScale.rangeBand() / 2;
   })
   .attr("y", function(d) {
        return h - yScale(d.value) + 14;
   })
   .attr("font-family", "sans-serif") 
   .attr("font-size", "11px")
   .attr("fill", "white");

Answer №1

Perhaps this solution will be beneficial to you.

http://jsfiddle.net/T742n/8/

Here are a few key points:

  1. I adjusted the y domain range in your code from .range([0, h-margin]); to .range([h-margin, 0]); This change resolves the issue of the y-axis marks moving in the wrong direction, as web browsers consider the origin point (0,0) to be at the top-left corner instead of the bottom-left corner as in mathematics.

  2. As a result of this modification, I also made adjustments to your .attr('height') and .attr('y').

  3. A helpful technique for determining the height of a bar in a bar chart is recognizing that yscale(0) provides the pixel-position of the bottom of the bar chart. By calculating yscale(value) - yscale(0), you can obtain the pixel-height of your bars.

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

Rails inspired tag selection tool akin to Stack Overflow

In my Rails application, I am looking to implement a tagging system for models. I want to create a tag selection feature similar to Stack Overflow where I can type in a tag like 'rails' and a drop-down list of options containing that tag will app ...

Modifying attributes of an object within a document using Mongoose

Encountering an issue where the sentiment object in my document is not updating. Within my Model Class, there's a field named sentiment of type Object structured like this: sentiment: { terrible: 0, bad: 0, okay: 0, good: 0, fantastic: 0 } ...

What is the best way to insert a button at the end of the last row in the first column and also at the

I am working on a JavaScript project that involves creating a table. My goal is to dynamically add buttons after the last row of the first column and also at the top of the last column. for (var i = 0; i < responseData.length; i++) { fo ...

What is causing the unexpected behavior in this Vue transformation?

I am currently attempting to implement a simple slide panel using Vue.js, similar to the one shown in this example website: . However, I am facing an issue where the panel does not slide; instead, it waits for 2 seconds and then closes without any animatio ...

I experienced an issue with Firestore where updating just one data field in a document caused all the other data to be wiped out and replaced with empty Strings

When updating data in my Firestore document, I find myself inputting each individual piece of data. If I try to edit the tag number, it ends up overwriting the contract number with an empty string, and vice versa. This issue seems to stem from the way th ...

Set up a Google Map that is added dynamically

I have developed a form with a Google Map that utilizes 'places autocomplete'. I also added a button on the same page to add another location, which creates another map-canvas div. However, when attempting to initialize another instance of the ma ...

Execute the function when the element comes into view

Is there a way to create a function that will automatically attach itself to an element when it comes into view? I have multiple elements on my page - element1, element2, and element3. Instead of using a large if statement, I would like to write a functio ...

Make the card change to gray when clicked using Bootstrap

Is it possible to achieve a common function in an infinite list using HTML, CSS, JS, jQuery (on the user's side) where an item will be grayed out after being clicked? How can we implement this effect? 1.) When the user clicks on the card element htt ...

The process of setting up React in the terminal becomes tricky when the VS code editor is directing to a non-existent path

Issue with VS Code editor not recognizing existing path Recently attempted to install React using the npx command in the terminal, following steps from various tutorials on YouTube. Despite trying all suggested methods, the installation didn't succee ...

Reverse key-value pairs within a nested object using JavaScript

There is a specific object that I am working with: { "images": [ { "key": "ASDV1-01.jpg", "image_location": "image1.jpg", "data": { "documentid": "CE ...

The attempt to load a JavaScript resource has resulted in an error: the file was not located, despite the fact that it is a

Recently, I came across a new challenge in my application. Whenever I navigate to specific pages, I notice an error message in the development console: inject.preload.js:373 GET blob:http://my-app-name.test/ba65127c-383e-45b7-8159-9b52ea288658 0 () Upon ...

What are the best ways to incorporate a theme into your ReactJS project?

Looking to create a context for applying dark or light themes in repositories without the need for any manual theme change buttons. The goal is to simply set the theme and leave it as is. Currently, I have a context setup like this: import { createContext ...

Stop Cross-Site Scripting Attacks by Sanitizing jQuery html()

After retrieving data from a database through ajax, I merge it with HTML code on the website using the .html() jQuery function. The process looks like this: $.ajax({ url: "getDatabaseData.php", type: "post", dataType: "json", success: func ...

A guide on updating data with Vue-SweetAlert2 by passing user input

I'm currently working on creating a "create" button that will prompt a popup with a text input field for the user, similar to the image below. https://i.sstatic.net/eP7ki.png The expected behavior is that when the OK button is clicked, the name ente ...

What is the process for generating an auto-incrementing button with a *different input field*?

After searching everywhere for a code snippet to add another input bootstrap input group, I finally decided to take matters into my own hands and create one from scratch. And would you believe it worked like a charm! ...

Angular.js, Yeoman, and Grunt are essential tools for front-end

I've been working on developing an AngularJS application using Yeoman. Everything was going smoothly until I decided to implement some unit tests. Whenever I try to run my unit tests using grunt, I keep encountering the following error: Warning: Tas ...

Is there a way to access request or response objects in express.Js from any location?

Within an express.Js application, I aim to create a controller class responsible for managing the request and response for various other controllers. This includes tasks such as adding data to locals in the res object or deleting data from req.session. I ...

Guide to Making Colorful Text Inside Bootstrap 5 Tooltip

When trying to include the double quote character " in a custom HTML tooltip, it appears to cause the tooltip to malfunction. This results in the browser mistakenly treating the tooltip title as completed and interpreting a portion of the title as ext ...

Ways to invoke Java function using Javascript (Client-side)

I have a Java Swing application that handles the User Interface, but requires JavaScript files for hardware testing. The application calls a JavaScript engine to execute functions using the `InvokeFunction()` method. Currently, I am utilizing the LabJack ...

Is there an advantage to pre-compiling jade templates for production in an express environment?

Is it advantageous to have a middleware that pre-compiles all .jade views for production use, or does this happen automatically when NODE_ENV is set to 'production'? I am investigating ways to accelerate jade rendering for production purposes. ...