in tools/analysis/ping-patterns/ping-patterns.py [0:0]
def plot_timeline(client_id, data, metrics_rows, baseline_rows):
"""
Make the SVG timeline.
"""
data = sorted(data, key=lambda x: x["start_time_hour"])
# Find the date range to determine the size of the plot
min_time = data[0]["start_time_hour"]
max_time = max(ping["end_time_hour"] for ping in data)
width = max_time - min_time
height = (len(metrics_rows) + len(baseline_rows) + 2) * ROW_HEIGHT
svg = ET.Element(
"svg",
{
"version": "1.1",
"width": str(width),
"height": str(height),
"xmlns": "http://www.w3.org/2000/svg",
},
)
ET.SubElement(
svg,
"rect",
{
"x": "0",
"y": "0",
"width": str(width),
"height": str(height),
"fill": "white",
},
)
# Draw vertical lines at midnight and 4am, with the date indicated
dt = data[0]["start_time_local"].replace(hour=0, minute=0, second=0)
while get_fractional_hour(dt) < max_time:
x = get_fractional_hour(dt) - min_time
draw_line(svg, x, x, 0, height, stroke="#cccccc")
draw_text(svg, x + 2, height - 2, dt.strftime("%m-%d"))
four = dt.replace(hour=4)
x = get_fractional_hour(four) - min_time
draw_line(svg, x, x, 0, height, stroke="#cccccc", stroke_dasharray="2,1")
dt += datetime.timedelta(days=1)
# Draw markers for the first time key "FIX" versions were seen in the ping metadata
fixes = list(enumerate(FIXES))
for ping in sorted(data, key=lambda x: x["end_time_local"]):
if ping["version_date"] is not None and ping["version_date"] >= fixes[0][1][1]:
x = ping["end_time_hour"] - min_time
draw_line(svg, x, x, 0, height, stroke="#33aa33")
draw_text(svg, x + 2, 12, str(fixes[0][0] + 1), title=fixes[0][1][0])
fixes.pop(0)
if len(fixes) == 0:
break
# Draw the actual pings in the timeline
y = ROW_HEIGHT
for (rows, color) in ((baseline_rows, "#000088"), (metrics_rows, "#880000")):
for row in rows[::-1]:
for ping in row:
draw_line(
svg,
ping["start_time_hour"] - min_time,
ping["end_time_hour"] - min_time,
y,
y,
stroke=color,
stroke_width="0.5",
)
if ping["ping_type"] == "baseline" and ping["duration"]:
session_start = (
get_fractional_hour(
ping["end_time_local"]
- datetime.timedelta(seconds=int(ping["duration"]))
)
- min_time
)
draw_line(
svg,
session_start,
ping["end_time_hour"] - min_time,
y,
y,
stroke=color,
stroke_width="3",
)
if ping["notes"]:
x = 0
for note in sorted(list(ping["notes"])):
draw_text(
svg,
ping["end_time_hour"] - min_time + 2 + x,
y + 3,
str(note),
font_size="6px",
title=NOTE_SUMMARIES[note],
)
x += 8
y += ROW_HEIGHT
draw_text(svg, 2, 12, f"Android SDK: {data[0]['sdk']}")
tree = ET.ElementTree(svg)
with open(f"{client_id}.svg", "wb") as fd:
tree.write(fd)