如何解决使用D3.js在Typescript中将HeartBeat从v3转换为v4
我成功使用此link中的D3.js转换了HeartBeat:
从Typescript中的v3到v4。
由于某种原因,我收到以下错误消息
在“ 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 举报,一经查实,本站将立刻删除。