D3实现数字动态变化效果

使用D3.js的过渡函数transition.tween实现一个数值到另一数值的过渡。

首先,来看一下效果:
在这里插入图片描述
使页面中的数字有一个动态增长的效果,而不是直接展示出来,当页面数据更新时,也可以从之前数据增加到最新数据。


d3关于transition.tween 的解释如下:指定一个自定义的补间操作符作为过渡的一部分运行。详细文档请参考:D3-过渡

selection.transition().tween("text", function() {
    var i = d3.interpolateRound(0, 100);  // 此处为插补两个整数
    return function(t) {
        this.textContent = i(t);
    };
});

d3.interpolate - 插补两个值。
d3.interpolateRound - 插补两个整数。

讲这块代码封装成组件,就可以在页面中直接调用了,不用每次都需要重写一遍。

使用方法:
引入组件: import Counter from ‘./Counter’;

	<!--调用方法  默认展示数据为整数 -->
	<Counter data={item.value ? item.value : 0} />

也可以添加参数toFixedaddDot配置数字的展示方式。
如:

 <!--设置数字保留两位小数 -->
<Counter data={item.value ? item.value : 0} toFixed={2} />

在这里插入图片描述

<!--设置数字以逗号形式分割-->
<Counter data={item.value ? item.value : 0} addDot />

在这里插入图片描述
当然,自己有其他需求的话也可修改代码配置其他参数。

完整代码:

代码使用React架构编写

index.js

import React, { Component } from 'react';
import { fromJS } from 'immutable';
import playCounter from './render';
import './index.styl';
export default class Counter extends Component {
  constructor(props) {
    super(props);
    this.num = 0;
  }
  componentDidMount() {
    playCounter(this.counter, this.props.data || 0, this.num, this.option);
  }
  shouldComponentUpdate(nextProps) {
    if (!fromJS(nextProps).equals(fromJS(this.props))) {
      return true;
    }
    return false;
  }
  componentDidUpdate() {
    playCounter(this.counter, this.props.data || 0, this.num, this.option);
    this.num = this.props.data || 0;
  }
  render() {
    this.option = {
      delay: this.props.delay,
      dur: this.props.dur,
      toFixed: this.props.toFixed,
      addDot: this.props.addDot,
    };
    return (
      <span className="counter" ref={(node) => { this.counter = node; }}></span>
    );
  }
}

Counter.propTypes = {
  data: React.PropTypes.oneOfType([
    React.PropTypes.number,
    React.PropTypes.string,
  ]),
  delay: React.PropTypes.number,
  dur: React.PropTypes.number,
  toFixed: React.PropTypes.number,
  addDot: React.PropTypes.bool,
};

render.js

import d3 from 'd3';

export default function playCounter(id, data, num, option) {
  const {
    fontSize = 30,
    delay = 1000,
    dur = 2000,
    toFixed = 0,
    addDot = false,
  } = option || {};
  (() => {
    d3.select(id).selectAll('div').remove();
  })();
  const duration = dur;
  d3.select(id).append('span')
    .text(num)
    .transition()
    .delay(delay)
    .duration(duration)
    .ease('linear')
    .tween('text', () => {
      const i = d3.interpolate(num, data);
      function count(t) {
        let content = 0;
        if (toFixed && addDot) {
          content = Number(i(t)).toFixed(toFixed).toLocaleString();
        } else if (toFixed && !addDot) {
          content = Number(i(t)).toFixed(toFixed);
        } else if (!toFixed && addDot) {
          content = Math.round(i(t)).toLocaleString();
        } else {
          content = Math.round(i(t));
        }
        this.textContent = content;
      }
      return count;
    });
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值