<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <script src="https://d3js.org/d3.v4.js"></script>

    <style>
        svg text {
            font-family: sans-serif;
            font-size: 13px;
        }

        circle {
            fill: transparent;
            stroke: black;
            stroke-width: 1px;
            pointer-events:none;
        }

    </style>

</head>
<body>
<div id="block"></div>
<script>

    // dimensions
    var dims = {
        width: 800,
        height: 300,
        svg_dx: 100,
        svg_dy: 100
    };

    // Data
    var dataPoints = [1, 1010, 1020, 5000];

    // Zoom
    var zoom = d3.zoom()
        .extent([[dims.svg_dx, dims.svg_dy], [dims.width-(dims.svg_dx*2), dims.height-dims.svg_dy]])
        .scaleExtent([1, 10])
        .translateExtent([[dims.svg_dx, dims.svg_dy], [dims.width-(dims.svg_dx*2), dims.height-dims.svg_dy]])
        .on('zoom', zoomed);

    // Scale
    var xScale = d3.scaleLinear()
        .domain([0, 5000])
        .range([dims.svg_dx, dims.width-(dims.svg_dx*2)]);

    // Axis
    var xAxis = d3.axisTop(xScale)

    // Main svg
    var gMain = d3.select('#block')
        .append("svg")
        .attr("width", dims.width)
        .attr("height", dims.height)
        .append("g")
        .attr("transform", "translate(100, 100)");

    var rect = gMain
        .append("rect")
        .attr("x", 0)
        .attr("y", -25)
        .attr("width", dims.width)
        .attr("height", 50)
        .style("fill", "transparent")
        .call(zoom);


    // circles
    var circles = gMain.selectAll('circle')
        .data(dataPoints)
        .enter()
        .append('circle')
        .attr('r', 7)
        .attr('cx', function (d) {
            return xScale(d);
        });

    // axis
    var axis = gMain.append("g")

    // Jump to position (500, 1500) at start
    startTransition();


    function zoomed() {
        var transform = d3.event.transform;

        // Zoom the circles
        var xNewScale = transform.rescaleX(xScale);
        circles
            .attr("cx", function (d) {
                return xNewScale(d);
            });

        // Zoom the axis
        xAxis.scale(xNewScale);
        axis.call(xAxis);
    }

    function startTransition() {
        // Position to (500, 1500) at start
        // to jump to [500,1500] we need to calculate a new scale factor (k)...
        var k = (xScale(5000) - xScale(0)) / (xScale(1500) - xScale(500));

        // ...and then a translate to [500, 0]
        var tx = dims.svg_dx - (k * xScale(500));

        var t = d3.zoomIdentity.translate(tx, 0).scale(k);

        // Rescale the axis
        xAxis.scale(t.rescaleX(xScale));
        axis
            .attr("transform", "translate(0,-20)")
            .call(xAxis);

        // Rescale the circles
        rect.call(zoom.transform, t);
    }

</script>
</body>