我想使用 javascript 访问 Chart JS 中渐进折线图中的当前点,例如,每隔一秒在控制台上记录该线的当前值,其中动画的总持续时间为 20 秒。
可以用setInterval来实现吗?或者有没有更简单、不那么笨拙的方法?
事实上,你可以像 ChartJS 做动画一样设置间隔。因此,请潜入您拥有的动画延迟定义和一些代码。请注意,我们无法设置精确的延迟秒数,但我们必须为每个点使用延迟间隔,因为:
// Animation-----
const totalDuration = 10000; /* 10 seconds */
const delayBetweenPoints = totalDuration / data.length;
/* This delayBetweenPoints may be 100ms, or 33ms...
depending on data.length */
无论如何,你可以自己做一些计算,或者只公开一个值,例如以这种方式每 100 点图表数据,请查看代码底部:
// Animation-----
const totalDuration = 10000;
const delayBetweenPoints = totalDuration / data.length;
const previousY = (ctx) => ctx.index === 0 ? ctx.chart.scales.y.getPixelForValue(100) : ctx.chart.getDatasetMeta(ctx.datasetIndex).data[ctx.index - 1].getProps(['y'], true).y;
const animation = {
x: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: NaN, // the point is initially skipped
delay(ctx) {
if (ctx.type !== 'data' || ctx.xStarted) {
return 0;
}
ctx.xStarted = true;
return ctx.index * delayBetweenPoints;
}
},
y: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: previousY,
delay(ctx) {
if (ctx.type !== 'data' || ctx.yStarted) {
return 0;
}
ctx.yStarted = true;
/* HERE we output the value of each data row and
we use same delay between drawing the points: */
if( ctx.index%100==0 ) setTimeout(()=>{
console.log( ctx.raw.y );
}, ctx.index * delayBetweenPoints);
return ctx.index * delayBetweenPoints;
}
}
};
// Animation-----
您可以在this Fiddle上查看,或在下面:
// Data-----
const data = [];
const data2 = [];
let prev = 100;
let prev2 = 80;
for (let i = 0; i < 1000; i++) {
prev += 5 - Math.random() * 10;
data.push({x: i, y: prev});
prev2 += 5 - Math.random() * 10;
data2.push({x: i, y: prev2});
}
// Data-----
// Animation-----
const totalDuration = 10000;
const delayBetweenPoints = totalDuration / data.length;
const previousY = (ctx) => ctx.index === 0 ? ctx.chart.scales.y.getPixelForValue(100) : ctx.chart.getDatasetMeta(ctx.datasetIndex).data[ctx.index - 1].getProps(['y'], true).y;
const animation = {
x: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: NaN, // the point is initially skipped
delay(ctx) {
if (ctx.type !== 'data' || ctx.xStarted) {
return 0;
}
ctx.xStarted = true;
return ctx.index * delayBetweenPoints;
}
},
y: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: previousY,
delay(ctx) {
if (ctx.type !== 'data' || ctx.yStarted) {
return 0;
}
ctx.yStarted = true;
/* HERE we output the value of each data row and
we use same delay between drawing the points: */
if( ctx.index%100==0 ) setTimeout(()=>{
console.log( ctx.raw.y );
}, ctx.index * delayBetweenPoints);
return ctx.index * delayBetweenPoints;
}
}
};
// Animation-----
// Config-----
const config = {
type: 'line',
data: {
datasets: [{
borderColor: "#ff0000",
borderWidth: 1,
radius: 0,
data: data,
},
{
borderColor: "#00FFFF",
borderWidth: 1,
radius: 0,
data: data2,
}]
},
options: {
animation,
interaction: {
intersect: false
},
plugins: {
legend: false
},
scales: {
x: {
type: 'linear'
}
}
}
};
// Config-----
var myChart = new Chart(
document.getElementById('myChart'),
config
);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div>
<canvas id="myChart"></canvas>
</div>