Capital One
Events Timeline
A resource's compliance history was a table of rows sorted by date, which is technically the whole story and practically unreadable. I built the feature that sits above it end to end, the GraphQL API and the interface both: a time-scaled track where a glance tells you what state a resource is in, how long it has been in it, and what the automated remediation did along the way. The demo linked above is a simplified, scrubbed recreation of it.
A table is a list of events, not a history
The events were all there, sorted by timestamp, each one accurate. But the question people actually had was never “what happened on the third of August”. It was “how long has this been broken”, and a table answers that only if you are willing to read it and do arithmetic.
A timeline answers it by being looked at. That is the whole argument for the feature: the data did not change, the shape of it did.
What it answers now is a different question from the one the table answered. Not “is this compliant right now”, which a chip can say in four words, but “how did it get into this state, and what did the automation do about it”. The chip at the top right gives the state and how long it has held: conformant since a date, or in violation for four days, with the timer resetting the moment a fix lands so there is no ambiguity about whether it did.
Violated here, fixed there. The gap between them is the answer, and the table makes you work it out.
Colouring the gaps
Events are discrete and compliance is continuous, and that mismatch is the whole engineering problem. A resource that was violated on the 3rd and fixed on the 8th generates two events and five days of nothing, and those five days are the part that matters most.
So state carries forward: the segment between two events is coloured by the state the earlier one left behind, not by the absence of data. Drawn the naive way, the track shows two dots and a gap, which reads as “nothing was wrong” for precisely the stretch when something was.
The track is time-scaled, so where a dot sits horizontally is when it happened, and the colours are semantic rather than per-event: red while the resource was in violation, green while it was conformant, amber across an automated change of any kind. Three colours covering a dozen event types is a decision that has to be made once and defended afterwards, and the defence is that a reader scanning a track is asking about state, not about which of six words the change was called.
When two things happen at once
Events cluster. An automated fix fires, fails, retries and succeeds, and at any sensible zoom those are four dots occupying the same pixel.
Adjacent same-day events collapse into one dot that opens a popover with all of them. The alternative was letting them overlap, which looks like a rendering bug, or spacing them evenly, which lies about when they happened. Collapsing keeps the position honest and moves the detail one interaction away, where there is room for it.
The badge is a count, and it opens a card listing every event that landed at that moment. Clicking one of them scrolls to its row in the table below, which is the part that makes the two halves one feature rather than a chart with a table under it. Clusters are usually a fleet-wide change arriving everywhere at once, so the count is information in itself.
What a column can be asked to do
The table under the track is not a fallback. It is where the specifics live, and two of its columns do more than report a field.
The quantification column renders financial events as money. The underlying value is a metric string, and every reader of it was doing the same conversion in their head to answer the same question, which is what a remediation actually saved. Doing that conversion once, in the column, is a smaller change than it sounds and it is the difference between a number and an answer.
The requirement column is a link out to the control the event was raised against. It exists because the alternative was a reader copying an identifier into a second system, which is the exact behaviour this whole dashboard was built to remove. Every column sorts, and the filters above narrow by event type, status and timeframe.
The same data, now legible
The question the feature exists to answer, how long and is it fixed, went from a read-and-calculate to a glance. The table is still there underneath for the cases where you need the specifics.
It shipped in beta for feedback, which was the right call for something whose value is entirely in whether people read it the way it was meant to be read.
Shipped in beta · figures describe scope, not usage
Most-used control Timeframe filter