diff --git a/README.md b/README.md index afd0774..91b6f20 100644 --- a/README.md +++ b/README.md @@ -75,11 +75,11 @@ You can customize much of it through optional URL parameters: Examples: -- [https://linqlover.github.io/trace4d](https://linqlover.github.io/trace4d) -- [https://linqlover.github.io/trace4d/?trace=traces/regexMatch.json&countFPS](https://linqlover.github.io/trace4d/?trace=traces/regexMatch.json&countFPS) -- http://localhost:5173?trace=https://raw.githubusercontent.com/LinqLover/trace4d/main/assets/traces/displayScanner.json?measureStartTime +- [https://linqlover.github.io/trace4d/app.html](https://linqlover.github.io/trace4d/app.html) +- [https://linqlover.github.io/trace4d/app.html?trace=traces/regexMatch.json&countFPS](https://linqlover.github.io/trace4d/app.html?trace=traces/regexMatch.json&countFPS) +- http://localhost:5173/app.html?trace=https://raw.githubusercontent.com/LinqLover/trace4d/main/assets/traces/displayScanner.json?measureStartTime -If you have an [own trace file](#creating-a-program-trace), you first need to copy it to `assets/traces` (or to any public web server). +If you have an [own trace file](#creating-a-program-trace), you can select it on the [landing page](https://linqlover.github.io/trace4d/). #### Navigation diff --git a/docs/paper/sections/05_use_case.tex b/docs/paper/sections/05_use_case.tex index 428e57b..446c4a8 100644 --- a/docs/paper/sections/05_use_case.tex +++ b/docs/paper/sections/05_use_case.tex @@ -8,7 +8,7 @@ \section{Use Case: Exploring Internals of a Regular Expression Engine} In this example, our programmer visualizes the construction of the simple regular expression \hardcode{\textbackslash{}d|\textbackslash{}w+} to gain a closer understanding of the involved subsystems and their interactions. To create the visualization, the programmer records and exports a trace of the program \code{\textquotesingle{}\textbackslash{}d|\textbackslash{}w+\textquotesingle{} asRegex} in Squeak and loads it into the \tfd{} web app% -\footnote{The interactive visualization of the described program trace is available at \ifanon{\url{https://user.github.io/repo/?trace=traces/regexParse.json} (blinded)}{\url{https://linqlover.github.io/trace4d/?trace=traces/regexParse.json}} and in the Wayback Machine of the Internet Archive.}% +\footnote{The interactive visualization of the described program trace is available at \ifanon{\url{https://user.github.io/repo/app.html?trace=traces/regexParse.json} (blinded)}{\url{https://linqlover.github.io/trace4d/app.html?trace=traces/regexParse.json}} and in the Wayback Machine of the Internet Archive.}% . As the visualization loads, she can see about 25 objects moving around in the object map and arranging themselves into a semi-structured graph within a few seconds~(\cref{fig:teaser}). By navigating through the scene, she discovers several meaningful objects and clusters of objects: diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 84414aa..2709b55 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -4,6 +4,7 @@ "license": "MIT", "dependencies": { "@fortawesome/fontawesome-free": "^6.4.2", + "bootstrap": "^5.3.2", "collect.js": "^4.36.1", "d3": "^7.8.5", "d3-flame-graph": "^4.1.3", diff --git a/packages/frontend/src/app.html b/packages/frontend/src/app.html new file mode 100644 index 0000000..42e25b1 --- /dev/null +++ b/packages/frontend/src/app.html @@ -0,0 +1,177 @@ + + + + + Trace4D + + + + + + + + + + +
+
+
+
+
+ + +
+
+
+
+
+
+
+ + diff --git a/packages/frontend/src/main.js b/packages/frontend/src/app.js similarity index 76% rename from packages/frontend/src/main.js rename to packages/frontend/src/app.js index fcacdc3..397234d 100644 --- a/packages/frontend/src/main.js +++ b/packages/frontend/src/app.js @@ -26,7 +26,13 @@ async function init() { Object.assign(traceMap.options, options) traceMap.buildMap(document.querySelector('#container')) - await traceMap.loadTraceFromServerFile(traceUrl, style) + // check session storage for trace file + const sessionTrace = sessionStorage.getItem('trace') + if (sessionTrace) { + await traceMap.loadTraceFromString(sessionTrace, style) + } else { + await traceMap.loadTraceFromServerFile(traceUrl, style) + } } await init() diff --git a/packages/frontend/src/index.html b/packages/frontend/src/index.html index 56dea9f..ffc3017 100644 --- a/packages/frontend/src/index.html +++ b/packages/frontend/src/index.html @@ -4,174 +4,134 @@ Trace4D - - - - - - -
-
-
-
-
- - -
-
-
+
+
+ + + + + trace4d + +
+ +
+

trace4d

+

Visualization of program traces in animated 2.5D object maps. Research prototype.

+ + + +
+

Featured program traces

+ + + + +

+ Learn how to use this visualization or read more about the origin of these traces. +

+
+ +
+

Bring your own trace

+

You can select your own trace file in JSON format.

+ +
+
+ +
+
+
+
-
+ diff --git a/packages/frontend/src/map.js b/packages/frontend/src/map.js index dd50374..3551f69 100644 --- a/packages/frontend/src/map.js +++ b/packages/frontend/src/map.js @@ -660,8 +660,8 @@ traceMap.player.stepsPerSecond = 100 return await this.loadTrace(TraceReader.readTraceFromServerFile(serverFile), style) } - async loadTraceFromLocalFile(localFile, style) { - return await this.loadTrace(TraceReader.readTraceFromLocalFile(localFile), style) + async loadTraceFromString(jsonString, style) { + return await this.loadTrace(TraceReader.readTraceFromString(jsonString), style) } loadTrace(trace, style = undefined) { diff --git a/packages/frontend/src/trace.js b/packages/frontend/src/trace.js index 6ac0b50..597b938 100644 --- a/packages/frontend/src/trace.js +++ b/packages/frontend/src/trace.js @@ -97,17 +97,6 @@ export class TraceReader { return new this(traceData).getTrace() } - static async readTraceFromLocalFile(localFile) { - const fileReader = new FileReader() - fileReader.readAsText(localFile) - const result = await new Promise((resolve, reject) => { - fileReader.onload = () => resolve(fileReader.result) - fileReader.onerror = () => reject(fileReader.error) - }) - const traceData = JSON.parse(result) - return this.readTrace(traceData) - } - static async readTraceFromServerFile(serverFile) { const response = await fetch(serverFile) if (!response.ok) throw new Error(`Failed to load trace: ${response.status} ${response.statusText}`) @@ -115,6 +104,11 @@ export class TraceReader { return this.readTrace(traceData) } + static async readTraceFromString(jsonString) { + const traceData = JSON.parse(jsonString) + return this.readTrace(traceData) + } + getTrace() { const objects = this.getObjects(this.traceData.objects) const classes = this.getClasses(this.traceData.classes) diff --git a/packages/frontend/yarn.lock b/packages/frontend/yarn.lock index e59176b..5500de6 100644 --- a/packages/frontend/yarn.lock +++ b/packages/frontend/yarn.lock @@ -117,6 +117,11 @@ resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.2.tgz#36b6a9cb5ffbecdf89815c94d0c0ffa489ac5ecb" integrity sha512-m5cPn3e2+FDCOgi1mz0RexTUvvQibBebOUlUlW0+YrMjDTPkiJ6VTKukA1GRsvRw+12KyJndNjj0O4AgTxm2Pg== +bootstrap@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.2.tgz#97226583f27aae93b2b28ab23f4c114757ff16ae" + integrity sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g== + collect.js@^4.36.1: version "4.36.1" resolved "https://registry.yarnpkg.com/collect.js/-/collect.js-4.36.1.tgz#0194c52e90e01db6f136d28e7a3cf88c5687894d"