Accepted answer

Well, finally I implemented what I want.


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

                .attr("x", (d) => newScaleX(d[0]))
                .attr("width", (d) => newScaleX(d[1]) - newScaleX(d[0]));

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