Skip to content

Improved Dashboard timeline time range management #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ public record TimelineState
/// Gets/sets a boolean value that indicates whether data is currently being gathered
/// </summary>
public bool Loading { get; set; } = false;
/// <summary>
/// Gets/sets a boolean value that indicates whether to keep the previous chart's time frame or to redraw it with the new data boundaries
/// </summary>
public bool KeepTimeRange { get; set; } = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public class TimelineStore(ICloudStreamsCoreApiClient cloudStreamsApi)
/// </summary>
public IObservable<bool> Loading => this.Select(state => state.Loading).DistinctUntilChanged();

/// <summary>
/// Gets an <see cref="IObservable{T}"/> used to observe <see cref="TimelineState.KeepTimeRange"/> changes
/// </summary>
public IObservable<bool> KeepTimeRange => this.Select(state => state.KeepTimeRange).DistinctUntilChanged();

/// <inheritdoc/>
public override async Task InitializeAsync()
{
Expand Down Expand Up @@ -108,6 +113,16 @@ public void RemoveStreamsReadOption(int index)
});
}

/// <summary>
/// Toggles the state's <see cref="TimelineState.KeepTimeRange"/>
/// </summary>
public void ToggleKeepTimeRange()
{
this.Reduce(state => state with {
KeepTimeRange = !state.KeepTimeRange
});
}

/// <summary>
/// Adds a <see cref="TimelineState.StreamsReadOptions"/> for the provided <see cref="PartitionReference"/> if none already exists
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
</div>
</div>
}
<div class="form-check me-3 pt-2">
<input class="form-check-input" type="checkbox" checked="@keepTimeRange" @onchange="_ => Store.ToggleKeepTimeRange()" id="keep-time-frame">
<label class="form-check-label" for="keep-time-frame">
Keep current time range
</label>
</div>
<Button Color="ButtonColor.Light" Outline="true" @onclick="_ => Store.AddStreamsReadOption()" Disabled="loading"><Icon Name="IconName.Plus"></Icon></Button>
</div>
</div>
Expand Down Expand Up @@ -87,6 +93,10 @@
/// </summary>
private bool loading = false;
/// <summary>
/// Indicates whether to keep the previous chart's time frame or to redraw it with the new data boundaries
/// </summary>
private bool keepTimeRange = false;
/// <summary>
/// The style applied to the cloud event tooltip
/// </summary>
private string cloudEventTooltipStyle = "";
Expand Down Expand Up @@ -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);
}

/// <inheritdoc/>
Expand All @@ -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);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
/// <param name="dataset">The event-drops dataset</param>
/// <param name="start">The moment the timeline starts</param>
/// <param name="end">The moment the timeline starts></param>
public async ValueTask RenderTimelineAsync(ElementReference domElement, DotNetObjectReference<Timeline>? dotnetReference, IEnumerable<TimelineLane> dataset, DateTimeOffset start, DateTimeOffset end)
public async ValueTask RenderTimelineAsync(ElementReference domElement, DotNetObjectReference<Timeline>? dotnetReference, IEnumerable<TimelineLane> dataset, DateTimeOffset start, DateTimeOffset end, bool keepTimeRange)

Check warning on line 48 in src/dashboard/CloudStreams.Dashboard/Services/EventDropsInterop.cs

View workflow job for this annotation

GitHub Actions / build (8.0.x)

Parameter 'keepTimeRange' has no matching param tag in the XML comment for 'EventDropsInterop.RenderTimelineAsync(ElementReference, DotNetObjectReference<Timeline>?, IEnumerable<TimelineLane>, DateTimeOffset, DateTimeOffset, bool)' (but other parameters do)
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("renderTimeline", domElement, dotnetReference, dataset, start, end);
await module.InvokeVoidAsync("renderTimeline", domElement, dotnetReference, dataset, start, end, keepTimeRange);
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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;
}

Expand Down
Loading