score:1

Accepted answer

Well, finally I implemented what I want.

Result: https://jsfiddle.net/2yqbvrwp/

Details: First of all, I decided to remove second scale, bc I need it only in runtime. So, my zoom function is changed to:

d3.zoom().scaleExtent([ 1, 10 ])
        // I am not sure if I need the line below since code works same without it
        // I think below is default value

        //.translateExtent([ [ 0, 0 ], [ width, height ] ])
        .on("zoom", (event) => {

            const transform = event.transform;

            // the new scale I use for runtime
            // the important part here is clamp method. It prevents from moving
            // segments outside of axis
            const newScaleX = transform.rescaleX(xScale).clamp(true);

            // so I just applied new scale to current axis
            xAxis.scale(newScaleX)
            svg.select("g.axis-x").call(xAxis);

            svg.selectAll("rect.segment")
                .attr("x", (d) => newScaleX(d[0]))
                .attr("width", (d) => newScaleX(d[1]) - newScaleX(d[0]));
        })

    svg.call(zoom);

Also I removed rect transform from css and added margin left in code. But I think I will return it back since native css is faster.


Related Query