diff --git a/cache/assets/dependencies.dot b/cache/assets/dependencies.dot index d2f422f..89d6e93 100644 --- a/cache/assets/dependencies.dot +++ b/cache/assets/dependencies.dot @@ -1,12 +1,12 @@ digraph G { - A [label="fetch-data-1", class="job", shape="box"]; - B [label="content", class="artifact", shape="ellipse"]; - C [label="calculate-functions", class="job", shape="box"]; - D [label="stats", class="artifact", shape="ellipse"]; - E [label="compute-statistics", class="job", shape="box"]; - F [label="result", class="artifact", shape="ellipse"]; - G [label="generate-website", class="job", shape="box"]; - H [label="website", class="artifact", shape="ellipse"]; + A [id="fetch-data-1", label="fetch-data-1", class="job", shape="box"]; + B [id="content", label="content", class="artifact", shape="ellipse"]; + C [id="calculate-functions", label="calculate-functions", class="job", shape="box"]; + D [id="stats", label="stats", class="artifact", shape="ellipse"]; + E [id="compute-statistics", label="compute-statistics", class="job", shape="box"]; + F [id="result", label="result", class="artifact", shape="ellipse"]; + G [id="generate-website", label="generate-website", class="job", shape="box"]; + H [id="website", label="website", class="artifact", shape="ellipse"]; A -> B; B -> C; C -> D; diff --git a/cache/assets/dependencies.dot.svg b/cache/assets/dependencies.dot.svg index 5653bb1..c6dc411 100644 --- a/cache/assets/dependencies.dot.svg +++ b/cache/assets/dependencies.dot.svg @@ -10,13 +10,13 @@ G - + A fetch-data-1 - + B content @@ -28,7 +28,7 @@ - + C calculate-functions @@ -40,7 +40,7 @@ - + E compute-statistics @@ -52,7 +52,7 @@ - + D stats @@ -64,7 +64,7 @@ - + G generate-website @@ -76,7 +76,7 @@ - + F result @@ -94,7 +94,7 @@ - + H website diff --git a/cache/assets/pipeline.json b/cache/assets/pipeline.json index d8a3494..b055d8c 100644 --- a/cache/assets/pipeline.json +++ b/cache/assets/pipeline.json @@ -2,33 +2,33 @@ { "stage": "fetch", "job": "fetch-data-1", - "start": "2024-04-21 15:06:16.087712", - "stop": "2024-04-21 15:06:16.188543", - "duration": "0:00:00.100831", - "duration_text": "100 ms" + "start": "2024-04-21 17:05:48.090399", + "stop": "2024-04-21 17:05:48.191794", + "duration": "0:00:00.101395", + "duration_text": "101 ms" }, { "stage": "process", "job": "calculate-functions", - "start": "2024-04-21 15:06:16.188543", - "stop": "2024-04-21 15:06:16.490527", - "duration": "0:00:00.301984", + "start": "2024-04-21 17:05:48.191794", + "stop": "2024-04-21 17:05:48.493691", + "duration": "0:00:00.301897", "duration_text": "301 ms" }, { "stage": "process", "job": "compute-statistics", - "start": "2024-04-21 15:06:16.490527", - "stop": "2024-04-21 15:06:16.891631", - "duration": "0:00:00.401104", + "start": "2024-04-21 17:05:48.493691", + "stop": "2024-04-21 17:05:48.894970", + "duration": "0:00:00.401279", "duration_text": "401 ms" }, { "stage": "build", "job": "generate-website", - "start": "2024-04-21 15:06:16.891631", - "stop": "2024-04-21 15:06:17.394657", - "duration": "0:00:00.503026", - "duration_text": "503 ms" + "start": "2024-04-21 17:05:48.894970", + "stop": "2024-04-21 17:05:49.397943", + "duration": "0:00:00.502973", + "duration_text": "502 ms" } ] \ No newline at end of file diff --git a/cache/assets/timeline.json b/cache/assets/timeline.json index bc5baba..53ce2b5 100644 --- a/cache/assets/timeline.json +++ b/cache/assets/timeline.json @@ -1,26 +1,46 @@ -[ - { - "id": "fetch-data-1", - "content": "fetch-data-1", - "start": "2024-04-21 15:06:16.087712", - "end": "2024-04-21 15:06:16.188543" - }, - { - "id": "calculate-functions", - "content": "calculate-functions", - "start": "2024-04-21 15:06:16.188543", - "end": "2024-04-21 15:06:16.490527" - }, - { - "id": "compute-statistics", - "content": "compute-statistics", - "start": "2024-04-21 15:06:16.490527", - "end": "2024-04-21 15:06:16.891631" - }, - { - "id": "generate-website", - "content": "generate-website", - "start": "2024-04-21 15:06:16.891631", - "end": "2024-04-21 15:06:17.394657" - } -] \ No newline at end of file +{ + "items": [ + { + "id": "fetch-data-1", + "content": "fetch-data-1", + "group": "fetch", + "start": "2024-04-21 17:05:48.090399", + "end": "2024-04-21 17:05:48.191794" + }, + { + "id": "calculate-functions", + "content": "calculate-functions", + "group": "process", + "start": "2024-04-21 17:05:48.191794", + "end": "2024-04-21 17:05:48.493691" + }, + { + "id": "compute-statistics", + "content": "compute-statistics", + "group": "process", + "start": "2024-04-21 17:05:48.493691", + "end": "2024-04-21 17:05:48.894970" + }, + { + "id": "generate-website", + "content": "generate-website", + "group": "build", + "start": "2024-04-21 17:05:48.894970", + "end": "2024-04-21 17:05:49.397943" + } + ], + "groups": [ + { + "id": "fetch", + "content": "fetch" + }, + { + "id": "process", + "content": "process" + }, + { + "id": "build", + "content": "build" + } + ] +} \ No newline at end of file diff --git a/graph_utils.py b/graph_utils.py index 2ce618e..3fbb2d5 100644 --- a/graph_utils.py +++ b/graph_utils.py @@ -22,7 +22,7 @@ def graph_to_dot(graph): label = node["label"] node_class = node["class"] node_shape = shapes_map[node_class] - dot_string += f' {nodes_map[label]} [label="{label}", class="{node_class}", shape="{node_shape}"];\n' + dot_string += f' {nodes_map[label]} [id="{label}", label="{label}", class="{node_class}", shape="{node_shape}"];\n' for edge in graph["edges"]: source = nodes_map[edge["source"]] target = nodes_map[edge["target"]] diff --git a/runner.py b/runner.py index a4130ef..420d0c5 100644 --- a/runner.py +++ b/runner.py @@ -102,16 +102,29 @@ def run_pipeline(pipeline): def generate_timeline(pipe): - timeline = [] + items = [] + groups = [] + groups_names = [] #user to keep entries unique for item in pipe: - timeline.append({ + if(item["stage"] not in groups_names): + groups_names.append(item["stage"]) + groups.append({ + "id":item["stage"], + "content":item["stage"] + }) + items.append({ "id":item["job"], "content":item["job"], + "group":item["stage"], "start":item["start"], "end":item["stop"] }) + timeline = { + "items":items, + "groups":groups + } return timeline +manifest = utl.load_yaml("manifest.yaml") if __name__ == '__main__': - manifest = utl.load_yaml("manifest.yaml") run_pipeline(manifest["pipeline"]) diff --git a/website/config.js b/website/config.js index f4584b3..d11f84a 100644 --- a/website/config.js +++ b/website/config.js @@ -9,6 +9,7 @@ const outdir = join(cachedir,"web") const base = env.PUBLIC_BASE const config = { + webdir, rootdir, base, cachedir, diff --git a/website/src/components/SvgInline.astro b/website/src/components/SvgInline.astro index 3d480eb..01844cc 100644 --- a/website/src/components/SvgInline.astro +++ b/website/src/components/SvgInline.astro @@ -4,10 +4,11 @@ import {load_text} from '@/libs/utils.js' export interface Props { filepath: string; + folder: string; } -const { filepath } = Astro.props as Props; -const innerHTML = await load_text(filepath); +const { filepath, folder="cachedir" } = Astro.props as Props; +const innerHTML = await load_text(filepath,folder); --- diff --git a/website/src/components/timeline.js b/website/src/components/timeline.js index 7e180cc..b8271ba 100644 --- a/website/src/components/timeline.js +++ b/website/src/components/timeline.js @@ -12,10 +12,10 @@ async function init(){ const data_file = timeline_element.dataset.file; try { const file_url = `${config.base}/artifacts/${data_file}` - console.log(`fetching ${file_url}`) + //console.log(`fetching ${file_url}`) const response = await fetch(file_url); const data_timeline = await response.json(); // Assuming the response needs to be converted to JSON - new Timeline(timeline_element, data_timeline, {}) + new Timeline(timeline_element, data_timeline.items,data_timeline.groups,{}) } catch (error) { console.error('Failed to fetch data:', error); } diff --git a/website/src/icons/github.svg b/website/src/icons/github.svg new file mode 100644 index 0000000..0eca688 --- /dev/null +++ b/website/src/icons/github.svg @@ -0,0 +1,11 @@ + + + + diff --git a/website/src/libs/utils.js b/website/src/libs/utils.js index 077e06e..b8889d4 100644 --- a/website/src/libs/utils.js +++ b/website/src/libs/utils.js @@ -19,7 +19,11 @@ async function load_json(path,folder="cachedir"){ } async function load_text(path,folder="cachedir"){ - return await readFile(join(config[folder],path)); + if(folder == "icons"){ + return await readFile(join(config.webdir,"src/icons",path)); + }else{ + return await readFile(join(config[folder],path)); + } } export{ diff --git a/website/src/pages/artifacts.js b/website/src/pages/artifacts.js new file mode 100644 index 0000000..b812c72 --- /dev/null +++ b/website/src/pages/artifacts.js @@ -0,0 +1,24 @@ + +document.addEventListener('DOMContentLoaded', () => { + const artifacts = document.querySelectorAll('g.artifact'); + + artifacts.forEach(artifact => { + artifact.style.cursor = 'pointer'; // Make cursor a pointer to indicate clickable + artifact.addEventListener('click', function() { + const id = this.id; + fetch(`/artifacts/${id}`) + .then(response => response.blob()) // Get the file as a blob + .then(blob => { + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `${id}.json`; // Set the default filename for the download + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }) + .catch(error => console.error('Error downloading the file:', error)); + }); + }); +}); diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro index 8bd4be8..66617d8 100644 --- a/website/src/pages/index.astro +++ b/website/src/pages/index.astro @@ -5,6 +5,41 @@ import Timeline from '@/components/Timeline.astro'; --- + + + +
+

Workflow

+
+ # Stage > Job +
+
+ pipeline: +
+
+   fetch: +
+
+   fetch-data-1: pipeline.py#fetch +
+
+  process: +
+
+   calculate-functions: pipeline.py#calculate +
+
+   compute-statistics: pipeline.py#compute +
+
+  build: +
+
+   generate-website: pipeline.py#build +
+

Dependencies

timeline

@@ -15,4 +50,17 @@ import Timeline from '@/components/Timeline.astro'; :global(.artifact > ellipse){ fill:antiquewhite; } +.social{ + position: fixed; + top:5px; + right:5px; + width:30px; + background-color: #f9f9f9; + border: 1px solid #ccc; + border-radius: 50%; + padding: 10px; + box-shadow: 0 4px 8px rgba(0,0,0,0.1); +} + +