Communication Over Time: focus a summary trace on a time range and a subset of entry methods - #167
Merged
Merged
Conversation
The chart stacks every entry method that processed a message, and one of them commonly has two orders of magnitude more than the rest, which flattens everything else into the axis. Ticking one off in "Choose Entry Colors" now drops it from the chart, the totals line and the legend, so the y axis rescales to what is left. The dialog already supports a visibility column -- Timeline uses it -- but the graph tools' path into it hardcoded colors-only. That is now a hook, entryFilterAllowsHiding(), which only this tool answers yes to; every other GenericGraphWindow tool opens the dialog exactly as before. Its list is still restricted to the entry methods present in the loaded range, and switched-off ones stay listed, since the dialog is the only way to switch them back on.
A run of a few seconds at millisecond resolution puts thousands of intervals on the chart, and the interesting stretch is usually a fraction of one. Dragging across the plot now narrows it to that stretch, with a Reset Zoom button to go back to the whole loaded range. Both axes follow: only the selected slice is handed to the chart, so the stacked maximum is recomputed from it and the x axis is re-based onto the first interval on show. So does the entry chooser -- the entry methods it lists, and the totals and legend, are those of the window being looked at, which on a large trace is the difference between a handful of entries and several hundred. Zooming re-slices data already in memory rather than re-reading the trace, so it is free at a few thousand PEs, but it cannot show finer bins than the range dialog loaded; a shorter range still has to be loaded for that. The rubber band itself is Graph.setXRangeSelectionListener, filling in mouse handlers that were empty stubs. A tool that registers no listener sees no change at all.
Most entry methods in range on a large trace are a handful of setup calls against millions of messages -- 50 of the 78 in range on a 1792 PE summary trace have under 100 events each. Listed by entry method id, the ones that matter are scattered among them, and a user looking for the entry method that is actually on the chart has to read the whole list. getEntriesArray() already returns numbers rather than flags (Timeline returns real frequencies), so a tool can now opt in with sortEntriesByCount(): its list is ordered largest first, the counts get a column, and anything under a thousandth of the busiest is greyed at the bottom -- present in the range, but nothing on a chart. Only Messages Over Time opts in; every other chooser keeps the list and columns it had. MyTableModel had the column count and the editable columns hardcoded by position, which the extra column breaks. Both are now taken from the data: as a side effect the id column is no longer editable, which it has been all along, letting a user type over an entry method's id to no effect whatever.
Loading a range ran two passes over the run length data, one for counts and one for sizes, each costing PEs x intervals x entry methods and each showing its own progress bar. The second one is usually for nothing: a trace written by a charm that does not record message sizes has no such line in its .sumd files, so the pass walks empty data on every PE to produce an array of zeros that the Bytes view then declines to draw. Sizes now expand the first time something needs them, which is the first switch to the Bytes view. That switch, and a range reload made while Bytes is showing, both do the work off the event thread -- on the event thread the progress bar cannot paint and the window would simply hang.
A millisecond interval on a real run is noisy enough that the chart's shape is hard to read. A Smoothing button now offers two ways to combine intervals, and a special case of the first. Combining every k intervals sums them into one bar, so the totals are preserved exactly and a bar means the messages of the intervals under it; a partial last bin is kept rather than dropped, which would lose messages. A moving average keeps one bar per interval and puts the mean of the k around it in each, averaging over what exists at the edges rather than inventing data. The special case is k equal to the whole visible range: one bar whose stacked bands are the totals per entry method over the range on screen. What follows from a bar no longer being an interval: rates divide by the time the bar spans rather than by one interval, popups name the span of intervals a bar covers and say when a value is an average, and a drag to zoom converts the bars it selected back into intervals. Zooming and smoothing compose -- the whole-range case re-reads the zoom every time it draws, so narrowing the view re-totals it.
lvkale
requested review from
ericjbohm,
matthiasdiener and
ritvikrao
as code owners
August 13, 2026 20:50
ritvikrao
approved these changes
Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-on to #166, from using it on a 1792 PE Frontier summary trace (14995 intervals of 1 ms, 440 entry methods). Everything here is about finding the part of such a chart worth looking at.
Five commits, each building on its own.
Switch entry methods off from the entry chooser. The chart stacks every entry method that processed a message, and one commonly has two orders of magnitude more than the rest, flattening the others into the axis. Ticking one off in "Choose Entry Colors" drops it from the chart, the totals and the legend, so the y axis rescales to what is left. The dialog already had a visibility column (Timeline uses it); the graph tools' path into it hardcoded colors-only, and that is now the
entryFilterAllowsHiding()hook, which only this tool answers yes to.Drag to zoom the time axis. Dragging across the plot narrows it to that stretch, with a Reset Zoom button to undo. Only the selected slice is handed to the chart, so the stacked maximum is recomputed from it and the x axis re-bases; popups, totals, legend and the chooser's entry list all follow. Zooming re-slices data already in memory rather than re-reading the trace, so it cannot show bins finer than the range dialog loaded. The rubber band is
Graph.setXRangeSelectionListener, filling in mouse handlers that were empty stubs -- a tool that registers no listener sees no change.Order the entry chooser by count where a tool has one. 50 of the 78 entry methods in range on the test trace have under 100 events each, against 1.76 M messages total; listed by id, the ones that matter are scattered among them.
getEntriesArray()already returned numbers rather than flags, so a tool can opt in withsortEntriesByCount(): largest first, counts in a column, anything under a thousandth of the busiest greyed at the bottom. Only Messages Over Time opts in. This also stopsMyTableModelhardcoding its column count and editable columns by position -- as a side effect the id column is no longer editable, which it had been all along.Expand message sizes only when asked for. Loading a range ran two passes over the run length data, one for counts and one for sizes, each costing PEs x intervals x entry methods with its own progress bar. The second is usually for nothing: a trace written before charm recorded sizes (charmplusplus/charm#3937, still open) has no such line, so the pass walks empty data to produce zeros the Bytes view then declines to draw. Sizes now expand on the first switch to Bytes, off the event thread.
Combine intervals to see the shape under the noise. A Smoothing button offers combining every k intervals into one bar (totals preserved exactly, partial last bin kept), a moving average over k intervals (one bar per interval, edges averaged over what exists), and the special case of k equal to the whole visible range -- one bar whose bands are the totals per entry method on screen. Rates then divide by the time a bar spans rather than one interval, popups name the span a bar covers and say when a value is an average, and drag-to-zoom converts selected bars back into intervals.
Testing
Driven by hand on the 1792 PE trace above, plus headless checks of the parts that are awkward to verify by eye:
[Visible][Entry Method][ID][Count][Color], only the three under a thousandth of the largest are grey, visible and colour cells stay editable, and a tool that does not opt in still gets[Entry Method][ID][Color]in id orderShared files
gui/graph/Graph.java,gui/ChooseEntriesWindow.java,gui/MyTableModel.java,gui/GenericGraphWindow.javaandgui/EntryMethodVisibility.javaare used by other tools. Every behaviour change in them is behind an opt-in a tool has to ask for, except the id column of the chooser becoming non-editable.