(newbie question) dynamically add Signal as new data comes in from an EventSource? #1373
Replies: 3 comments 1 reply
-
|
Beta Was this translation helpful? Give feedback.
-
thanks! so here is a piece of code I came up with in it uses fancy shallow state updates to only update the part of the data corresponding to the label for the message it receives. import * as d3 from "https://cdn.skypack.dev/d3?dts";
import { useEffect, useState } from "preact/hooks";
import DataContext from "../contexts/DataContext.tsx";
import { META_SPECIAL_LABEL } from "../types/data.ts";
import {
isRawPatientMetaMessage,
isRawPointMessage,
isRawTimeSeriesMessage,
isRawVectorMessage,
RawMessage,
} from "../types/message.ts";
import { maybe_convert_to_date, normalise_bed_label } from "../common.ts";
function state_modify_factory(msg: RawMessage) {
if (isRawPointMessage(msg) || isRawVectorMessage(msg)) {
return (
(prev_state) => ({
...prev_state,
[msg.pid]: {
...prev_state[msg.pid],
[msg.lbl]: [
...((msg.pid in prev_state) && (msg.lbl in prev_state[msg.pid])
? prev_state[msg.pid][msg.lbl]
: []),
{ val: msg.val, ts: d3.isoParse(msg.ts_recv) },
],
},
})
);
} else if (isRawPatientMetaMessage(msg)) {
const meta = {
"gender": msg["gender"],
"ipp": msg["ipp"],
"first_name": msg["first_name"],
"last_name": msg["last_name"],
"nbl": normalise_bed_label(msg["nbl"]),
"dob": maybe_convert_to_date(msg["dob"]),
"dtbegin": maybe_convert_to_date(msg["dtbegin"]),
};
return (
(prev_state) => ({
...prev_state,
[msg.pid]: {
...prev_state[msg.pid],
[META_SPECIAL_LABEL]: [meta],
},
})
);
} else if (isRawTimeSeriesMessage(msg)) {
console.warn(
`got time series message which is not expected lbl=${msg.lbl}`,
);
return ((prev_state) => prev_state);
} else {
throw Error(`got unknown msg: ${msg}`);
}
}
export default function DataAware({ children }) {
const [data, setData] = useState({});
let es: EventSource;
useEffect(() => {
es = new EventSource("http://localhost:8888/data");
es.onopen = () => {
console.log("connected to server-sent-event data stream");
};
es.onmessage = (event) => {
const msg = JSON.parse(event.data);
setData(state_modify_factory(msg));
console.log(data);
};
}, []);
return (
<DataContext.Provider value={data}>
{children}
</DataContext.Provider>
);
} and the corresponding import { createContext } from "preact";
const DataContext = createContext({});
export default DataContext; and the import { AppProps } from "$fresh/server.ts";
import Header from "../components/Header.tsx";
import { Head } from "$fresh/runtime.ts";
import DataAware from "../islands/DataAware.tsx";
export default function App({ Component, route }: AppProps) {
return (
<DataAware>
<div class="wrapper">
<Header route={route} />
<Component />
</div>
</DataAware>
);
} and the actual component being displayed import { Head } from "$fresh/runtime.ts";
import { useContext } from "preact/hooks";
import DataContext from "../contexts/DataContext.tsx";
export default function MyComponent() {
const data = useContext(DataContext);
return (
<>
<div class="p-4 mx-auto max-w-screen-lg">
Plot will be here
<p>
Current data : {data.value}
</p>
</div>
</>
);
} my any idea? |
Beta Was this translation helpful? Give feedback.
-
hmm, actually the data seems to be correctly set when adding this to my useEffect(() => {
console.log(data);
}, [data]); i see that the state is indeed being updated... i'm wondering why displaying the data with (again, i'm new to all of this, so i'm probably missing some basic understanding of how (p)react works) thanks a ton @marvinhagemeister for answering my newbie questions! |
Beta Was this translation helpful? Give feedback.
-
I have a very specific question regarding a real-time medical research data visualisation app that I am building in a French hospital.
I have a Python backend that consumes data with a high temporal resolution (high frequency) from a Kafka broker, calculates some lower-frequency signals from this data, and then exposes it through an EventSource server.
My Fresh server runs on the same machine as the Python backend, and exposes the real-time visualisation application to doctors.
On the client side, I want the client to directly connect to the Python backend's EventSource server to subscribe to streams of data.
Each data point that is coming through has a "label". Each plot has a specific set of labels that it's going to subscribe to, and use for its particular visualisation.
Plots might share labels (e.g. PlotA and PlotB will both subscribe to label
xyz
).I am wondering how to structure this with Fresh. And in particular:
Signal
as new labels are being subscribed to? My thinking is that a plot should be updated only when data with the labels it's subscribing to received new data. i.e. if labely
comes in but the current plot being displayed doesn't care about labely
, then it should not be updated (useless recalculation).In general, being new to (p)react and Fresh, I am still a bit confused by all these concepts.
If someone more experienced with Fresh and preact could give her two cents that would be great!
Thanks :)
Beta Was this translation helpful? Give feedback.
All reactions