in src/Chart.tsx [248:385]
color: getRandomColor(),
},
}));
}
setData(current => ({
...current,
[id]: {
...current[id],
values: [
...(current[id]?.values ?? []),
{timestamp: new Date().toISOString(), value},
],
},
}));
}
},
[telemetryId, metadata],
);
const getChartCompatibleData = React.useCallback(
(telemetryData: TelemetryData) =>
Object.keys(telemetryData).reduce<ChartData[]>(
(chartData, telemId) => [
...chartData,
{
[telemId]: {
[metadata[telemId].displayName]: telemetryData[
telemId
].values.reduce<SeriesData>(
(values, value) => ({
...values,
[value.timestamp]: {
[telemId]: value.value,
},
}),
{},
),
},
},
],
[],
),
[metadata],
);
React.useEffect(() => {
const sensor = SensorMap[telemetryId]; // || HealthMap[telemetryId];
sensor?.addListener(DATA_AVAILABLE_EVENT, updateData);
// init chart with current value
if (currentValue !== undefined) {
updateData(telemetryId, currentValue);
}
return () => {
sensor?.removeListener(DATA_AVAILABLE_EVENT, updateData);
};
}, [telemetryId, currentValue, updateData]);
// Init chart or update it with new data
React.useEffect(() => {
if (Object.keys(data).length === 0) {
return;
}
const run = `
if(!tsiClient){
tsiClient = new TsiClient();
}
if(!lineChart){
lineChart = new tsiClient.ux.LineChart(document.getElementById('chart1'));
}
data=${JSON.stringify(getChartCompatibleData(data))};
lineChart.render(data, ${JSON.stringify(
chartOptions,
)}, ${JSON.stringify(chartDataOptions)});
true;
`;
chartRef.current?.injectJavaScript(run);
}, [data, chartOptions, chartDataOptions, getChartCompatibleData]);
if (chartType === ChartType.MAP) {
return (
<View style={styles.mapContainer}>
<Map style={styles.map} location={currentValue} />
<View style={style.summary}>
<Text>
<Name>Latitude:</Name> {currentValue.lat}
</Text>
<Text>
<Name>Longitude:</Name> {currentValue.lon}
</Text>
</View>
</View>
);
}
return (
<>
{Object.keys(data).length === 0 ? (
<Loader message="" visible={true} />
) : (
<View style={style.container}>
<View style={style.chart}>
<WebView
originWhitelist={['*']}
containerStyle={styles.webView}
ref={chartRef}
source={{
html,
}}
startInLoadingState={true}
// use theme background color when chart is loading
// style allows to cover all webview space as per issue:
// https://github.com/react-native-webview/react-native-webview/issues/1031
renderLoading={() => <View style={styles.loading} />}
/>
<View style={style.summary}>
<View style={styles.summary}>
{Object.keys(data).map((telId, i) => {
const telemetry = data[telId];
if (!telemetry) {
return null;
}
const avg =
telemetry.values.map(v => v.value).reduce((a, b) => a + b) /
telemetry.values.length;
const fill = avg > 1 || avg < -1 ? avg : Math.abs(avg * 1000);
return (
<AnimatedCircularProgress
key={`circle - ${i}`}
size={screen.width / 5}
width={5}
fill={fill}
tintColor={metadata[telId].color}
backgroundColor={LightenDarkenColor(
metadata[telId].color,
90,
true,
)}
rotation={360}>
{() => {