使用D3.js在Typescript中将HeartBeat从v3转换为v4

如何解决使用D3.js在Typescript中将HeartBeat从v3转换为v4

我成功使用此link中的D3.js转换了HeartBeat:

从Typescript中的v3到v4。

由于某种原因,我收到以下错误消息

enter image description here

在“ tick ”功能中。出于某些原因,似乎未定义“ this.transition ”。有人可以请教吗?

还要注意,我将tick函数从Instant函数转换为Normal函数,这有什么区别吗?

import * as d3 from 'd3';

导出默认类D3HeartBeat {

private svg = null;
private circle = null;
private circleTransition = null;
private latestBeat = null;
private insideBeat = false;
private data = [];
private SECONDS_SAMPLE = 5;
private BEAT_TIME = 400;
private TICK_FREQUENCY = this.SECONDS_SAMPLE * 1000 / this.BEAT_TIME;
private BEAT_VALUES = [0,3,-4,10,-7,0];
private CIRCLE_FULL_RADIUS = 40;

private MAX_LATENCY = 5000;
private transition;
private now;
private fromDate;
private x;
private y;
private line;
private axis;
private xAxis;
private path;

constructor() {

    window.onload = () => {

        let colorScale = d3.scaleLinear<string>()
            .domain([this.BEAT_TIME,(this.MAX_LATENCY - this.BEAT_TIME) / 2,this.MAX_LATENCY])
            .range(["#6D9521","#D77900","#CD3333"]);

        let radiusScale = d3.scaleLinear()
            .range([5,this.CIRCLE_FULL_RADIUS])
            .domain([this.MAX_LATENCY,this.BEAT_TIME]);


        let svgWrapper = document.getElementById("svg-wrapper");
        let margin = { left: 10,top: 10,right: this.CIRCLE_FULL_RADIUS * 3,bottom: 10 },width = svgWrapper.offsetWidth - margin.left - margin.right,height = svgWrapper.offsetHeight - margin.top - margin.bottom;

        // create SVG
        this.svg = d3.select('#svg-wrapper').append("svg")
            .attr("width",width + margin.left + margin.right)
            .attr("height",height + margin.bottom + margin.top)
            .append("g")
            .attr("transform","translate(" + margin.left + "," + margin.top + ")");

        this.circle = this.svg
            .append("circle")
            .attr("fill","#6D9521")
            .attr("cx",width + margin.right / 2)
            .attr("cy",height / 2)
            .attr("r",this.CIRCLE_FULL_RADIUS);

        // init scales
        this.now = new Date(),this.fromDate = new Date(this.now.getTime() - this.SECONDS_SAMPLE * 1000);

        // create initial set of data
        this.data.push({
            date: this.now,value: 0
        });

        this.x = d3.scaleTime()
            .domain([this.fromDate,new Date(this.now.getTime())])
            .range([0,width]);

        this.y = d3.scaleLinear()
            .domain([-10,10])
            .range([height,0]);

        this.line = d3.line().curve(d3.curveBasis)
            .x((d: any) => {
                return this.x(d.date);
            })
            .y((d: any) => {
                return this.y(d.value);
            });

        this.xAxis = d3.axisBottom(this.x)
            .ticks(d3.timeSecond,1)
            .tickFormat((d: any) => {
                let seconds = d.getSeconds() === 0 ? "00" : d.getSeconds();
                return seconds % 10 === 0 ? d.getMinutes() + ":" + seconds : ":" + seconds;
            });

        // add clipPath
        this.svg.append("defs").append("clipPath")
            .attr("id","clip")
            .append("rect")
            .attr("width",width)
            .attr("height",height);

        this.axis = d3.select("svg").append("g")
            .attr("class","axis")
            .attr("transform","translate(0," + height + ")")
            .call(this.xAxis);

        this.path = this.svg.append("g")
            .attr("clip-path","url(#clip)")
            .append("path")
            .attr("class","line");

        this.svg.select(".line")
            .attr("d",this.line(this.data));

        this.transition = d3.select("path").transition()
            .duration(100)
            .ease(d3.easeLinear);

        this.tick(); 

        setInterval(() => {

            this.now = new Date();
            this.fromDate = new Date(this.now.getTime() - this.SECONDS_SAMPLE * 1000);

            for (let i = 0; i < this.data.length; i++) {
                if (this.data[i].date < this.fromDate) {
                    this.data.shift();
                } else {
                    break;
                }
            }

            if (this.insideBeat) return;

            this.data.push({
                date: this.now,value: 0
            });

            if (this.circleTransition != null) {

                let diff = this.now.getTime() - this.latestBeat.getTime();

                if (diff < this.MAX_LATENCY) {
                    this.circleTransition = this.circle.transition()
                        .duration(this.TICK_FREQUENCY)
                        .attr("r",radiusScale(diff))
                        .attr("fill",colorScale(diff));
                }
            }


        },this.TICK_FREQUENCY);

        setInterval(() => {
            this.beat();
        },2000);
        this.beat();
    };

}

beat() {

    if (this.insideBeat) return;

    this.insideBeat = true;

    let now = new Date();
    let nowTime = now.getTime();

    if (this.data.length > 0 && this.data[this.data.length - 1].date > now) {
        this.data.splice(this.data.length - 1,1);
    }

    this.data.push({
        date: now,value: 0
    });

    let step = this.BEAT_TIME / this.BEAT_VALUES.length - 2;
    for (let i = 1; i < this.BEAT_VALUES.length; i++) {
        this.data.push({
            date: new Date(nowTime + i * step),value: this.BEAT_VALUES[i]
        });
    }

    this.latestBeat = now;

    this.circleTransition = this.circle.transition()
        .duration(this.BEAT_TIME)
        .attr("r",this.CIRCLE_FULL_RADIUS)
        .attr("fill","#6D9521");

    setTimeout(() => {
        this.insideBeat = false;
    },this.BEAT_TIME);
}

tick() {

    //if (this.transition && typeof this.transition !== 'undefined')

    this.transition = this.transition.each(() => {

        // update the domains
        this.now = new Date();
        this.fromDate = new Date(this.now.getTime() - this.SECONDS_SAMPLE * 1000);
        this.x.domain([this.fromDate,new Date(this.now.getTime() - 100)]);

        let translateTo = this.x(new Date(this.fromDate.getTime()).getUTCMilliseconds() - 100);

        // redraw the line
        this.svg.select(".line")
            .attr("d",this.line(this.data))
            .attr("transform",null)
            .transition()
            .attr("transform","translate(" + translateTo + ")");

        // slide the x-axis left
        this.axis.call(this.xAxis);

    }).transition().on("start",this.tick);
}

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-