score:1

Accepted answer

There is no need to generate a function converting Month number into full labels, d3-time-format does it for you..

The specifier for full Month name in d3.timeFormat is %B (source: d3-time-format documentation.

const yAxis = d3.axisLeft(yScale)
                .tickFormat(d => d3.timeFormat('%B')( new Date(0).setMonth(d-1) ));

Because Months in javascript dates go between 0 and 11, we need to deduct 1 from d, which goes between 1 and 12.

The snippet below illustrates the solution.

Few other modifications were made in order to get the chart visible in firefox:

  • set svg width and height as attr rather than style
  • remove hard-coded CSS positioning.

const render = (baseTemperature, dataset) => {
  const width = 960;
  const height = 500;
  
  const xValue = d => d['year'];
  const yValue = d => d['month'];
  const variance = d => Math.round10(d['variance'], -1);
  const currTemp = d => Math.round10(baseTemperature - d['variance'], -1);
  
  const margin = { top: 40, right: 60, bottom: 40, left: 60 };
  const innerWidth = width - margin.left - margin.right;
  const innerHeight = height - margin.top - margin.bottom;
  
  const titleText = 'Monthly Global Land-Surface Temperature';
  const titleXAxisPos = innerWidth / 2;
  const titleYAxisPos = 10;
  
  const subtitleText = `${d3.min(dataset, xValue)} - ${d3.max(dataset, xValue)}: base temperature ${baseTemperature}℃`;
  const subtitleYAxisPos = titleYAxisPos + 22;
  
  // Initiate a svg canvas
  const svg = d3.select('body')
    .append('svg')
    .attr('height', height)
    .attr('width', width)
  
  // Initiate a heat map
  const heatmap = svg.append('g')
    .attr('transform', `translate(${margin.left}, ${margin.top})`);
  
  // Establish a scale
  const xScale = d3.scaleTime()
    .domain([d3.min(dataset, xValue), d3.max(dataset, xValue)])
    .range([0, innerWidth]);
  
  const yScale = d3.scaleTime()
    .domain([d3.min(dataset, yValue), d3.max(dataset, yValue)])
    .range([0, innerHeight]);
  
  // Create axes
  const xAxis = d3.axisBottom(xScale).tickFormat(d => d3.timeFormat('%Y')( new Date(0).setFullYear(d) ));
  const yAxis = d3.axisLeft(yScale).tickFormat(d => d3.timeFormat('%B')( new Date(0).setMonth(d-1) ));
  
  heatmap.append('g')
       .attr('id', 'x-axis')
       .attr('transform', `translate(0, ${innerHeight})`)
       .call(xAxis);
    
  heatmap.append('g')
    .attr('id', 'y-axis')
    .call(yAxis);
  
  const titleSection = heatmap.append('g')
      .attr('text-anchor', 'middle')
    
  titleSection.append('text')
    .attr('id', 'title')
    .attr('x',  titleXAxisPos)
    .attr('y', titleYAxisPos)
    .style('font-size', '1.5em')
    .style('font-weight', 'bold')
    .text(titleText);
    
  titleSection.append('text')
    .attr('id', 'subtitle')
    .attr('x', titleXAxisPos)
    .attr('y', subtitleYAxisPos)
    .style('font-size', '1.2em')
    .text(subtitleText);
  
  
};

document.addEventListener('DOMContentLoaded', function() {
  const request = new XMLHttpRequest();
  request.open('GET', 'https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/global-temperature.json', true);
  request.send();
  request.onload = function () {
    let json = JSON.parse(request.responseText);
    let baseTemperature = json.baseTemperature;
    let dataset = json.monthlyVariance;
    render(baseTemperature, dataset);
  };
});
body {
  background-color: rgb(128,128,128);
  font-family: monospace;
}

svg {
  background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>
<body></body>


Related Query

More Query from same tag