创建心率监测器
Creating a heart rate monitor
我一直在尝试使用 chart.js 创建一个心率监测器,但我对如何表示图表存在分歧。
我想按照这个演示的思路构建一些东西:
link to demo.
chart.js中的图表是这样制作的:
var data = {
labels: ["Heart Rate Monitor"],
datasets: [
{
label: "heart rate",
data: [65, 59, 80, 81, 56, 55, 40]
}
]
};
var myLineChart = new Chart(ctx).Line(data, {});
我们可以这样更新数据:
myLineChart.datasets[0].points[0].value = 50;
这会将数组中的第一个值:65 设置为 50。
所以我做了一些尝试来创建一个数组,其值看起来像演示,并将第一个元素移到最后,并将数组中的每个其他元素向下移动 (-1),并用值。这在一定程度上可行,但我无法改变我需要做的值的速度。
建议?
心电图是一段时间内心脏电 activity 的图表。这不是您的心率(但是 EKG 可以显示您的心率,因为它显示随着时间的推移在某些时间点电 activity 增加,给出平均心率)。
所以我不相信你甚至可以使用心率来生成类似于 EKG 的图表。
你可以使用 2 个系列,然后交换点数。您可能需要在点之间进行插值以平滑动画。
我使用了线性插值,但如果要获得更平滑的曲线,您可能会使用其他方法,但我相信如果您有实际数据,线性插值会很好。
function getActualData() {
var actualData = []
for (var m = 0; m < 20; m++)
actualData.push(45 + parseInt(Math.random() * 35))
return actualData;
}
var ANIMATIONSTEPS = 200;
var myLineChart;
var labels;
var animationStep;
setInterval(function () {
if (myLineChart === undefined) {
var actualData = getActualData();
// if we have only a few data points interpolate to fill out enough points to make the animation smooth
var interpolationSteps = Math.ceil(ANIMATIONSTEPS / actualData.length);
labels = []
var data = []
var blankData = []
for (var i = 0; i < (actualData.length - 1); i++) {
labels.push('')
data.push(actualData[i])
blankData.push(null)
// push interpolation
var difference = actualData[i + 1] - actualData[i];
var interpolationStep = 1 / interpolationSteps;
for (var j = 1; j < interpolationSteps; j++) {
labels.push('')
data.push(actualData[i] + difference * Chart.helpers.easingEffects["linear"](j * interpolationStep));
blankData.push(null)
}
}
labels.push('')
data.push(actualData[i])
blankData.push(null)
var data = {
labels: labels,
datasets: [
{
strokeColor: "rgba(243, 118, 27, 1)",
data: blankData
},
{
strokeColor: "transparent",
data: data
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
myLineChart = new Chart(ctx).Line(data, {
animation: false,
datasetFill: false,
pointDot: false,
datasetStrokeWidth: 5,
showTooltips: false,
scaleOverride: true,
scaleSteps: 12,
scaleStepWidth: 5,
scaleStartValue: 30,
scaleShowVerticalLines: false,
scaleShowLabels: false,
});
animationStep = 0;
}
// the actual animation
myLineChart.datasets[0].points[animationStep].value = myLineChart.datasets[1].points[animationStep].value
myLineChart.update();
animationStep++;
// start new cycle
if (animationStep >= labels.length) {
myLineChart.destroy();
myLineChart = undefined;
}
}, 10)
Fiddle - http://jsfiddle.net/t795k4j3/
我一直在尝试使用 chart.js 创建一个心率监测器,但我对如何表示图表存在分歧。
我想按照这个演示的思路构建一些东西: link to demo.
chart.js中的图表是这样制作的:
var data = {
labels: ["Heart Rate Monitor"],
datasets: [
{
label: "heart rate",
data: [65, 59, 80, 81, 56, 55, 40]
}
]
};
var myLineChart = new Chart(ctx).Line(data, {});
我们可以这样更新数据:
myLineChart.datasets[0].points[0].value = 50;
这会将数组中的第一个值:65 设置为 50。
所以我做了一些尝试来创建一个数组,其值看起来像演示,并将第一个元素移到最后,并将数组中的每个其他元素向下移动 (-1),并用值。这在一定程度上可行,但我无法改变我需要做的值的速度。
建议?
心电图是一段时间内心脏电 activity 的图表。这不是您的心率(但是 EKG 可以显示您的心率,因为它显示随着时间的推移在某些时间点电 activity 增加,给出平均心率)。
所以我不相信你甚至可以使用心率来生成类似于 EKG 的图表。
你可以使用 2 个系列,然后交换点数。您可能需要在点之间进行插值以平滑动画。
我使用了线性插值,但如果要获得更平滑的曲线,您可能会使用其他方法,但我相信如果您有实际数据,线性插值会很好。
function getActualData() {
var actualData = []
for (var m = 0; m < 20; m++)
actualData.push(45 + parseInt(Math.random() * 35))
return actualData;
}
var ANIMATIONSTEPS = 200;
var myLineChart;
var labels;
var animationStep;
setInterval(function () {
if (myLineChart === undefined) {
var actualData = getActualData();
// if we have only a few data points interpolate to fill out enough points to make the animation smooth
var interpolationSteps = Math.ceil(ANIMATIONSTEPS / actualData.length);
labels = []
var data = []
var blankData = []
for (var i = 0; i < (actualData.length - 1); i++) {
labels.push('')
data.push(actualData[i])
blankData.push(null)
// push interpolation
var difference = actualData[i + 1] - actualData[i];
var interpolationStep = 1 / interpolationSteps;
for (var j = 1; j < interpolationSteps; j++) {
labels.push('')
data.push(actualData[i] + difference * Chart.helpers.easingEffects["linear"](j * interpolationStep));
blankData.push(null)
}
}
labels.push('')
data.push(actualData[i])
blankData.push(null)
var data = {
labels: labels,
datasets: [
{
strokeColor: "rgba(243, 118, 27, 1)",
data: blankData
},
{
strokeColor: "transparent",
data: data
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
myLineChart = new Chart(ctx).Line(data, {
animation: false,
datasetFill: false,
pointDot: false,
datasetStrokeWidth: 5,
showTooltips: false,
scaleOverride: true,
scaleSteps: 12,
scaleStepWidth: 5,
scaleStartValue: 30,
scaleShowVerticalLines: false,
scaleShowLabels: false,
});
animationStep = 0;
}
// the actual animation
myLineChart.datasets[0].points[animationStep].value = myLineChart.datasets[1].points[animationStep].value
myLineChart.update();
animationStep++;
// start new cycle
if (animationStep >= labels.length) {
myLineChart.destroy();
myLineChart = undefined;
}
}, 10)
Fiddle - http://jsfiddle.net/t795k4j3/