Heatmap of the day's hours - Issue with displaying colors

I've been working on creating a d3.js heatmap chart, and I've encountered an issue with the colors. Initially, I used code from this link and then modified it to read data from a PHP file that outputs JSON format data. However, after making these modifications, the heatmap is displaying all grids in black color with some white spaces between them.

I am relatively new to d3 charts, so please forgive any minor mistakes you may come across in the code snippet below:

See image here

<!DOCTYPE html>
<meta charset="utf-8">
<html>
  <head>
    <style>
      rect.bordered {
        stroke: #E6E6E6;
        stroke-width:2px;   
      }

      text.mono {
        font-size: 9pt;
        font-family: Consolas, courier;
        fill: #aaa;
      }

      text.axis-workweek {
        fill: #000;
      }

      text.axis-worktime {
        fill: #000;
      }
    </style>
    <script src="http://d3js.org/d3.v3.js"></script>
  </head>
  <body>
    <div id="chart"></div>
    
    <script type="text/javascript">
      var margin = { top: 50, right: 0, bottom: 100, left: 30 },
          width = 960 - margin.left - margin.right,
          height = 430 - margin.top - margin.bottom,
          gridSize = Math.floor(width / 24),
          legendElementWidth = gridSize*2,
          buckets = 9,
          colors = ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"], // alternatively colorbrewer.YlGnBu[9]
          days = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
          times = ["1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a", "9a", "10a", "11a", "12a", "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p", "10p", "11p", "12p"];
         // datasets = ["data1.tsv", "data2.tsv"];
        

      d3.json("heatmaptry2.php", function(error, data) {


data.forEach(function(d) {
console.log(d);
day= +d.day; 
hour= +d.hour;
value= +d.value; 
});
  var colorScale = d3.scale.quantile();

      var svg = d3.select("#chart").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 + ")");

      var dayLabels = svg.selectAll(".dayLabel")
          .data(days)
          .enter().append("text")
            .text(function (d) { return d; })
            .attr("x", 0)
            .attr("y", function (d, i) { return i * gridSize; })
            .style("text-anchor", "end")
            .attr("transform", "translate(-5," + gridSize / 1.5 + ")")
            .attr("class", function (d, i) { return ((i >= 0 && i <= 4) ? "dayLabel mono axis axis-workweek" : "dayLabel mono axis"); });

      var timeLabels = svg.selectAll(".timeLabel")
          .data(times)
          .enter().append("text")
            .text(function(d) { return d; })
            .attr("x", function(d, i) { return i * gridSize; })
            .attr("y", 0)
            .style("text-anchor", "middle")
            .attr("transform", "translate(" + gridSize / 2 + ", -5)")
            .attr("class", function(d, i) { return ((i >= 7 && i <= 16) ? "timeLabel mono axis axis-worktime" : "timeLabel mono axis"); });
    
  var heatMap = svg.selectAll(".hour")
          .data(data)
          .enter().append("rect")
          .attr("x", function(d) { return (d.hour) * gridSize; })
          .attr("y", function(d) { return (d.day ) * gridSize; })
          .attr("rx", 4)
          .attr("ry", 4)
          .attr("class", "hour bordered")
          .attr("width", gridSize)
          .attr("height", gridSize)
          .style("fill", colors[0]);

      heatMap.transition().duration(1000)
          .style("fill", function(d) { return colorScale(d.value); });

      heatMap.append("title").text(function(d) { return d.value; });
     heatMap.exit().remove();     

 var legend = svg.selectAll(".legend")
              .data([0].concat(colorScale.quantiles()), function(d) { return d; });

          legend.enter().append("g")
              .attr("class", "legend");

          legend.append("rect")
            .attr("x", function(d, i) { return legendElementWidth * i; })
            .attr("y", height)
            .attr("width", legendElementWidth)
            .attr("height", gridSize / 2)
            .style("fill", function(d, i) { return colors[i]; });

          legend.append("text")
            .attr("class", "mono")
            .text(function(d) { return "≥ " + Math.round(d); })
            .attr("x", function(d, i) { return legendElementWidth * i; })
            .attr("y", height + gridSize);

          legend.exit().remove();

        });  
      

      
    </script>
  </body>
</html>

Answer №1

Instead of the initial code:

var colorScale = d3.scale.quantile();

you should use the following (make sure to set the domain properly):

 var colorScale = d3.scale.quantile()
              .domain([0, buckets - 1, d3.max(data, function (d) { return d.value; })])
              .range(colors);

For a working example, check out this link

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

Tips for organizing a list in Angular 1 when a button is clicked

I'm looking for help with sorting a list in Angular 1 when a button is clicked. I want the ability to toggle between ascending and descending order on each click. Here is a link to the code: https://plnkr.co/edit/HYuk7DAgOY6baWhrvXko?p=preview var ap ...

Applying CSS to Components in Next.js: A Step-by-Step Guide

I'm currently working on an app in next.js with chakra UI, and I'm facing a challenge when trying to add a footer. The issue is that I can't seem to get the components under the navbar to fill up the remaining height of the screen. It appea ...

`Why is THREE.Vector3.sub() in three.js behaving strangely?`

What could be causing THREE.Vector3.sub to return (0,0,0) in this specific case? p0 = new THREE.Vector3( 0, 100, 50 ); p1 = new THREE.Vector3( 0, 50, 100 ); dummy = new THREE.Vector3(0,0,0); p1_relative_to_p0 = dummy.sub(p1, p0); console.log(p1_relative_t ...

When initializing React Native, the Android, iOS, and app folders seem to be missing

https://i.sstatic.net/bkmvE.png Where have my android, ios, and app folders gone? Also, why are the index js files missing? I am currently working with React Native version 0.1.10 on a Windows 7 operating system. ...

Locate Checkbox by its Attribute Name and Value

On my webpage, there are multiple groups of checkboxes. In one particular group, I have added a custom "documentcategory" attribute to each checkbox. My goal is to identify all the checkboxes on the page that have the "documentcategory" attribute with a va ...

What steps are involved in a server utilizing Next.js to create a complete document for transmission to the client?

Understanding Next.js has been quite challenging for me. I am struggling to grasp how it operates on the server and how the server is able to implement server side rendering with the files generated by Next.js during the build process. I have a good under ...

Angular 8 delivers an observable as a result following a series of asynchronous requests

I am working on a simple function that executes 3 asynchronous functions in sequence: fetchData() { this.fetchUsers('2') .pipe( flatMap((data: any) => { return this.fetchPosts(data.id); }), fl ...

What could be the reason for the empty array returned by the combinationSum function in Javascript?

The combinationSum function is returning an empty resultArr. When checking the ds array with console.log, it shows the correct answer, but for some reason, the final output array ends up being [[],[]]. var combinationSum = function(candidates, target) { ...

Need assistance with CSS: The div:hover~div selector isn't functioning properly for a div that appears later in

Check out this example page Apologies for the unclear title, let me clarify the issue here. The webpage consists of two identical dividers. When I hover over the left divider, I want the opacity to change and simultaneously affect the second divider as w ...

Having trouble loading a listbox with JSON data using jQuery

I need help populating a ListBox using jQuery/Json. The code snippet below shows my current approach: jQuery within document.ready: $('#<%=txtSearch.ClientID %>').keyup(function() { if ($('#<%=txtSearch.ClientID %>&apos ...

Spinal cord: Connecting to the surrounding container of the view

Within my Backbone IndexView, I am using a TaskView for each 'task' model. I would like to bind an event to the li element that encloses the taskview. For instance, if the 'className' attribute is 'task', I want to trigger an ...

Is there a way to make FullPage and Lightbox compatible with each other?

Currently utilizing Fullpage.js for my website, I am looking to incorporate a lightbox in one of the sections. However, upon attempting to load the script and CSS, my fullpage layout breaks and the sections collapse. I have experimented with placing the ...

Implementing a feature that allows users to initiate a download window in a node.js express application

I have a node.js + express application in development. A scenario I am facing involves creating an excel file on the server side and then serving it to the user for download, allowing them to choose their preferred directory. Once the file is downloaded, I ...

Styling React Native components using multiple CSS arguments

Can you help me with styling in react-native using CSS like this? border-width: 5px 5px 5px 5px I attempted to use: borderWidth:{5,5,5,5} and borderWidth:'5px 5px 5px 5px' but it didn't work ...

Challenge with Jquery's slideToggle functionality when used with <H3> elements

I'm looking to make a small amendment to the jQuery code below. (Take a look at the DEMO) In the demo, you'll see that Heading One slides up and down as expected, but Heading Two and Three do not. The only difference is that I added an extra div ...

Showing the name of an object from a list based on its ID value

Is it possible to retrieve the member name from another list and display it in a table based on the member ID? (function(){ var app = angular.module('tableApp',[]); app.controller('tableController', function($scope){ $scope.user ...

Implementing server-side middleware for individual routes in Next.js

I am currently exploring options for executing code upon the initial page load of each request. My goal is to determine the domain of the request and redirect to a specific section of the website based on this information. One possibility I have considere ...

Automated Form Submission: A Guide to Automatically Sending the Form After Captcha Verification

I'm looking to incorporate ReCaptcha into my website in order to display additional data. My goal is to have the form automatically submitted once the ReCaptcha has been completed, eliminating the need for an extra submit button. However, I've en ...

What is the best way to set the date defaultValue to be empty?

I've developed a basic radio button to display an additional input field when the user chooses yes. I also created a function that will clear the fields if the user selects no. schema.ts: const formSchemaData = z.object({ doesHaveDryRun: z.enum( ...

Element widths are displaying uneven alignment

I can't seem to wrap my head around what's happening here. I've got an HTML layout with a header, sidebar, and central content page. Both the sidebar and central content are within the same div acting as a clearfix. I floated the sidebar le ...