Skip to content

Commit

Permalink
WIP2 [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneTR committed Dec 15, 2024
1 parent f32202d commit 8c6f842
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 95 deletions.
151 changes: 93 additions & 58 deletions api/api_helpers.py

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@

from api import eco_ci
from api.object_specifications import Software
from api.api_helpers import (ORJSONResponseObjKeep, add_phase_stats_statistics, determine_comparison_case,
from api.api_helpers import (ORJSONResponseObjKeep, add_phase_stats_statistics,
determine_comparison_case,get_comparison_details,
html_escape_multi, get_phase_stats, get_phase_stats_object,
is_valid_uuid, rescale_energy_value, get_timeline_query,
get_run_info, get_machine_list, get_artifact, store_artifact,
Expand Down Expand Up @@ -290,14 +291,16 @@ async def compare_in_repo(ids: str):
return ORJSONResponse({'success': True, 'data': orjson.loads(artifact)}) # pylint: disable=no-member

try:
case = determine_comparison_case(ids)
case, comparison_db_key = determine_comparison_case(ids)
except RuntimeError as err:
raise RequestValidationError(str(err)) from err

comparison_details = get_comparison_details(ids, comparison_db_key)

if not (phase_stats := get_phase_stats(ids)):
return Response(status_code=204) # No-Content

phase_stats_object = get_phase_stats_object(phase_stats, case)
phase_stats_object = get_phase_stats_object(phase_stats, case, comparison_details)
phase_stats_object = add_phase_stats_statistics(phase_stats_object)
phase_stats_object['common_info'] = {}

Expand Down Expand Up @@ -373,7 +376,7 @@ async def get_phase_stats_single(run_id: str):
if not (phase_stats := get_phase_stats([run_id])):
return Response(status_code=204) # No-Content

phase_stats_object = get_phase_stats_object(phase_stats, None)
phase_stats_object = get_phase_stats_object(phase_stats, None, None, [run_id])
phase_stats_object = add_phase_stats_statistics(phase_stats_object)

store_artifact(ArtifactType.STATS, str(run_id), orjson.dumps(phase_stats_object)) # pylint: disable=no-member
Expand Down
4 changes: 4 additions & 0 deletions frontend/css/green-coding.css
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,7 @@ a,
page-break-before: always;
}
}


/* Allow clickable boxes for chart overlays */
.statistics-chart div { pointer-events: all !important }
10 changes: 9 additions & 1 deletion frontend/js/compare.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const getURLParams = () => {
return url_params;
}


async function fetchDiff() {
document.querySelector('#diff-question').remove();
document.querySelector('#loader-diff').style.display = '';
Expand Down Expand Up @@ -70,7 +71,14 @@ $(document).ready( (e) => {

document.querySelector('#fetch-diff').addEventListener('click', fetchDiff);

buildComparisonChartData(phase_stats_data)
buildPhaseTabs(phase_stats_data)
renderCompareChartsForPhase(phase_stats_data, getAndShowPhase(), run_count);
displayTotalChart(...buildTotalChartData(phase_stats_data));

document.querySelectorAll('.ui.steps.phases .step, .runtime-step').forEach(node => node.addEventListener('click', el => {
const phase = el.currentTarget.getAttribute('data-tab');
renderCompareChartsForPhase(phase_stats_data, phase, run_count);
}));

})();
});
Expand Down
81 changes: 60 additions & 21 deletions frontend/js/helpers/charts.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const getCompareChartOptions = (legend, series, chart_type='line', x_axis='time', y_axis_name, mark_area=null, graphic=null, comparison_details=null) => {
let select_diff_buffer = [];

const addToDiffSelection = (node) => {
select_diff_buffer.push(node.getAttribute('data-run-id'));
return false;
}

const getCompareChartOptions = (legend, series, chart_type='line', x_axis='time', y_axis_name, mark_area=null, graphic=null, comparison_details=null, comparison_identifiers=null) => {
let tooltip_trigger = (chart_type=='line') ? 'axis' : 'item';

let series_count = series.length;
Expand All @@ -13,15 +20,21 @@ const getCompareChartOptions = (legend, series, chart_type='line', x_axis='time'
tooltip: {
triggerOn: 'click',
formatter: function (params, ticket, callback) {
console.log(params);
console.log(comparison_details);
return `<strong>${comparison_details[params.dataIndex].name}</strong><br>
run_id: <a href="/stats.html?id=${comparison_details[params.dataIndex].run_id}" target="_blank">${comparison_details[params.dataIndex].run_id}</a><br>
date: ${comparison_details[params.dataIndex].created_at}<br>
if (select_diff_buffer.length > 0) {
window.open(`/compare.html?ids=${select_diff_buffer[0]},${comparison_details[params.seriesIndex][params.dataIndex].run_id}`, '_blank');
select_diff_buffer = [] // reset
return false;
}

return `<strong>${comparison_details[params.seriesIndex][params.dataIndex].name}</strong><br>
run_id: <a href="/stats.html?id=${comparison_details[params.seriesIndex][params.dataIndex].run_id}" target="_blank">${comparison_details[params.seriesIndex][params.dataIndex].run_id}</a><br>
date: ${comparison_details[params.seriesIndex][params.dataIndex].created_at}<br>
value: ${numberFormatter.format(params.value)}<br>
commit_timestamp: ${comparison_details[params.dataIndex].commit_timestamp}<br>
commit_hash: <a href="${$("#uri").text()}/commit/${comparison_details[params.dataIndex].commit_hash}" target="_blank">${comparison_details[params.dataIndex].commit_hash}</a><br>
gmt_hash: <a href="https://github.com/green-coding-solutions/green-metrics-tool/commit/${comparison_details[params.dataIndex].gmt_hash}" target="_blank">${comparison_details[params.dataIndex].gmt_hash}</a><br>
commit_timestamp: ${comparison_details[params.seriesIndex][params.dataIndex].commit_timestamp}<br>
commit_hash: <a href="${$("#uri").text()}/commit/${comparison_details[params.seriesIndex][params.dataIndex].commit_hash}" target="_blank">${comparison_details[params.seriesIndex][params.dataIndex].commit_hash}</a><br>
gmt_hash: <a href="https://github.com/green-coding-solutions/green-metrics-tool/commit/${comparison_details[params.seriesIndex][params.dataIndex].gmt_hash}" target="_blank">${comparison_details[params.seriesIndex][params.dataIndex].gmt_hash}</a><br>
<br>
👉 <a href="" class="select-diff-run" onClick="return addToDiffSelection(this);" data-run-id="${comparison_details[params.seriesIndex][params.dataIndex].run_id}" target="_blank">Diff with ... (?)</a>
`;
},
},
Expand Down Expand Up @@ -72,17 +85,36 @@ const getCompareChartOptions = (legend, series, chart_type='line', x_axis='time'
type: 'scroll',
}
);
let mark_point = {
data: []
};

let data = [null] // default. Used as indicator for missing data

if (series[index] == null) { // whole series to compare is missing. Happens if different metrics where captured
mark_point.data.push({ name: 'Missing', coord: [0, 0], value: 'Missing Data', label: { show: true } })
} else { // single runs have missing metrics. Happens if run ended prematurely in earlier phase or did not run at all
data = series[index]
for (el_index in series[index]) {
if (series[index][el_index] == null) {
mark_point.data.push({ name: 'Missing', coord: [el_index, 0], value: 'Missing Data', label: { show: true } })
}
}
}


options.series.push(
{
type: chart_type,
data: series[index],
data: data,
xAxisIndex: index,
yAxisIndex:index,
markLine: {
precision: 4, // generally annoying that precision is by default 2. Wrong AVG if values are smaller than 0.001 and no autoscaling!
data: [ {type: "average",label: {formatter: "Mean:\n{c}"}}]
}
}
},
markPoint: mark_point,
},
);
if (mark_area != null) {
options['series'][index]['markArea'] = {
Expand Down Expand Up @@ -168,7 +200,7 @@ const getLineBarChartOptions = (legend, labels, series, x_axis_name=null, y_axis




console.log(series);
let options = {
tooltip: { trigger: tooltip_trigger },
grid: {
Expand Down Expand Up @@ -516,26 +548,33 @@ const displayKeyMetricsEmbodiedCarbonChart = (phase) => {
}

const displayTotalChart = (legend, labels, data) => {

let chartDom = document.querySelector(`#total-phases-data .bar-chart .statistics-chart`);
const chartDom = document.querySelector(`#total-phases-data .bar-chart .statistics-chart`);
document.querySelector(`#total-phases-data .bar-chart .chart-title`).innerText = TOTAL_CHART_BOTTOM_TITLE;

let myChart = echarts.init(chartDom);
const myChart = echarts.init(chartDom);

const series = [];

let series = [];
for (const key in data) {
const mark_point_data = []
for (el_index in data[key]) {
if (data[key][el_index] == null) {
mark_point_data.push({ name: 'Missing', coord: [parseInt(el_index), 0], value: 'Missing Data', label: { show: true } })
}
}
series.push({
name: key,
type: 'bar',
emphasis: {
focus: 'series'
},
data: data[key]
data: data[key],
markPoint: {data: mark_point_data}
})
}


let options = getLineBarChartOptions(null, labels, series, null, TOTAL_CHART_UNIT, 'category', null, true)
const options = getLineBarChartOptions(null, labels, series, null, TOTAL_CHART_UNIT, 'category', null, true)

myChart.setOption(options);
// set callback when ever the user changes the viewport
Expand All @@ -548,10 +587,10 @@ const displayTotalChart = (legend, labels, data) => {
}


const displayCompareChart = (phase, title, y_axis_name, legend, data, mark_area=null, graphic=null, comparison_details=null) => {
const displayCompareChart = (phase, title, y_axis_name, legend, data, mark_area=null, graphic=null, comparison_details=null, comparison_identifiers=null) => {
const element = createChartContainer(`.ui.tab[data-tab='${phase}'] .compare-chart-container`, title);
const myChart = echarts.init(element);
let options = getCompareChartOptions(legend, data, 'bar', 'category', y_axis_name, mark_area, graphic, comparison_details);
let options = getCompareChartOptions(legend, data, 'bar', 'category', y_axis_name, mark_area, graphic, comparison_details, comparison_identifiers);
myChart.setOption(options);
// set callback when ever the user changes the viewport
// we need to use jQuery here and not Vanilla JS to not overwrite but add multiple resize callbacks
Expand Down
16 changes: 10 additions & 6 deletions frontend/js/helpers/phase-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ const buildPhaseTabs = (phase_stats_object) => {
render* means that build* and display* functions are mixed
*/
const renderCompareChartsForPhase = (phase_stats_object, phase = '[RUNTIME]') => {
const renderCompareChartsForPhase = (phase_stats_object, phase='[RUNTIME]', run_count=1) => {

// we now traverse all branches of the tree
// the tree is sparese, so although we see all metrics that are throughout all phases and comparison_keys
Expand Down Expand Up @@ -200,8 +200,12 @@ const renderCompareChartsForPhase = (phase_stats_object, phase = '[RUNTIME]') =>

/* END BLOCK LABELS*/

if (Object.keys(detail_data['data']).length != phase_stats_object.comparison_identifiers.length) {
showWarning(phase, `${metric_name} ${detail_name} was missing from at least one comparison.`);
if (
(phase_stats_object.comparison_identifiers.length == 2 && detail_data['data'][phase_stats_object.comparison_identifiers[0]]?.values?.length != detail_data['data'][phase_stats_object.comparison_identifiers[1]]?.values?.length)
||
(phase_stats_object.comparison_identifiers.length == 1 && detail_data['data'][phase_stats_object.comparison_identifiers[0]]?.values?.length != run_count)
) {
showWarning(phase, `${metric_name} ${detail_name} was missing from at least one comparison.`)
}

let compare_chart_data = []
Expand Down Expand Up @@ -247,8 +251,7 @@ const renderCompareChartsForPhase = (phase_stats_object, phase = '[RUNTIME]') =>
detail_data.is_significant
);
}
if(phase_stats_object.comparison_case !== null) { // compare charts will display for everything apart stats.html
console.log(phase);
if(phase_stats_object.comparison_case != null) { // compare charts will display for everything apart stats.html
displayCompareChart(
phase,
`${getPretty(metric_name, 'clean_name')} via ${getPretty(metric_name, 'source')} - ${detail_name} <i data-tooltip="${getPretty(metric_name, 'explanation')}" data-position="bottom center" data-inverted><i class="question circle icon link"></i></i>`,
Expand All @@ -258,6 +261,7 @@ const renderCompareChartsForPhase = (phase_stats_object, phase = '[RUNTIME]') =>
compare_chart_mark,
null, // graphic
phase_stats_object.comparison_details,
phase_stats_object.comparison_identifiers,
);
}
} // end detail
Expand Down Expand Up @@ -343,7 +347,7 @@ const buildTotalChartData = (phase_stats_object) => {
if(total_chart_bottom_data?.[`${TOTAL_CHART_BOTTOM_LABEL} - ${key}`] == null) {
total_chart_bottom_data[`${TOTAL_CHART_BOTTOM_LABEL} - ${key}`] = []
}
total_chart_bottom_data[`${TOTAL_CHART_BOTTOM_LABEL} - ${key}`].push(NaN)
total_chart_bottom_data[`${TOTAL_CHART_BOTTOM_LABEL} - ${key}`].push(null)
}
}

Expand Down
1 change: 0 additions & 1 deletion frontend/js/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,6 @@ $(document).ready( (e) => {
const phase = el.currentTarget.getAttribute('data-tab');
renderCompareChartsForPhase(phase_stats_data, phase);
}));

}


Expand Down
4 changes: 0 additions & 4 deletions frontend/timeline.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@
<script src="/js/timeline.js" defer></script>
<link rel="stylesheet" type="text/css" class="ui" href="/dist/css/semantic_reduced.min.css">
<link rel="stylesheet" type="text/css" href="/css/green-coding.css">
<style type="text/css">
.hide-for-single-stats { display: none !important; }
.statistics-chart div { pointer-events: all !important }
</style>
</head>
<body class="preload">
<gmt-menu></gmt-menu>
Expand Down

0 comments on commit 8c6f842

Please sign in to comment.