d3.js v4曲线图的拖拽功能实现Zoom

本文介绍了一个使用D3.js实现的缩放案例,通过zoom事件来重新绘制x轴scale,实现了图表数据的平滑缩放效果。文章提供了完整的源码及在线演示地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

zoom缩放案例

源码:https://github.com/HK-Kevin/d...
demo:https://hk-kevin.github.io/d3...


原理:通过zoom事件来重新绘制xscale,同时获得此时scale,在zoom事件的时候调用函数,将每个数据点的xScale重新绘制一遍。


源码分析

   let data = [[{x: 0, y: 30}, {x: 1, y: 8}, {x: 2, y: 10}, {x: 3, y: 14}, {x: 4, y: 10}, {x: 5, y: 11}, {x: 6,y: 22}, {x: 7, y: 17}, {x: 12, y: 14}, {x: 14, y: 18}, {x: 20, y: 20}]]
   //定义图表数据
   let svg = d3.select("svg"),
     margin = {top :20,right:20,bottom:50,left:50}, //设值绘图区的布局
     areaWidth = svg.attr("width") - margin.left-margin.right,//获得绘图区的宽高
     areaHeight = svg.attr("height") - margin.top - margin.bottom,
     
     g = svg.append("g")//绘图区容器,所有的图形都放在这里面
     .attr("transform",`translate(${margin.left},${margin.top})`)
     .attr("width",areaWidth)
     .attr("height",areaHeight)

    let xScale =d3.scaleLinear()//添加x的尺度,线性的尺度
      .domain([0,22])
      .range([0,areaWidth]);

    let yScale = d3.scaleLinear()//添加x的尺度,线性的尺度
      .domain([40,0])
      .range([0,areaHeight]) ;

    let xAxis = d3.axisBottom(xScale) ;//添加底部坐标轴

    let yAxis = d3.axisLeft(yScale)  ;//添加左部坐标轴

    let line = d3.line()    //线生成器,就是把data的数据通过x,y的尺度转化为此坐标轴对应的数据
    .curve(d3.curveStepAfter)
    .x(function(d){
      return xScale(d.x)
    })
    .y(function (d) {
       return yScale(d.y)
    });

    let t =d3.transition()//定义动画
         .duration(500)  //持续时间
         .ease(d3.easeLinear)//动画type
         
   let xGrooup = g.append("g") //生成x轴 
     .attr("transform",`translate(0,${areaHeight})`)
     .call(xAxis)

   let yGroup =  g.append("g")//生成y轴 
      .attr("transform",`translate(0,0)`)
      .call(yAxis)

      g.append("clipPath") //添加一个剪切区,超出这个区的图形都不显示
     .attr("id", "clip")
     .append("rect")
     .attr("width", areaWidth)
     .attr("height", areaHeight);

    let updateLine = g.append("g")   //enter 、update、exit
     .attr("class","chart")
     .selectAll("line")
     .data(data)

     let enterLine = updateLine.enter();
     let exitLine = updateLine.exit();

   let path =  enterLine.append("path")
     .attr("clip-path", "url(#clip)")
     .attr("class","line")
     .attr("d",line)
     .attr("fill","none")
     .attr("stroke",0)
     .transition(t)
     .attr("stroke-width",2)
     .attr("stroke","green")

     exitLine.remove();
     
     let zoom = d3.zoom()              //设置zoom参数       
         .scaleExtent([1, 8])          //放大倍数
         .translateExtent([[0,0], [areaWidth, areaHeight]])//移动的范围
          .extent([[0, 0], [width, height]]) 
            //视窗 (左上方,右下方),默认最近父级元素的[0,0],[width,height]
         .on("zoom", zoomed);          //zoom事件,调用zoomed函数


     let zoomRect = svg.append("rect") //设置缩放的区域,一般覆盖整个绘图区
     .attr("width",areaWidth)
     .attr("height",areaHeight)
     .attr("fill","none")
     .attr("pointer-events","all")
     .call(zoom);


   function zoomed() {   
       let t = d3.event.transform.rescaleX(xScale)  //获得缩放后的scale
       xGrooup.call(xAxis.scale(t))                 //重新设置x坐标轴的scale
       g.select("path.line").attr("d", line.x(function(d){ //获取曲线,用新的x尺度来计算line
         return t(d.x)}))
     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值