KeepTimeRange => this.Select(state => state.KeepTimeRange).DistinctUntilChanged();
+
///
public override async Task InitializeAsync()
{
@@ -108,6 +113,16 @@ public void RemoveStreamsReadOption(int index)
});
}
+ ///
+ /// Toggles the state's
+ ///
+ public void ToggleKeepTimeRange()
+ {
+ this.Reduce(state => state with {
+ KeepTimeRange = !state.KeepTimeRange
+ });
+ }
+
///
/// Adds a for the provided if none already exists
///
diff --git a/src/dashboard/CloudStreams.Dashboard/Components/Timeline/Timeline.razor b/src/dashboard/CloudStreams.Dashboard/Components/Timeline/Timeline.razor
index b8a22fa1..95cfb861 100644
--- a/src/dashboard/CloudStreams.Dashboard/Components/Timeline/Timeline.razor
+++ b/src/dashboard/CloudStreams.Dashboard/Components/Timeline/Timeline.razor
@@ -25,6 +25,12 @@
}
+
+ Store.ToggleKeepTimeRange()" id="keep-time-frame">
+
+
@@ -87,6 +93,10 @@
///
private bool loading = false;
///
+ /// Indicates whether to keep the previous chart's time frame or to redraw it with the new data boundaries
+ ///
+ private bool keepTimeRange = false;
+ ///
/// The style applied to the cloud event tooltip
///
private string cloudEventTooltipStyle = "";
@@ -131,8 +141,8 @@
await base.OnInitializedAsync().ConfigureAwait(false);
this.Store.StreamsReadOptions.Subscribe(streamsReadOptions => this.OnStateChanged(cmp => cmp.streamsReadOptions = streamsReadOptions), token: this.CancellationTokenSource.Token);
this.Store.Loading.Subscribe(processing => this.OnStateChanged(cmp => cmp.loading = processing), token: this.CancellationTokenSource.Token);
- this.Store.TimelineLanes.SubscribeAsync(async timelineLanes => await this.RenderTimelineAsync(timelineLanes), null, null, cancellationToken: this.CancellationTokenSource.Token);
-
+ this.Store.KeepTimeRange.Subscribe(keepTimeRange => this.OnStateChanged(cmp => cmp.keepTimeRange = keepTimeRange), token: this.CancellationTokenSource.Token);
+ this.Store.TimelineLanes.SubscribeAsync(async timelineLanes => await this.RenderTimelineAsync(timelineLanes), null!, null!, cancellationToken: this.CancellationTokenSource.Token);
}
///
@@ -156,20 +166,24 @@
{
return;
}
- var entries = timelineLanes.SelectMany(lane => lane.Data).OrderBy(data => data.Time!.Value);
- if (!entries.Any())
+ var timeEntries = timelineLanes
+ .SelectMany(lane => lane.Data)
+ .Where(data => data.Time != null)
+ .Select(data => data.Time!.Value)
+ .OrderBy(time => time);
+ if (!timeEntries.Any())
{
return;
}
- var start = entries.First().Time!.Value;
- var end = entries.Last().Time!.Value;
+ var start = timeEntries.First();
+ var end = timeEntries.Last();
var delta = end.Subtract(start).TotalMilliseconds;
if (delta == 0)
{
delta = 20;
}
var margin = delta / 20;
- await this.eventDropsInterop.RenderTimelineAsync(this.timeline, this.dotnetReference, timelineLanes, start, end.AddMilliseconds(margin));
+ await this.eventDropsInterop.RenderTimelineAsync(this.timeline, this.dotnetReference, timelineLanes, start, end.AddMilliseconds(margin), this.keepTimeRange);
}
///
diff --git a/src/dashboard/CloudStreams.Dashboard/Services/EventDropsInterop.cs b/src/dashboard/CloudStreams.Dashboard/Services/EventDropsInterop.cs
index b2b4280d..37dc3520 100644
--- a/src/dashboard/CloudStreams.Dashboard/Services/EventDropsInterop.cs
+++ b/src/dashboard/CloudStreams.Dashboard/Services/EventDropsInterop.cs
@@ -45,10 +45,10 @@ public EventDropsInterop(IJSRuntime jsRuntime)
/// The event-drops dataset
/// The moment the timeline starts
/// The moment the timeline starts>
- public async ValueTask RenderTimelineAsync(ElementReference domElement, DotNetObjectReference? dotnetReference, IEnumerable dataset, DateTimeOffset start, DateTimeOffset end)
+ public async ValueTask RenderTimelineAsync(ElementReference domElement, DotNetObjectReference? dotnetReference, IEnumerable dataset, DateTimeOffset start, DateTimeOffset end, bool keepTimeRange)
{
var module = await moduleTask.Value;
- await module.InvokeVoidAsync("renderTimeline", domElement, dotnetReference, dataset, start, end);
+ await module.InvokeVoidAsync("renderTimeline", domElement, dotnetReference, dataset, start, end, keepTimeRange);
}
///
diff --git a/src/dashboard/CloudStreams.Dashboard/wwwroot/js/event-drops-interop.js b/src/dashboard/CloudStreams.Dashboard/wwwroot/js/event-drops-interop.js
index d9cd8b42..28b8605f 100644
--- a/src/dashboard/CloudStreams.Dashboard/wwwroot/js/event-drops-interop.js
+++ b/src/dashboard/CloudStreams.Dashboard/wwwroot/js/event-drops-interop.js
@@ -14,7 +14,7 @@
let previousChart;
-export function renderTimeline(el, dotnetRef, dataset, start, end) {
+export function renderTimeline(el, dotnetRef, dataset, start, end, keepTimeRange) {
const chart = eventDrops({
...baseConfig,
range: {
@@ -36,9 +36,12 @@ export function renderTimeline(el, dotnetRef, dataset, start, end) {
.select(el)
.data([dataset])
.call(chart);
- if (!!previousChart) {
+ if (keepTimeRange && !!previousChart) {
chart.zoomToDomain(previousChart.scale().domain());
}
+ else {
+ chart.zoomToDomain(chart.scale().domain());
+ }
previousChart = chart;
}