Skip to content
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
202 changes: 74 additions & 128 deletions Dashboard/Controls/DefaultTraceContent.xaml

Large diffs are not rendered by default.

78 changes: 8 additions & 70 deletions Dashboard/Controls/DefaultTraceContent.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,13 @@ public partial class DefaultTraceContent : UserControl
private DateTime? _defaultTraceEventsToDate;
private string? _defaultTraceEventsFilter;

private int _traceAnalysisHoursBack = 24;
private DateTime? _traceAnalysisFromDate;
private DateTime? _traceAnalysisToDate;

// Popup filter state (shared popup, per-grid filter dictionaries)
// Popup filter state
private Popup? _filterPopup;
private ColumnFilterPopup? _filterPopupContent;
private string? _activeFilterGrid;

private readonly Dictionary<string, ColumnFilterState> _defaultTraceFilters = new();
private List<DefaultTraceEventItem>? _defaultTraceUnfilteredData;

private readonly Dictionary<string, ColumnFilterState> _traceAnalysisFilters = new();
private List<TraceAnalysisItem>? _traceAnalysisUnfilteredData;

public DefaultTraceContent()
{
InitializeComponent();
Expand All @@ -58,28 +50,19 @@ public void SetTimeRange(int hoursBack, DateTime? fromDate = null, DateTime? toD
_defaultTraceEventsHoursBack = hoursBack;
_defaultTraceEventsFromDate = fromDate;
_defaultTraceEventsToDate = toDate;

_traceAnalysisHoursBack = hoursBack;
_traceAnalysisFromDate = fromDate;
_traceAnalysisToDate = toDate;
}

public async Task RefreshAllDataAsync()
{
if (_databaseService == null) return;

await Task.WhenAll(
RefreshDefaultTraceEventsAsync(),
RefreshTraceAnalysisAsync()
);
await RefreshDefaultTraceEventsAsync();
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
TabHelpers.AutoSizeColumnMinWidths(DefaultTraceEventsDataGrid);
TabHelpers.AutoSizeColumnMinWidths(TraceAnalysisDataGrid);
TabHelpers.FreezeColumns(DefaultTraceEventsDataGrid, 1);
TabHelpers.FreezeColumns(TraceAnalysisDataGrid, 1);
}

#region Default Trace Events
Expand Down Expand Up @@ -130,45 +113,14 @@ private async Task RefreshDefaultTraceEventsAsync()

#endregion

#region Trace Analysis

private async Task RefreshTraceAnalysisAsync()
{
if (_databaseService == null) return;

try
{
var data = await _databaseService.GetTraceAnalysisAsync(_traceAnalysisHoursBack, _traceAnalysisFromDate, _traceAnalysisToDate);
_traceAnalysisUnfilteredData = data;
_traceAnalysisFilters.Clear();
TraceAnalysisDataGrid.ItemsSource = data;
TraceAnalysisNoDataMessage.Visibility = data.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
UpdateFilterButtonStyles(TraceAnalysisDataGrid, _traceAnalysisFilters);
}
catch (Exception ex)
{
Logger.Error($"Error loading trace analysis: {ex.Message}");
}
}

#endregion

#region Popup Filter Infrastructure

private void DefaultTraceFilter_Click(object sender, RoutedEventArgs e)
{
_activeFilterGrid = "DefaultTrace";
if (sender is Button button && button.Tag is string columnName)
ShowFilterPopup(button, columnName, _defaultTraceFilters);
}

private void TraceAnalysisFilter_Click(object sender, RoutedEventArgs e)
{
_activeFilterGrid = "TraceAnalysis";
if (sender is Button button && button.Tag is string columnName)
ShowFilterPopup(button, columnName, _traceAnalysisFilters);
}

private void ShowFilterPopup(Button button, string columnName, Dictionary<string, ColumnFilterState> filters)
{
if (_filterPopup == null)
Expand Down Expand Up @@ -197,26 +149,12 @@ private void FilterPopup_FilterApplied(object? sender, FilterAppliedEventArgs e)
if (_filterPopup != null)
_filterPopup.IsOpen = false;

switch (_activeFilterGrid)
{
case "DefaultTrace":
if (e.FilterState.IsActive)
_defaultTraceFilters[e.FilterState.ColumnName] = e.FilterState;
else
_defaultTraceFilters.Remove(e.FilterState.ColumnName);
ApplyFilters(_defaultTraceFilters, _defaultTraceUnfilteredData, DefaultTraceEventsDataGrid, DefaultTraceEventsNoDataMessage);
UpdateFilterButtonStyles(DefaultTraceEventsDataGrid, _defaultTraceFilters);
break;

case "TraceAnalysis":
if (e.FilterState.IsActive)
_traceAnalysisFilters[e.FilterState.ColumnName] = e.FilterState;
else
_traceAnalysisFilters.Remove(e.FilterState.ColumnName);
ApplyFilters(_traceAnalysisFilters, _traceAnalysisUnfilteredData, TraceAnalysisDataGrid, TraceAnalysisNoDataMessage);
UpdateFilterButtonStyles(TraceAnalysisDataGrid, _traceAnalysisFilters);
break;
}
if (e.FilterState.IsActive)
_defaultTraceFilters[e.FilterState.ColumnName] = e.FilterState;
else
_defaultTraceFilters.Remove(e.FilterState.ColumnName);
ApplyFilters(_defaultTraceFilters, _defaultTraceUnfilteredData, DefaultTraceEventsDataGrid, DefaultTraceEventsNoDataMessage);
UpdateFilterButtonStyles(DefaultTraceEventsDataGrid, _defaultTraceFilters);
}

private void FilterPopup_FilterCleared(object? sender, EventArgs e)
Expand Down
76 changes: 57 additions & 19 deletions Dashboard/Controls/MemoryContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,28 +133,66 @@

<!-- Memory Clerks Sub-Tab -->
<TabItem Header="Memory Clerks">
<!-- Chart + Summary Panel (grid removed) -->
<Border BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Top Memory Clerks Over Time" FontWeight="Bold" FontSize="14" Margin="10,5" Foreground="{DynamicResource ForegroundBrush}"/>
<ScottPlot:WpfPlot Grid.Row="1" x:Name="MemoryClerksChart"/>
<!-- Summary Panel (excludes buffer pool) -->
<Border Grid.Row="2" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="10,8">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="Non-BP Total:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryClerksTotalText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
<TextBlock Text="Top Non-BP Clerk:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryClerksTopText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="220"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<!-- Clerk Type Picker -->
<Border Grid.Column="0" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,0,1,0" Padding="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Select Memory Clerks" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundBrush}" Margin="0,0,0,4"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,4">
<Button Content="Top Clerks" Click="MemoryClerkSelectTop_Click" Padding="6,2" Margin="0,0,4,0" FontSize="11"/>
<Button Content="Clear All" Click="MemoryClerkClearAll_Click" Padding="6,2" FontSize="11"/>
<TextBlock x:Name="MemoryClerkCountText" Text="0 selected" FontSize="10" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="8,0,0,0"/>
</StackPanel>
<TextBox Grid.Row="2" x:Name="MemoryClerkSearchBox" TextChanged="MemoryClerkSearch_TextChanged"
Margin="0,0,0,4" Padding="4,2"/>
<ListBox Grid.Row="3" x:Name="MemoryClerksList" Background="Transparent" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}"
Checked="MemoryClerk_CheckChanged" Unchecked="MemoryClerk_CheckChanged"
Foreground="{DynamicResource ForegroundBrush}" FontSize="11">
<TextBlock Text="{Binding DisplayName}"/>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
<TextBlock x:Name="MemoryClerksNoDataMessage" Grid.Row="1" Style="{StaticResource EmptyStateMessage}"
Text="No memory clerk data in selected time range"/>
<controls:LoadingOverlay x:Name="MemoryClerksLoading" Grid.Row="1"/>

<!-- Chart + Summary -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Memory Clerks Over Time" FontWeight="Bold" FontSize="14" Margin="10,5" Foreground="{DynamicResource ForegroundBrush}"/>
<ScottPlot:WpfPlot Grid.Row="1" x:Name="MemoryClerksChart"/>
<!-- Summary Panel (excludes buffer pool) -->
<Border Grid.Row="2" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Padding="10,8">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="Non-BP Total:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryClerksTotalText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center" Margin="0,0,20,0"/>
<TextBlock Text="Top Non-BP Clerk:" FontWeight="SemiBold" Foreground="{DynamicResource ForegroundDimBrush}" VerticalAlignment="Center" Margin="0,0,5,0"/>
<TextBlock x:Name="MemoryClerksTopText" Text="N/A" Foreground="{DynamicResource ForegroundBrush}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
<TextBlock x:Name="MemoryClerksNoDataMessage" Grid.Row="1" Style="{StaticResource EmptyStateMessage}"
Text="No memory clerk data in selected time range"/>
<controls:LoadingOverlay x:Name="MemoryClerksLoading" Grid.Row="1"/>
</Grid>
</Grid>
</Border>
</TabItem>
Expand Down
Loading
Loading