score:1

Accepted answer

I've already came out with a solution (with a better and cleaner approach). This solution is based the TBD's d3 timeline implementation. Using his solution I just adapted to the y axis and to my code

    const maxYValues = d3.max(maxValues) || 0;

    const yScaleGlobal = d3
      .scaleLinear()
      .domain([0, maxYValues])
      .range([0, svgHeight - MARGINS.TOP - MARGINS.BOTTOM]);

    const yAxis = d3.axisLeft(yScaleGlobal).tickFormat((d: any) => `${d} m`);

    const gY = litoligicalGroup.select(`.${styles.yAxis}`).call(yAxis);

    const spanY = (d) => {
      if (d.thickness) return yScaleGlobal(0) - 10;
      return yScaleGlobal(d.from);
    };

    const spanH = (d) => {
      if (d.thickness) return 10;
      return yScaleGlobal(d.to - d.from);
    };

    const zoom = d3
      .zoom()
      .scaleExtent([0.2, 5])
      .on('zoom', (e) => {
        const transform = e.transform;

        gY.call(yAxis.scale(transform.rescaleY(yScaleGlobal)));
        // the viz group is where all the layers are attached
        vizGroup
          .selectAll('rect')
          .attr('y', (d) => {
            if (!d) return null;
            return transform.applyY(spanY(d));
          })
          .attr('height', (d) => {
            if (!d) return null;
            return transform.k * spanH(d);
          });
      });

    drawProfile();

    svg.call(zoom);

    function drawProfile() {
      if (geologicData) updateGeology(geologicData, yScaleGlobal);
      if (constructionData) updatePoco(constructionData, yScaleGlobal);
    }

Related Query

More Query from same tag