<svg></svg>

<div style="padding: 2rem; text-align: center;">
	<p>If you are viewing this example you are viewing the cached version of the rain fall probability of Lagos, Nigeria fetched from <a href="https://www.tomorrow.io/weather-api/">Tomorrow.io weather API on </a> - <small>December 03, 2021</small>
	</p>
</div>
      body {
        margin: 0px;
      }
      .domain {
        display: none;
      }
      .tick line {
        stroke: #c0c0bb;
      }
      .tick text {
        fill: #8e8883;
        font-family: sans-serif;
      }
      .axis-label {
        fill: #635f5d;
        font-family: sans-serif;
      }
      .svg_title {
        fill: #635f5d;
        font-family: sans-serif;
      }
import * as d3 from "https://cdn.skypack.dev/d3@7.1.1";


const lat = 6.465422;
const long = 3.406448;
const api_key = null;

let url = null;

if(api_key !== null) {
	url = `https://api.tomorrow.io/v4/timelines?location=${lat},${long}&fields=snowAccumulation,precipitationProbability,precipitationType&timesteps=1h&units=metric&apikey=${api_key}`;
} else {
	url = "https://raw.githubusercontent.com/iamspruce/intro-d3/main/data/cache-tomorrow_io.json"
}

// labels
const x_label = "Time";
const y_label = "Rainfall Probability";
const location_name = "Lagos Nigeria";

const margin = { left: 120, right: 30, top: 60, bottom: 30 },
  width = document.querySelector("body").clientWidth,
  height = 500;

const svg = d3.select("svg").attr("viewBox", [0, 0, width, height]);

// add title
svg
  .append("text")
  .attr("class", "svg_title")
  .attr("x", (width - margin.right + margin.left) / 2)
  .attr("y", margin.top / 2)
  .attr("text-anchor", "middle")
  .style("font-size", "22px")
  .text(`${y_label} of ${location_name}`);

// add y label
svg
  .append("text")
  .attr("text-ancho", "middle")
  .attr(
    "transform",
    `translate(${margin.left - 70}, ${
      (height - margin.top - margin.bottom + 180) / 2
    }) rotate(-90)`
  )
  .style("font-size", "26px")
  .text(y_label);

// add x label
svg
  .append("text")
  .attr("class", "svg_title")
  .attr("x", (width - margin.right + margin.left) / 2)
  .attr("y", height - margin.bottom - margin.top + 60)
  .attr("text-anchor", "middle")
  .style("font-size", "26px")
  .text(x_label);

const x_scale = d3.scaleTime().range([margin.left, width - margin.right]);
const y_scale = d3.scaleLinear().range([
  height - margin.bottom - margin.top,
  margin.top,
]);

const ticks = 10;

const x_axis = d3.axisBottom()
  .scale(x_scale)
  .tickPadding(10)
  .ticks(ticks)
  .tickSize(-height + margin.top * 2 + margin.bottom);

const y_axis = d3.axisLeft()
  .scale(y_scale)
  .tickPadding(5)
  .ticks(ticks, ".1")
  .tickSize(-width + margin.left + margin.right);

// convert precipitationProbability to % gotten from this thread https://stackoverflow.com/questions/38078924/d3-js-axis-percentage-values-with-decimals
y_axis.tickFormat((d) => {
  if (!Number.isInteger(d)) {
    d = decimalFormatter(d);
  }
  return d + "%";
});

const start_time = (d) => new Date(d.startTime);
const temperature = (d) => +d.values.precipitationProbability;

const line_generator = d3.line()
  .x((d) => x_scale(start_time(d)))
  .y((d) => y_scale(temperature(d)))
  .curve(d3.curveBasis);

d3.json(url).then(({ data }) => {
  const d = data.timelines[0].intervals;

  x_scale.domain(d3.extent(d, start_time)).nice(ticks);

  y_scale.domain(d3.extent(d, temperature)).nice(ticks);

  // append x axis
  svg
    .append("g")
    .attr("transform", `translate(0,${height - margin.bottom - margin.top})`)
    .call(x_axis);
  // add y axis
  svg.append("g").attr("transform", `translate(${margin.left},0)`).call(y_axis);

  // add the line path
  svg
    .append("path")
    .attr("fill", "none")
    .attr("stroke", "steelblue")
    .attr("stroke-width", 4)
    .attr("d", line_generator(d));
});
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.