我正在相对于时间轴绘制移动式加速度计的实时数据。x-axis
将有时间,y-axis
将显示加速度计的值。我正在使用react-native-highcharts
绘制数据。但是输出图为空白。实时数据绘图的代码在URL https://github.com/TradingPal/react-native-highcharts处给出。在这段代码中,我只是将y
替换为加速度计的x-values
。我正在渲染的东西在这里
import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Accelerometer } from 'expo-sensors';
import ChartView from 'react-native-highcharts';
export default class AccelerometerSensor extends React.Component {
constructor(props){
super(props);
}
state = {
accelerometerData: {},
dataArr:[],
};
componentDidMount() {
this._toggle();
}
componentWillUnmount() {
this._unsubscribe();
}
_toggle = () => {
if (this._subscription) {
this._unsubscribe();
} else {
this._subscribe();
}
};
_slow = () => {
Accelerometer.setUpdateInterval(1000);
};
_fast = () => {
Accelerometer.setUpdateInterval(16);
};
_subscribe = () => {
this._subscription = Accelerometer.addListener(accelerometerData => {
this.setState({ accelerometerData });
});
};
_unsubscribe = () => {
this._subscription && this._subscription.remove();
this._subscription = null;
};
render() {
let { xx, y, z } = this.state.accelerometerData;
var Highcharts='Highcharts';
var conf={
chart: {
type: 'spline',
//animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = round(z);
series.addPoint([x, y], true, true);
},1000);
}
}
},
title: {
text: 'Live accelerometer data'
},
xAxis: {
type: 'datetime',
// tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
// tooltip: {
// formatter: function () {
// return '<b>' + this.series.name + '</b><br/>' +
// Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
// Highcharts.numberFormat(this.y,2);
// }
// },
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'xValue',
data: (function () {
// generate an array of random data
for (i = -19; i <= 0; i += 1) {
var data = [],
time = (new Date()).getTime(),i
;
data.push({
x: time + i * 1000,
y: round(z)
});
}
return data;
}())
}]
};
const options = {
global: {
useUTC: false
},
lang: {
decimalPoint: ',',
thousandsSep: '.'
}
};
return (
<View style={styles.sensor}>
<Text style={styles.text}>Accelerometer: (in Gs where 1 G = 9.81 m s^-2)</Text>
<Text style={styles.text}>
xx: {round(xx)} y: {round(y)} z: {round(z)}
</Text>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={this._toggle} style={styles.button}>
<Text>Toggle</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._slow} style={[styles.button, styles.middleButton]}>
<Text>Slow</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._fast} style={styles.button}>
<Text>Fast</Text>
</TouchableOpacity>
<ChartView style={{height:300}} config={conf} options={options}></ChartView>
</View>
</View>
);
}
}
function round(n) {
if (!n) {
return 0;
}
return Math.floor(n * 100) / 100;
}
const styles = StyleSheet.create({
buttonContainer: {
flexDirection: 'column',
alignItems: 'stretch',
marginTop: 15,
},
button: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#eee',
padding: 20,
},
middleButton: {
borderLeftWidth: 1,
borderRightWidth: 1,
borderColor: '#ccc',
},
sensor: {
marginTop: 45,
paddingHorizontal: 10,
},
// array: {
// padding: 50,
// },
text:{
textAlign: 'center'
}
});
状态应始终是不变的,并且只能通过调用setState
进行更改。如果像示例中那样直接对其进行突变,则组件将不会更新。
我建议您进一步了解React中的component state(与React Native相同),然后您将意识到如何重构对this.state.dataArr.push
等的调用。
[render
应该是纯函数的props
和state
。
因为我们看不到整个图片,所以只有render方法(以后请尝试发布完整的示例),我们只能在此处进行假设。
我想在您的其他一些代码中,您正在记录加速度计,并调用setState
来更改accelerometerData
。 (如果要通过常规分配直接更改它,请将其更改为setState
调用。)然后,不要使用dataArr
方法来使render
发生变异,而应使用相同的dataArr
调用来更改setState
。
ps.s。这仍然不是一个完美的解决方案,因为它仍将使用derived state,但这是另一个话题,并且要稍微高级一些。]
按原样,您的代码始终使用最新的加速度计数据,即,您始终绘制一个点(最新),因此该图似乎为空。