Colorful D3.js heatmap display

Hello, I am currently working on incorporating a color scale into my heat map using the d3.schemeRdYlBu color scheme. However, I am facing challenges in getting it to work properly as it only displays black at the moment. While I have also implemented a hover feature, my main focus is on making the colors appear correctly. I aim to have lower numbers displayed in blue and higher numbers in red to indicate temperature variations.

<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div for the visualization -->
<div id="my_dataviz"></div>

<!-- Load necessary libraries for color palettes -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>

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

// Define dimensions and margins of the graph
var margin = {top: 80, right: 25, bottom: 30, left: 40},
  width = 1000 - margin.left - margin.right,
  height = 1000 - margin.top - margin.bottom;

// Append an SVG element to display the graph
var svg = d3.select("#my_dataviz")
.append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
.append("g")
  .attr("transform",
        "translate(" + margin.left + "," + margin.top + ")");

// Read the data from a CSV file
d3.csv("https://raw.githubusercontent.com/Nataliemcg18/Data/master/NASA_Surface_Temperature.csv", function(data) {

  // Generate unique identifiers for rows and columns
  var myGroups = d3.map(data, function(d){return d.group;}).keys()
  var myVars = d3.map(data, function(d){return d.variable;}).keys()

  // Create X scales and axis:
  var x = d3.scaleBand()
    .range([ 0, width ])
    .domain(myGroups)
    .padding(0.05);
  svg.append("g")
    .style("font-size", 15)
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x).tickSize(0))
    .select(".domain").remove()

  // Create Y scales and axis:
  var y = d3.scaleBand()
    .range([ height, 0 ])
    .domain(myVars)
    .padding(0.05);
  svg.append("g")
    .style("font-size", 15)
    .call(d3.axisLeft(y).tickSize(0))
    .select(".domain").remove()

  // Define color scale using RdYlBu color scheme
  var myColor = (d3.schemeRdYlBu[2])

  ...

</script>

Answer №1

Utilizing arrow functions instead of traditional functions allows you to establish your own binding for accessing the myColor variable.

<!DOCTYPE html>
<meta charset="utf-8" />

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<!-- Load color palettes -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>

<script src="https://d3js.org/d3.v4.js"></script>
<script>
  // define graph dimensions and margins
  var margin = { top: 80, right: 25, bottom: 30, left: 40 },
    width = 1000 - margin.left - margin.right,
    height = 1000 - margin.top - margin.bottom;

  // append svg object to the page
  var svg = d3
    .select("#my_dataviz")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  //Read the data
  d3.csv(
    "https://raw.githubusercontent.com/Nataliemcg18/Data/master/NASA_Surface_Temperature.csv",
    function (data) {
      // Extract unique group and variable identifiers from data
      var myGroups = d3
        .map(data, function (d) {
          return d.group;
        })
        .keys();
      var myVars = d3
        .map(data, function (d) {
          return d.variable;
        })
        .keys();

      // Build X scales and axis:
      var x = d3.scaleBand().range([0, width]).domain(myGroups).padding(0.05);
      svg
        .append("g")
        .style("font-size", 15)
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x).tickSize(0))
        .select(".domain")
        .remove();

      // Build Y scales and axis:
      var y = d3.scaleBand().range([height, 0]).domain(myVars).padding(0.05);
      svg
        .append("g")
        .style("font-size", 15)
        .call(d3.axisLeft(y).tickSize(0))
        .select(".domain")
        .remove();

      // Establish color scale
      var myColor = d3.schemeRdYlBu[3][2];

      // create a tooltip
      var tooltip = d3
        .select("#my_dataviz")
        .append("div")
        .style("opacity", 0)
        .attr("class", "tooltip")
        .style("background-color", "white")
        .style("border", "solid")
        .style("border-width", "2px")
        .style("border-radius", "5px")
        .style("padding", "5px");

      // Functions for handling mouse events on cells
      var mouseover = function (d) {
        tooltip.style("opacity", 1);
        d3.select(this).style("stroke", "green").style("opacity", 1);
      };
      var mousemove = function (d) {
        tooltip
          .html("The exact value of this cell is: " + d.value)
          .style("left", d3.mouse(this)[0] + 70 + "px")
          .style("top", d3.mouse(this)[1] + "px");
      };
      var mouseleave = function (d) {
        tooltip.style("opacity", 0);
        d3.select(this).style("stroke", "none").style("opacity", 0.8);
      };

      // Add rectangles representing data
      svg
        .selectAll()
        .data(data, function (d) {
          return d.group + ":" + d.variable;
        })
        .enter()
        .append("rect")
        .attr("x", function (d) {
          return x(d.group);
        })
        .attr("y", function (d) {
          return y(d.variable);
        })
        .attr("rx", 4)
        .attr("ry", 4)
        .attr("width", x.bandwidth())
        .attr("height", y.bandwidth())
        .style("fill", (d) => {
          return myColor;
        })
        .style("stroke-width", 4)
        .style("stroke", "none")
        .style("opacity", 0.8)
        .on("mouseover", mouseover)
        .on("mousemove", mousemove)
        .on("mouseleave", mouseleave);
    }
  );

  // Add title to graph
  svg
    .append("text")
    .attr("x", 0)
    .attr("y", -50)
    .attr("text-anchor", "left")
    .style("font-size", "22px")
    .text("A d3.js heatmap");

  // Add subtitle to graph
  svg
    .append("text")
    .attr("x", 0)
    .attr("y", -20)
    .attr("text-anchor", "left")
    .style("font-size", "14px")
    .style("fill", "grey")
    .style("max-width", 400)
    .text("A short description of the take-away message of this chart.");
</script>

Answer №2

Here is an alternative method to achieve the intended outcomes

    let customScale = d3.scaleLinear()
        .range(["blue", "red"])
        .domain([10, 100])

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 is the best way to utilize the `Headers` iterator within a web browser?

Currently, I am attempting to utilize the Headers iterator as per the guidelines outlined in the Iterator documentation. let done = false while ( ! done ) { let result = headers.entries() if ( result.value ) { console.log(`yaay`) } ...

Importing Laravel select2 library is necessary for enhancing user experience and improving

I've been attempting to incorporate select2 into my project without success. Every time I try these two methods, I always receive an error saying $('#state').select2 is not a function. However, when I include select2 in a standard <scrip ...

Can you explain the inner workings of the sort function in JavaScript, including how it utilizes the compare

I'm curious about how the sort function operates in JavaScript, specifically in conjunction with the compare function. According to what I've read, if you have an array and use the code array.sort(compare), it's stated that if the compare fu ...

What is the best method for efficiently wrapping contents within a div container?

On the website cjshayward.com/index_new.html, there is a div wrapped around the content of the body, which is approximately 1000 pixels wide. In Chrome and Firefox, the wrapper works perfectly for the top section of about 100 pixels. Further down the page, ...

Troubleshooting CSS Display Problem on Chrome and Firefox

While working on the design of a website offline, everything seemed to be running smoothly. However, upon uploading it to the server, various issues began to arise. Initially, the file loaded correctly upon first visit. Unfortunately, after reloading the ...

How do I iterate through my state in React Redux?

Currently, I am delving into Redux by creating a to-do list in React. I have been pondering on the utilization of the map function to iterate over the state so that I can display the data stored within different div elements. Here is my initial state: cons ...

Utilizing HTML documents instead of images in Owl Carousel 2

I am currently utilizing owl carousel 2 to construct a basic sliding carousel. However, I am only using images at the moment and would like to incorporate HTML files instead. These HTML files contain multiple divs where images can be inserted, and instead ...

Utilizing gradient effects on table backgrounds with html/css

Trying to enhance my responsive table by adding a gradient background, but encountering an issue where the style being applied is repeating in every cell, creating a messy look. Here's the gradient I'm using: background: linear-gradient(to right ...

AngularJS - Not binding $scope to the DOM

Recently starting out with Angular, I decided to practice by creating a simple website. One of the features I want to include is displaying the number of times a button has been clicked through data binding. Here's the controller code I've writte ...

Tips for determining the time and space complexity of this JavaScript code

Here are two codes utilized by my platform to establish relationships between nodes. code1 : const getNodeRelationship = (node1, node2) => { // if node1 and node2 are the same node if (node1 === node2) return null; // check direct parent ...

What causes the DOM's appendChild() to trigger on('load', ...) while jQuery's append() does not fire?

I have two snippets of code that I am working with: $(document).ready(function() { document.head.appendChild( $('<script />').attr('src', 'source.js').on('load', function() { ... ...

Upon clicking a table row, generate a div underneath containing mapped data

My dynamic table is currently being filled with rows based on an array, but I want to display more data in an expanded view when a button in a row is clicked. However, I'm facing challenges as it seems I can't have two table rows within the same ...

Creating TypeScript domain objects from JSON data received from a server within an Angular app

I am facing a common challenge in Angular / Typescript / JavaScript. I have created a simple class with fields and methods: class Rectangle { width: number; height: number; area(): number { return this.width * this.height; } } Next, I have a ...

angular-ui-tab-scroll: Odd spacing between blocks and tabs, each separated individually

Greetings! I would like to express my gratitude for this wonderful library! However, I am encountering an unusual issue when trying to wrap a tabset with tabs that are included separately. This can be done either by adding individual tab elements manually ...

Easily choose multiple items at once by searching with react-select

I have implemented react-select to showcase a searchable drop-down list of items where users can select multiple items. The list is lengthy, and users often find it tedious to multi-select many items that match the same filter string. This is because each ...

What methods can I employ to utilize preg_match with jQuery?

Is it possible to validate a phone number in jQuery using preg_match? I have tried the following code without success: if (!preg_match("/^[0-9]{3}-|\s[0-9]{3}-|\s[0-9]{4}$/", phone.val() )) { phone.addClass("needsfille ...

Creating a canvas that adjusts proportionally to different screen sizes

Currently, I am developing a pong game using Angular for the frontend, and the game is displayed inside an HTML canvas. Check out the HTML code below: <div style="height: 70%; width: 70%;" align="center"> <canvas id=&q ...

Tips for incorporating HTML code within a select option value?

I am working with AngularJS to create a Visual Composer for a website. One feature I want to incorporate is the ability to add HTML code based on the selection made in a dropdown menu. However, I am struggling to figure out how to include the HTML within t ...

When the click event is triggered, the second function guess() does not execute

I am currently developing a number guessing application. It consists of two functions, the first one called startGame() works correctly (it receives the maximum number and then disappears by adding the hidden class). However, the second function that is ...

What functionality does the --use-npm flag serve in the create-next-app command?

When starting a new NextJS project using the CLI, there's an option to use --use-npm when running the command npx create-next-app. If you run the command without any arguments (in interactive mode), this choice isn't provided. In the documentati ...