'Is there a way to create different d3 axis for unique groups in the data? (d3.js)

I am trying to create multiarray joy plot for some data, but I struggle to make a proper axis. I am facing the problem that each column in the joy plot needs its specific scale domain because the data is different from the other columns.

enter image description here

The way I have coded the plot is to group the data with d3.groups() and then build the structure of the joy plot with this approach. However, using this approach, I can create the plot but not draw the axis. Is there a way to accomplish this?

My first thought was that I could pass the data (mapped to .data()) to .call(). In the function that .call() calls, I could include some code that creates the scale and axis for each array in the joy plot. However, this doesnt seem to work because the function that .call calls doesnt have access to the data.

Here are some example data and the plot that generates the plot:

const width = window.innerWidth * 0.9;
const height = window.innerHeight * 0.9;
const margin = {
  top: 20,
  right: 20,
  bottom: 30,
  left: 20,
};
const groups = 2;
const padding = 10;
const paddingZ = 200;

const gWidth = width - margin.left - margin.right;
const gHeight = height - margin.top - margin.bottom;

const histogramHeight = (padding + gHeight + padding) / groups;
const histogramWidth = (padding + gWidth + padding) / groups;
const histogramZheight = (paddingZ + histogramHeight + paddingZ) / 3;

const svg = d3
  .select("body")
  .append("svg")
  .attr("height", height)
  .attr("width", width);

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

const main = async () => {

  data = [
    {bib: 1, split: 1, course: "A", performance: 2.4},
    {bib: 1, split: 1, course: "B", performance: 7},
    {bib: 1, split: 2, course: "A", performance: 2.7},
    {bib: 1, split: 2, course: "B", performance: 8},
    {bib: 2, split: 1, course: "A", performance: 2.9},
    {bib: 2, split: 1, course: "B", performance: 5.0},
    {bib: 2, split: 2, course: "A", performance: 9},
    {bib: 2, split: 2, course: "B", performance: 6},
    {bib: 2, split: 2, course: "A", performance: 3},
    {bib: 1, split: 2, course: "A", performance: 3},
    {bib: 1, split: 2, course: "B", performance: 1.2},
    {bib: 2, split: 1, course: "B", performance: 3},

  ]


  const dataGrouped = d3.groups(
    data,
    (d) => d.day,
    (d) => d.split,
    (d) => d.course
  );

  const cellX = g
    .selectAll(".cell")
    .data(dataGrouped)
    .join("g")
    .attr("class", "cellX")
    .attr("transform", (d) => console.log(d))
    .attr(
      "transform",
      (d, i) => `translate(0, ${i * (padding + histogramHeight + padding)})`
    );

  const cellY = cellX
    .selectAll(".cellX")
    .data((d) => d[1])
    .join("g")
    .attr("class", "cellXY")
    .attr(
      "transform",
      (d, i) => `translate(${i * (padding + histogramWidth + padding)},0)` //${ i * (padding + histogramWidth + padding)},0)`
    );

  const cellZ = cellY
    .selectAll(".cellXY")
    .data((d) => d[1])
    .join("g")
    .attr("class", "cellZ")
    .attr(
      "transform",
      (d, i) => `translate(0, ${i <= 2 ? i * paddingZ : i * (paddingZ)})` //(0, ${i * (paddingZ + histogramZheight + paddingZ)})`
    );

  const path = cellZ
    .selectAll(".lo")
    .data((d) => d)
    .join("path")
    .attr("d", (d) => {
      const xScale = d3
        .scaleLinear()
        .domain([-3, 40])
        .range([0, histogramWidth]);

      console.log(xScale.domain());

      const bingenerator = d3
        .bin()
        .domain(xScale.domain())
        .value((d) => d.performance);

      const binnedData = bingenerator(d);

      const topHistogramYscale = d3
        .scaleLinear()
        .domain(d3.extent(binnedData, (d) => d.length))
        .range([histogramZheight, 0]);

      const xAxis = d3.axisBottom().scale(xScale);

      const topHistogramLineGenerator = d3
        .area()
        .x((d) => xScale(d.x0))
        .y0(histogramZheight)
        .y1((d) => topHistogramYscale(d.length))
        .curve(d3.curveBasis);

      return topHistogramLineGenerator(binnedData);
    })


}

main();


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source