Galactic Center Distance

Astronomy
Scatter Chart
Code
chart = {
  const margin = { top: 20, right: 20, bottom: 30, left: 40 };
  const width = fullWidth - margin.left - margin.right,
        height = fullHeight - margin.top - margin.bottom;

  const window = d3.create("svg")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("viewBox", `0 0 ${fullWidth} ${fullHeight}`)
    .attr("preserveAspectRatio", "xMidYMid meet");

  const svg = window.append("g")
    .attr("class", "distance")
    .attr("transform", `translate(${margin.left},${margin.top})`);

  const x = d3.scaleTime()
    .domain([new Date(2004, 8), new Date(2019, 1)])
    .range([0, width]);

  const y = d3.scaleLinear()
    .domain([6, 10])
    .range([height, 0]);

  svg.append("g")
    .attr("transform", `translate(0,${height})`)
    .call(d3.axisBottom(x));

  svg.append("g")
    .call(d3.axisLeft(y));

  function average(data, filter) {
    const values = data.filter(filter);
    const weights = values.map(d => 1 / (d.error * d.error));
    return d3.sum(values.map((d, i) => d.value * weights[i])) / d3.sum(weights);
  }

  svg.append("line")
    .attr("class", "average")
    .attr("x1", 0)
    .attr("x2", width);

  svg.append("text")
    .attr("x", 10)
    .attr("y", 10)
    .text("Estimated distance to the Galactic Center (kpc)");

  svg.append("text")
    .attr("class", "reference")
    .attr("x", 10)
    .attr("y", height - 10);

  data.forEach(d => d.date = new Date(d.date));

  const voronoi = d3.Delaunay
    .from(data, d => x(d.date), d => y(d.value))
    .voronoi([0, 0, width, height]);

  const points = svg.selectAll(".point")
    .data(data)
    .join("g")
      .attr("class", "point selected");

  points.append("path")
    .attr("d", (_, i) => voronoi.renderCell(i));

  points.append("circle")
    .attr("cx", d => x(d.date))
    .attr("cy", d => y(d.value))
    .attr("r", 4);

  points.append("line")
    .attr("x1", d => x(d.date))
    .attr("x2", d => x(d.date))
    .attr("y1", d => y(d.value - d.error))
    .attr("y2", d => y(d.value + d.error));

  points.on("mouseover", function(event, d) {
    if (d3.select(this).classed("selected")) {
      d3.selectAll(".point")
        .classed("hover", false);

      d3.select(this)
        .classed("hover", true);

      svg.select(".reference")
        .text(`${d.reference} using ${d.method}`);
    }
  });

  function change(location) {
    function selected(d) {
      return location === "Any" || d.location.indexOf(location) !== -1;
    }

    d3.selectAll(".point")
      .classed("hover", false)
      .classed("selected", selected);

    const R0 = average(data, selected);

    svg.select(".average")
      .transition()
      .attr("y1", y(R0))
      .attr("y2", y(R0));

    svg.select(".reference")
      .text("");
  }

  return Object.assign(window.node(), {
    update(values) {
      change(values.location);
    },
  });
}

This chart shows a compilation of measurements of the distance to the Galactic Center, based on different methods.

Resources