Skip to content
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

Update chart: add date as x-axis, ux improvements #10

Merged
merged 9 commits into from
Mar 13, 2024
76 changes: 65 additions & 11 deletions scripts/lib/build_perf/html/measurement_chart_d3billboard.html
Original file line number Diff line number Diff line change
@@ -1,36 +1,90 @@
<script type="module">
// Get data
const rawData = [
{% for sample in measurement.samples %}
[{{ sample.commit_num }}, {{ sample.mean.gv_value() }}],
{% endfor %}
];
{% for sample in measurement.samples %}
[{{ sample.commit_num }}, {{ sample.mean.gv_value() }}, {{ sample.start_time }}],
{% endfor %}
];

const convertToMinute = (time) => {
return time[0]*60 + time[1] + time[2]/60 + time[3]/3600;
}

// Assuming the array quantities are durations in the format [hours, minutes, seconds, milliseconds]
const dataX = rawData.map(([commit, quantity]) => {
return commit
const dataX = rawData.map(([commit, value, time]) => {
// The Date object takes value in milliseconds rather than seconds. So to use a Unix timestamp we multiply it by 1000.
const date = new Date(time * 1000)
// billboardjs supports date format as 'YYYY-MM-DD'
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() // Adding an extra 1 for month as January starts from 0
});
dataX.unshift('commit');
dataX.unshift('dateOrCommit');

const dataY = rawData.map(([commit, quantity]) => {
return Array.isArray(quantity) ? convertToMinute(quantity) : quantity
// Assuming the array values are durations in the format [hours, minutes, seconds, milliseconds]
const dataY = rawData.map(([commit, value]) => {
return Array.isArray(value) ? convertToMinute(value) : value
});
dataY.unshift('quantity');
dataY.unshift('value');

let axisFormat
// Date is saved as string in the data
if (typeof dataX[1] === 'string') {
axisFormat = {
x: {
label: {
text: "Date",
position: "outer-center"
},
type: "timeseries",
tick: {
format: "%Y-%m-%d"
}
},
y: {
label: {
text: "Duration (minutes)",
position: "outer-middle"
}
}
}
} else {
axisFormat = {
x: {
label: {
text: "Commit number",
position: "outer-center"
}
},
y: {
label: {
text: "Disk size (MB)",
position: "outer-middle"
}
}
}
}

// Example: https://naver.github.io/billboard.js/demo/#Chart.SimpleXYLineChart
const chart = bb.generate({
data: {
x: "commit",
x: "dateOrCommit",
columns: [dataX, dataY],
type: "line",
},
axis: axisFormat,
zoom: {
enabled: true,
},
tooltip: {
format: {
value: function(value, ratio, id) {
const format = d3.format('.2f');
return format(value);
}
}
},
legend: {
show: false
},
bindto: {{chart_elem_id}}
});
</script>
93 changes: 65 additions & 28 deletions scripts/lib/build_perf/html/report.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{# Scripts, for visualization#}
<!--START-OF-SCRIPTS-->
<script src="https://cdn.jsdelivr.net/npm/d3@^6.1"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/billboard.js@3.10.3/dist/billboard.css">
<link rel="stylesheet" href="https://naver.github.io/billboard.js/release/latest/dist/theme/modern.css">
<script src="https://cdn.jsdelivr.net/npm/billboard.js"></script>

{# Render measurement result charts #}
Expand All @@ -26,23 +26,15 @@
text-align: left;
border-collapse: collapse;
}
.meta-table tr:nth-child(even){background-color: #f2f2f2}
meta-table th, .meta-table td {
padding: 4px;
}
.summary {
margin: 0;
font-size: 14px;
text-align: left;
border-collapse: collapse;
}
summary th, .meta-table td {
padding: 4px;
}
.measurement {
padding: 8px 0px 8px 8px;
border: 2px solid #f0f0f0;
margin-bottom: 10px;
margin: 1.5rem 0;
}
.details {
margin: 0;
Expand All @@ -62,32 +54,73 @@
background-color: #f0f0f0;
margin-left: 10px;
}
hr {
color: #f0f0f0;
.card-container {
border-bottom-width: 1px;
padding: 1.25rem 3rem;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
border-radius: 0.25rem;
}
body {
font-family: 'Helvetica', sans-serif;
margin: 3rem 8rem;
}
h1 {
text-align: center;
}
h2 {
font-size: 20px;
font-size: 1.5rem;
margin-bottom: 0px;
color: #707070;
padding-top: 1.5rem;
}
h3 {
font-size: 16px;
font-size: 1.3rem;
margin: 0px;
color: #707070;
padding: 1.5rem 0;
}
h4 {
font-size: 14px;
font-weight: lighter;
line-height: 1.2rem;
margin: auto;
padding-top: 1rem;
}
table {
margin-top: 1.5rem;
line-height: 2rem;
}
tr {
border-bottom: 1px solid #e5e7eb;
}
tr:first-child {
border-bottom: 1px solid #9ca3af;
}
tr:last-child {
border-bottom: none;
}
a {
text-decoration: none;
font-weight: bold;
color: #0000EE;
}
a:hover {
color: #8080ff;
}
</style>

<title>{{ title }}</title>
</head>

{% macro poky_link(commit) -%}
<a href="http://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?id={{ commit }}">{{ commit[0:11] }}</a>
<a href="http://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?id={{ commit }}">{{ commit[0:11] }}</a>
{%- endmacro %}

<body><div style="width: 700px">
<body><div>
<h1 style="text-align: center;">Performance Test Report</h1>
{# Test metadata #}
<h2>General</h2>
<hr>
<h4>The table provides an overview of the comparison between two selected commits from the same branch.</h4>
<table class="meta-table" style="width: 100%">
<tr>
<th></th>
Expand All @@ -110,19 +143,21 @@ <h2>General</h2>

{# Test result summary #}
<h2>Test result summary</h2>
<hr>
<h4>The test summary presents a thorough breakdown of each test conducted on the branch, including details such as build time and disk space consumption. Additionally, it gives insights into the average time taken for test execution, along with absolute and relative values for a better understanding.</h4>
<table class="summary" style="width: 100%">
<tr>
<th>Test name</th>
<th>Measurement description</th>
<th>Mean value</th>
<th>Absolute difference</th>
<th>Relative difference</th>
</tr>
{% for test in test_data %}
{% if loop.index is even %}
{% set row_style = 'style="background-color: #f2f2f2"' %}
{% else %}
{% set row_style = 'style="background-color: #ffffff"' %}
{% endif %}
{% if test.status == 'SUCCESS' %}
{% for measurement in test.measurements %}
<tr {{ row_style }}>
{% if loop.index == 1 %}
<td>{{ test.name }}: {{ test.description }}</td>
<td><a href=#{{test.name}}>{{ test.name }}: {{ test.description }}</a></td>
{% else %}
{# add empty cell in place of the test name#}
<td></td>
Expand Down Expand Up @@ -151,10 +186,12 @@ <h2>Test result summary</h2>
</table>

{# Detailed test results #}
<h2>Test details</h2>
<h4>The following section provides details of each test, accompanied by charts representing build time and disk usage over time or by commit number.</h4>
{% for test in test_data %}
<h2>{{ test.name }}: {{ test.description }}</h2>
<hr>
<h3 style="color: #000;" id={{test.name}}>{{ test.name }}: {{ test.description }}</h3>
{% if test.status == 'SUCCESS' %}
<div class="card-container">
{% for measurement in test.measurements %}
<div class="measurement">
<h3>{{ measurement.description }}</h3>
Expand Down Expand Up @@ -273,7 +310,8 @@ <h3>{{ measurement.description }}</h3>
{% endif %}
{% endif %}
</div>
{% endfor %}
{% endfor %}
</div>
{# Unsuccessful test #}
{% else %}
<span style="font-size: 150%; font-weight: bold; color: red;">{{ test.status }}
Expand All @@ -284,4 +322,3 @@ <h3>{{ measurement.description }}</h3>
{% endfor %}
</div></body>
</html>

7 changes: 5 additions & 2 deletions scripts/lib/build_perf/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def gv_value(self):
return "null"
return self / 1024

def measurement_stats(meas, prefix=''):
def measurement_stats(meas, prefix='', time=0):
"""Get statistics of a measurement"""
if not meas:
return {prefix + 'sample_cnt': 0,
Expand All @@ -304,7 +304,8 @@ def measurement_stats(meas, prefix=''):
prefix + 'min': MeasurementVal('nan'),
prefix + 'max': MeasurementVal('nan'),
prefix + 'minus': MeasurementVal('nan'),
prefix + 'plus': MeasurementVal('nan')}
prefix + 'plus': MeasurementVal('nan'),
prefix + 'start_time': MeasurementVal('nan')}

stats = {'name': meas['name']}
if meas['type'] == 'sysres':
Expand All @@ -319,6 +320,7 @@ def measurement_stats(meas, prefix=''):
stats['quantity'] = val_cls.quantity
stats[prefix + 'sample_cnt'] = len(values)

start_time = time # Add start time for both type sysres and disk usage
mean_val = val_cls(mean(values))
min_val = val_cls(min(values))
max_val = val_cls(max(values))
Expand All @@ -334,6 +336,7 @@ def measurement_stats(meas, prefix=''):
stats[prefix + 'max'] = max_val
stats[prefix + 'minus'] = val_cls(mean_val - min_val)
stats[prefix + 'plus'] = val_cls(max_val - mean_val)
stats[prefix + 'start_time'] = start_time

return stats

6 changes: 4 additions & 2 deletions scripts/oe-build-perf-report
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ def print_html_report(data, id_comp, buildstats):
test_i = test_data['tests'][test]
meas_i = test_i['measurements'][meas]
commit_num = get_data_item(meta, 'layers.meta.commit_count')
samples.append(measurement_stats(meas_i))
# Add start_time for both test measurement types of sysres and disk usage
start_time = test_i['start_time'][0]
samples.append(measurement_stats(meas_i, '', start_time))
samples[-1]['commit_num'] = commit_num

absdiff = samples[-1]['val_cls'](samples[-1]['mean'] - samples[id_comp]['mean'])
Expand Down Expand Up @@ -473,7 +475,7 @@ Examine build performance test results from a Git repository"""
group.add_argument('--branch', '-B', default='master', help="Branch to find commit in")
group.add_argument('--branch2', help="Branch to find comparision revisions in")
group.add_argument('--machine', default='qemux86')
group.add_argument('--history-length', default=25, type=int,
group.add_argument('--history-length', default=300, type=int,
help="Number of tested revisions to plot in html report")
group.add_argument('--commit',
help="Revision to search for")
Expand Down