title: D3 zooming in on a part of a line chart
body: <p>I am trying to zoom in with onclick function on a part of a line chart. I have read many articles and questions on the issue, but most of them deal with zooming with the wheel and what I need is just a zoom on the button click. Something like in <a href="https://www.zeit.de/politik/deutschland/2019-05/east-west-exodus-migration-east-germany-demography" rel="nofollow noreferrer">this article</a> (line chart).
  What I can not figure out, is how to calculate exact position of where the zoom should be translated to and scaled correctly (I need the right side of the graph, starting from a particular x Axis value to be zoomed in). Hope some one could help.
  I included mock data in my code, but the real data are much more granular.</p>
  
  <p>My code:
  Also <a href="https://codepen.io/fedmaria/pen/ZEGvGxj" rel="nofollow noreferrer">here</a></p>
  
  <pre><code>    &lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
      &lt;head&gt;
        &lt;meta charset="utf-8"&gt;
        &lt;script src="https://d3js.org/d3.v5.min.js"&gt;&lt;/script&gt;
  
      &lt;/head&gt;
  
      &lt;body&gt;
        &lt;div id="wrapper" class="wrapper"&gt;&lt;/div&gt;
  
        &lt;button id="zoom"&gt;Zoom&lt;/button&gt;
  
  &lt;script&gt;
  dataset = [
      {
      "num": 100,
      "month": 1,
      "year": 2016,
      "mmyy": "2016 _ 1",
      "group": "one",
      "mmyy_rec": "Jan 2016"
    },
        {
      "num": 80,
      "month": 1,
      "year": 2017,
      "mmyy": "2017 _ 1",
      "group": "one",
      "mmyy_rec": "Jan 2017"
    },
        {
      "num": 10,
      "month": 1,
      "year": 2018,
      "mmyy": "2018 _ 1",
      "group": "one",
      "mmyy_rec": "Jan 2018"
    }
  ]
  
   let dimensions = {
      width: 800,
      height: 400,
      margin: {
        top: 20,
        right: 15,
        bottom: 40,
        left: 60,
      },
  }
  
  dimensions.boundedWidth = dimensions.width - dimensions.margin.left - dimensions.margin.right
  dimensions.boundedHeight = dimensions.height - dimensions.margin.top - dimensions.margin.bottom
  
    const wrapper = d3.select("#wrapper")
      .append("svg")
      .attr("width", dimensions.width)
      .attr("height", dimensions.height);
  
    const bounds = wrapper.append("g")
      .style("transform", `translate(${dimensions.margin.left}px, ${dimensions.margin.top}px)`)
      .attr("class", "test");
  
    const xScale = d3.scalePoint() 
      .domain(dataset.map(d=&gt; d.mmyy_rec))
      .range([0, dimensions.boundedWidth]);
  
  
    const yScale = d3.scaleLinear()
      .domain([0, d3.max(dataset,d=&gt;d.num)])
      .range([dimensions.boundedHeight,0]);
  
    const line = d3.line()
      .curve(d3.curveNatural)
      .x(d =&gt; xScale(d.mmyy_rec))
      .y(d =&gt; yScale(d.num)); 
  
  
        const path1 = bounds
       .append('path')
       .datum(dataset)
       .attr('fill', 'none')
       .attr('stroke', 'green')
       .attr("class", "line1") 
       .attr('d', line)
  
  
  const yAxisGenerator = d3.axisLeft().scale(yScale)
  bounds.call(yAxisGenerator);
  
    d3.select("#zoom").on("click", function() {
  
     const d0 = "Jan 2017";
      const d1 = "Dec 2018";
  
     const k = dimensions.boundedWidth / (xScale(d1) - xScale(d0));
     const length = dimensions.boundedHeight - yScale(100);
     const centerX = dimensions.boundedWidth /2;
     const centerY = dimensions.boundedHeight /2;
     const translate = [dimensions.boundedWidth / 2 - centerX * k, dimensions.boundedHeight / 2 - centerY * k]
  
  
         const zoom = d3.zoom()
      .scaleExtent([1, 2])
      .translateExtent([[0, 0], [dimensions.boundedWidth, dimensions.boundedHeight]])
      .extent([[0, 0], [dimensions.boundedWidth, dimensions.boundedHeight]])
      .on('zoom', function() {
        path1.attr('transform', d3.event.transform);
  
      });
  
       zoom.scaleBy(path1.transition().duration(750), k)
       .translate(centerX,centerY); 
  
  
    });
  
  &lt;/script&gt;
      &lt;/body&gt;
  
  
  &lt;/html&gt;
  </code></pre>