Javascript D3放大折线图的一部分

Javascript D3放大折线图的一部分,javascript,d3.js,svg,Javascript,D3.js,Svg,我试图在折线图的一部分上使用onclick函数放大。我已经阅读了很多关于这个问题的文章和问题,但是大多数都是关于轮子的缩放,我需要的只是点击按钮进行缩放。类似于(折线图)的东西。 我搞不懂的是,如何计算缩放应该被正确平移和缩放的确切位置(我需要图形的右侧,从要放大的特定x轴值开始)。希望有人能帮忙。 我在代码中包含了模拟数据,但实际数据更细粒度 我的代码: 也 快速移动 数据集=[ { “num”:100, “月”:1, “年份”:2016年, “mmyy”:“2016年1月”, “集团”:“

我试图在折线图的一部分上使用onclick函数放大。我已经阅读了很多关于这个问题的文章和问题,但是大多数都是关于轮子的缩放,我需要的只是点击按钮进行缩放。类似于(折线图)的东西。 我搞不懂的是,如何计算缩放应该被正确平移和缩放的确切位置(我需要图形的右侧,从要放大的特定x轴值开始)。希望有人能帮忙。 我在代码中包含了模拟数据,但实际数据更细粒度

我的代码: 也


快速移动
数据集=[
{
“num”:100,
“月”:1,
“年份”:2016年,
“mmyy”:“2016年1月”,
“集团”:“一家”,
“mmyy_rec”:“2016年1月”
},
{
“num”:80,
“月”:1,
“年份”:2017年,
“mmyy”:“2017年1月”,
“集团”:“一家”,
“mmyy_rec”:“2017年1月”
},
{
“num”:10,
“月”:1,
“年份”:2018年,
“mmyy”:“2018年1月”,
“集团”:“一家”,
“mmyy_rec”:“2018年1月”
}
]
设维数={
宽度:800,
身高:400,
保证金:{
前20名,
右:15,
底数:40,
左:60,,
},
}
dimensions.boundedWidth=dimensions.width-dimensions.margin.left-dimensions.margin.right
尺寸.boundedHeight=尺寸.height-尺寸.margin.top-尺寸.margin.bottom
常量包装器=d3。选择(“包装器”)
.append(“svg”)
.attr(“宽度”,尺寸.宽度)
.attr(“高度”,尺寸。高度);
const bounds=wrapper.append(“g”)
.style(“transform”,`translate(${dimensions.margin.left}px,${dimensions.margin.top}px)`)
.attr(“类”、“测试”);
常量xScale=d3.scalePoint()
.domain(dataset.map(d=>d.mmyy_rec))
.范围([0,维度.边界宽度]);
常量yScale=d3.scaleLinear()
.domain([0,d3.max(数据集,d=>d.num)])
.范围([尺寸.边界高度,0]);
常量行=d3.line()
.曲线(d3.曲线自然)
.x(d=>xScale(d.mmyy_rec))
.y(d=>yScale(d.num));
常量路径1=边界
.append('路径')
.数据集(数据集)
.attr('填充','无')
.attr('笔划','绿色')
.attr(“类别”、“第1行”)
.attr('d',行)
常量yAxisGenerator=d3.axisLeft().scale(yScale)
调用(yAxisGenerator);
d3.选择(“缩放”)。在(“单击”,函数()上{
const d0=“2017年1月”;
const d1=“2018年12月”;
常数k=尺寸.边界宽度/(xScale(d1)-xScale(d0));
常量长度=尺寸。边界高度-yScale(100);
const centerX=尺寸。边界宽度/2;
常数中心=尺寸。边界高度/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(路径1.transition().duration(750),k)
.翻译(centerX、centerY);
});
    <!DOCTYPE html>
<html lang="en">
    <head>
      <meta charset="utf-8">
      <script src="https://d3js.org/d3.v5.min.js"></script>

    </head>

    <body>
      <div id="wrapper" class="wrapper"></div>

      <button id="zoom">Zoom</button>

<script>
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=> d.mmyy_rec))
    .range([0, dimensions.boundedWidth]);


  const yScale = d3.scaleLinear()
    .domain([0, d3.max(dataset,d=>d.num)])
    .range([dimensions.boundedHeight,0]);

  const line = d3.line()
    .curve(d3.curveNatural)
    .x(d => xScale(d.mmyy_rec))
    .y(d => 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); 


  });

</script>
    </body>


</html>