Closed Spongman closed 5 years ago
Isn't that very similar to the live chart demo in the website? Both x- and y-values change. You only need to replace the random data in that onReceive
function with data sent by the back-end VM.
no, not really. the problem with the live chart demo is that it's assumed that the cardinality of the x-values are always the same and that's only the y-values thatchange. it's also implemented in such a way as the whole data set changes each event. this has the effect that the points in the graph only move vertically, whereas in a real value vs. time graph, the data points move horizontally and appear from the right-hand side.
for example, contrast this example: http://dotnetify.net/core/examples/livechart
with the example i gave above: https://nagix.github.io/chartjs-plugin-streaming/samples/push.html
in the 1st (livechart) example, each time a new datum arrives, every point in the graph animates from one data point to another. the animation seems to indicate that the data values are changing, where in fact it's the x-axis that's changing. whereas, in the 2nd example, each point in the graph always corresponds to the same data point (until is scrolls off the left side).
also, and perhaps most importantly, the livechart example doesn't handle irregular data streams such that the number of points that appear on the graph may change over time.
I got it, you're focused on the animation of the chart. What I meant with 'similar' was, that in terms of data coming from the back-end, there's no difference. You could use the same dotNetify view model from the live demo and just replace the client-side chart rendering code to achieve this.
i don't think it's just limited to the animation, i think that the VM has to handle a stream of data points, not just an array. as far as i can tell, the current example code just overwrites the entire state of the chart with a new array each time an event arrives, whereas what i want is just to stream each new data item in as it arrives.
If you open up your browser's console log on that live demo, you'd see that the line chart data (waveform) only sends the latest value, not the entire set.
ah, great. so how do i get that value?
Which client-side library are you using? React, Vue?
The live chart demo has been updated to use the chart streaming plugin. Thank's for letting me know about the library; the demo looks much better now.
Oh, that’s fantastic. Thanks so much!
so i noticed that the example is using AddList
and PushUpdates
. is it possible to hook this up directly to an IObservable<T>
?
i tried doing AddProperty<>().SubscribeTo()
but nothing gets sent to the client when the observable's OnNext
is called.
No, not supported at the moment, but you can create your own extension method.
I can help if you give me your code snippet and explain your intent. Or look at the examples in the website; there are plenty of them, especially in 'Elements' demo, that use AddProperty<>().SubscribeTo
.
yeah, i found this:
AddProperty<string>("Clock")
.SubscribeTo(rxTimer.Select(_ => DateTime.Now.ToString("hh:mm:ss tt")))
.SubscribedBy(AddInternalProperty<bool>("Update"), _ => { PushUpdates(); return true; });
but i don't understand what's going on here.
why is it necessary to do the SubscribedBy
stuff? surely if a VM property is subscribed to an IObservable, shouldn't it automatically push updates to the browser when the observable updates? i don't understand what the SubscribedBy
is for. in what case does it make sense to be subscribed to an IObservable and not push updates to the browser?
PushUpdates
is only required when the data update is not part of the synchronous flow initiated by a client's request. In the above case, the timer update originates from the server code, and thus requires explicit call to push the update to the client.
As to why that's even necessary, it's due to the fact that update is sent across the network with some degree of latency, and so there has to be a mechanism to allow the developer control over when the update should occur. PushUpdates
does not just update a particular property, but every property in every view model on the same connection that has changed.
ah, that makes sense, thanks.
ok, i'm still having trouble with this.
firstly, i don't understand where the "Update"
comes from in the example code above. What is that property name, who defines it, and who's causing that handler to get invoked?
Besides that, the Update
handler does get invoked, and the value of _
is the value that has been pushed into the IObservable
, but the value that makes it to the browser is an old value.
Also, is PushUpdates()
going to do anything if i'm just subscribed to an IObservable
? Do i need to explicitly tell it that a propoerty has changed? or is that handled automatically by the subscription?
The Update
is a runtime property that gets created by AddInternalProperty
. Its only purpose is to enable method chaining.
As I mentioned, you will need to explicitly call PushUpdates
if it's either server-initiated or an async operation. Properties added through AddProperty
won't need to be explicitly called out when their values changed.
Perhaps rewriting it in an imperative manner will make it easier to understand:
public class ClockVM : BaseVM
{
private readonly Timer _timer;
public string Clock { get; set; }
public ClockVM()
{
_timer = new Timer(state =>
{
Clock = DateTime.Now.ToString("hh:mm:ss tt");
Changed(nameof(Clock)); // Mark the 'Clock' property value as changed.
PushUpdates(); // Push all changed property values to the client.
}, null, 0, 1000); // every 1000 ms.
}
public override void Dispose()
{
_timer.Dispose();
}
}
is there any chance you can add an example of using the API with explicit streaming?
i'm looking to integrate something like
chartjs-plugin-streaming
where the items in my IObservable are pushed one-at-a-time to the chart, like this:https://nagix.github.io/chartjs-plugin-streaming/samples/push.html
just updating an array of values results in a graph whose x-axis stays stationary and the y-values change. but this is inappropriate for a graph over time (eg, a graph of network traffic, or stock prices) where you want the points to scroll to the left.