Help Scaling Rects with Months (Visualize Data with a Heat Map)

Hello,

Been trying all day to get my rects to scale height with the y-axis that is in months. I’ve tried using my yScale with the parameter of d.month, have tried manipulating the range in the yScale, and tried numerous other things. Can someone steer me in the right direction?

CodePen

const url =
  "https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/global-temperature.json";

function getWidth() {
  return Math.max(document.body.offsetWidth);
}

function getHeight() {
  return Math.max(document.body.offsetHeight);
}

d3.json(url).then(function (data) {
  dataSet = Object.values(data.monthlyVariance);
  dataSetBase = data.baseTemperature;
  
  const padding = 75;
  const margin = {
    top: getHeight() * 0.25,
    right: getWidth() * 0.25,
    bottom: getHeight() * 0.25,
    left: getWidth() * 0.25
  };

  const w = 750;
  const h = 400;

  const minX = d3.min(dataSet, (d) => d3.timeParse("%Y")(d.year));
  const maxX = d3.max(dataSet, (d) => d3.timeParse("%Y")(d.year));

  const minY = d3.min(dataSet, (d) => d3.timeParse("%m")(d.month));
  const maxY = d3.max(dataSet, (d) =>  d3.timeParse("%m")(d.month));
  
  const minTemp = dataSetBase + d3.min(dataSet, (d) => d.variance);
  const maxTemp = dataSetBase + d3.max(dataSet, (d) => d.variance);

  const svg = d3
    .select("svg")
    .attr("width", w)
    .attr("height", h)
    .attr("margin", margin);

  const xScale = d3
    .scaleTime()
    .domain([minX, maxX])
    .range([padding, w - padding])
    .nice();

  const yScale = d3
    .scaleTime()
    .domain([maxY, minY])
    .range([h - padding, padding])
    .nice();
    
  const myColor = d3
  .scaleSequential()
  .interpolator(d3.interpolateRdYlBu)
  .domain([minTemp,maxTemp])

  const xAxis = d3.axisBottom(xScale);
  const yAxis = d3.axisLeft(yScale)
  .tickFormat(d3.timeFormat("%B"))
  

  svg
    .append("g")
    .attr("id", "x-axis")
    .attr("transform", "translate(0," + (h - padding) + ")")
    .call(xAxis);

  svg
    .append("g")
    .attr("id", "y-axis")
    .attr("transform", "translate(" + padding + ",0)")
    .call(yAxis);
  
    var chart = 
    svg
    .selectAll('rect')
    .data(data.monthlyVariance)
    .enter()
    .append("rect")
      .attr("x", (d) => xScale(d3.timeParse("%Y")(d.year)))
      .attr("y", (d) => yScale(d3.timeParse("%m")(d.month)))
      .attr("width", 5)
      .attr("height", 22)
      .attr('fill', (d) => myColor(parseFloat(dataSetBase -d.variance)))
    
});

I think I have the width figured out. Still struggling with the height:

var chart = 
    svg
    .selectAll('rect')
    .data(data.monthlyVariance)
    .enter()
    .append("rect")
      .attr("x", (d) => xScale(d3.timeParse("%Y")(d.year)))
      .attr("y", (d) => yScale(d3.timeParse("%m")(d.month)))
      .attr("width", dataSet.length / w)
      .attr("height", padding - 12 / h)
      .attr('fill', (d) => myColor(parseFloat(dataSetBase - d.variance)))
    
});

For anyone else having issues with this problem, I was able to get the height and width of the bars to work correctly using the following:

      .attr("width", dataSet.length / w)
      .attr("height", (h - padding)/12)

Basically, I used the typical height attr but divided it by the number of months in my chart. The width just needed to account for the array length and divide it by the width.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.