D3.js Path Transition(折线图的更新)

本文探讨如何使用D3.js库来实现折线图的动态过渡效果,通过不断更新数据并平移重绘线条,达到每秒刷新图表的目的,同时通过裁剪多余部分保持视觉流畅。

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

可视化肯定是需要及时更新数据的,每秒填充一次数据,渲染到图表中。
大概思路就是:重绘line,向左平移,把多余的line 裁剪掉。
在这里插入图片描述


 	const n = 100;
    const duration = 1000;
    let time = new Date(Date.now() - duration);
   
    const random = d3.randomNormal(0, .2);
    const data = d3.range(n).map(random);
    
    const margin = {top: 20, right: 10, bottom: 20, left: 40};
    const width = 960 - margin.right - margin.left;
    const height = 150 - margin.top - margin.bottom;

    const xScale = d3.scaleTime()
      .domain([time - (n - 2) * duration, time - duration])
      .range([0, width]);

    const yScale = d3.scaleLinear()
      .range([height, 0])
      .domain([-1, 1]);

    const line = d3.line()
      .x((d, i) => xScale(time - (n - 1 - i) * duration))
      .y((d, i) => yScale(d))
      .curve(d3.curveBasis);

    const svg = d3.select(id)
      .append('svg')
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom);

    const g = svg.append('g')
      .attr('transform', `translate(${margin.left}, ${margin.top})`);

    svg.append('defs')
      .append('clipPath')
      .attr('id', 'clip')
      .append('rect')
      .attr('width', width)
      .attr('height', height);

    const xAxis = d3.axisBottom(xScale).ticks(15);
    const yAxis = d3.axisLeft(yScale).ticks(5);

    g.append('g')
      .attr('class', 'axis--x')
      .attr('transform', 'translate(0,' + height + ')')
      .call(xAxis);

    g.append('g')
      .attr('class', 'axis--y')
      .call(yAxis);

    const transition = d3
      .transition()
      .duration(duration)
      .ease(d3.easeLinear);

   
    const path = g.append('g')
      .attr('clip-path', 'url(#clip)')
      .append('path')
      .datum(data)
      .attr('class', 'line')
      .attr('fill', 'none')
      .attr('stroke', 'red')
      .transition(transition)
      .on('start', tick);
      
    let flag = true;

    function tick() {
      time = new Date();
      xScale.domain([time - (n - 2) * duration, time - duration]);

      // push the accumulated count onto the back, and reset the count
      data.push(random());

      // slide the x-axis left
      d3.select('.axis--x')
        .transition(transition)
        .call(xAxis);

      // Redraw the line.
      const pa = d3.select(this)
        .attr('d', line)
        .attr('transform', null);

      const totalLength = path.node().getTotalLength();

      if (flag) {
     	//判断是否是第一次渲染,是的话添加一个动画
        // Set Properties of Dash Array and Dash Offset and initiate Transition
         pa
        .attr('stroke-dasharray', totalLength + ' ' + totalLength)
        .attr('stroke-dashoffset', totalLength)
        .transition(transition) // Call Transition Method
        .attr('stroke-dashoffset', 0); // Set final value of dash-offset for transition
       
         flag = false;
      }

      // Slide it to the left.
      d3.active(this)
        .attr('transform', `translate(${xScale(time - (n - 1) * duration)})`)
        .transition(transition)
        .on('start', tick);

      // pop the old data point off the front
      data.shift();
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值