From f75a7172dfd10d6948fcdbf6bfb36ccd4a4d1ba5 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 12:45:06 +0200 Subject: [PATCH 1/9] renamed the directory to reflect the title --- {js-plot => show-me-the-visualization}/.gitignore | 0 {js-plot => show-me-the-visualization}/README.md | 0 {js-plot => show-me-the-visualization}/algebra.cpp | 0 {js-plot => show-me-the-visualization}/app.html | 0 {js-plot => show-me-the-visualization}/bindings.cpp | 0 {js-plot => show-me-the-visualization}/cli.cpp | 0 .../composite.png | Bin .../newtonraphson.cpp | 0 .../newtonraphson.hpp | 0 .../newtonraphson.js | 0 .../newtonraphson.wasm | Bin .../root-plot.json | 0 .../root-plot.png | Bin {js-plot => show-me-the-visualization}/scatter.html | 0 {js-plot => show-me-the-visualization}/scatter.png | Bin 15 files changed, 0 insertions(+), 0 deletions(-) rename {js-plot => show-me-the-visualization}/.gitignore (100%) rename {js-plot => show-me-the-visualization}/README.md (100%) rename {js-plot => show-me-the-visualization}/algebra.cpp (100%) rename {js-plot => show-me-the-visualization}/app.html (100%) rename {js-plot => show-me-the-visualization}/bindings.cpp (100%) rename {js-plot => show-me-the-visualization}/cli.cpp (100%) rename {js-plot => show-me-the-visualization}/composite.png (100%) rename {js-plot => show-me-the-visualization}/newtonraphson.cpp (100%) rename {js-plot => show-me-the-visualization}/newtonraphson.hpp (100%) rename {js-plot => show-me-the-visualization}/newtonraphson.js (100%) rename {js-plot => show-me-the-visualization}/newtonraphson.wasm (100%) rename {js-plot => show-me-the-visualization}/root-plot.json (100%) rename {js-plot => show-me-the-visualization}/root-plot.png (100%) rename {js-plot => show-me-the-visualization}/scatter.html (100%) rename {js-plot => show-me-the-visualization}/scatter.png (100%) diff --git a/js-plot/.gitignore b/show-me-the-visualization/.gitignore similarity index 100% rename from js-plot/.gitignore rename to show-me-the-visualization/.gitignore diff --git a/js-plot/README.md b/show-me-the-visualization/README.md similarity index 100% rename from js-plot/README.md rename to show-me-the-visualization/README.md diff --git a/js-plot/algebra.cpp b/show-me-the-visualization/algebra.cpp similarity index 100% rename from js-plot/algebra.cpp rename to show-me-the-visualization/algebra.cpp diff --git a/js-plot/app.html b/show-me-the-visualization/app.html similarity index 100% rename from js-plot/app.html rename to show-me-the-visualization/app.html diff --git a/js-plot/bindings.cpp b/show-me-the-visualization/bindings.cpp similarity index 100% rename from js-plot/bindings.cpp rename to show-me-the-visualization/bindings.cpp diff --git a/js-plot/cli.cpp b/show-me-the-visualization/cli.cpp similarity index 100% rename from js-plot/cli.cpp rename to show-me-the-visualization/cli.cpp diff --git a/js-plot/composite.png b/show-me-the-visualization/composite.png similarity index 100% rename from js-plot/composite.png rename to show-me-the-visualization/composite.png diff --git a/js-plot/newtonraphson.cpp b/show-me-the-visualization/newtonraphson.cpp similarity index 100% rename from js-plot/newtonraphson.cpp rename to show-me-the-visualization/newtonraphson.cpp diff --git a/js-plot/newtonraphson.hpp b/show-me-the-visualization/newtonraphson.hpp similarity index 100% rename from js-plot/newtonraphson.hpp rename to show-me-the-visualization/newtonraphson.hpp diff --git a/js-plot/newtonraphson.js b/show-me-the-visualization/newtonraphson.js similarity index 100% rename from js-plot/newtonraphson.js rename to show-me-the-visualization/newtonraphson.js diff --git a/js-plot/newtonraphson.wasm b/show-me-the-visualization/newtonraphson.wasm similarity index 100% rename from js-plot/newtonraphson.wasm rename to show-me-the-visualization/newtonraphson.wasm diff --git a/js-plot/root-plot.json b/show-me-the-visualization/root-plot.json similarity index 100% rename from js-plot/root-plot.json rename to show-me-the-visualization/root-plot.json diff --git a/js-plot/root-plot.png b/show-me-the-visualization/root-plot.png similarity index 100% rename from js-plot/root-plot.png rename to show-me-the-visualization/root-plot.png diff --git a/js-plot/scatter.html b/show-me-the-visualization/scatter.html similarity index 100% rename from js-plot/scatter.html rename to show-me-the-visualization/scatter.html diff --git a/js-plot/scatter.png b/show-me-the-visualization/scatter.png similarity index 100% rename from js-plot/scatter.png rename to show-me-the-visualization/scatter.png From 27135e1e359565f265b20b144fc50fbb522f80d2 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 12:45:39 +0200 Subject: [PATCH 2/9] bunch of stylistic changes/rephrasing --- show-me-the-visualization/README.md | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/show-me-the-visualization/README.md b/show-me-the-visualization/README.md index 13d149a..c98e398 100644 --- a/show-me-the-visualization/README.md +++ b/show-me-the-visualization/README.md @@ -14,12 +14,12 @@ Let's make changes to the C++ code to store the data from the iterations. To store data of an iteration we will use a structure with the following variables: -* x, x value, starts with initial guess and ends with root result -* y, result of passing x through equation -* slope, slope or derivative at value x -* delta_x, y divided by slope +* `x`: x value, starting with the value of `initial_guess` and ending with the estimate of the `equation`'s root +* `y`: result of passing `x` through `equation` +* `slope`: result of passing `x` through `derivative` +* `delta_x`: `y` divided by `slope` -We will add `iterations` public property to the NewtonRaphson which is a vector of iteration structs. So the `newtonraphson.hpp` becomes +We will add a vector of `Iteration` `structs` named `iterations` as a public property to the `NewtonRaphson` class. So `newtonraphson.hpp` becomes: ```cpp #ifndef H_NEWTONRAPHSON_HPP @@ -47,7 +47,7 @@ class NewtonRaphson { ``` File: _newtonraphson.hpp_ -The `newtonraphson.cpp` is rewritten from a while loop to a do while loop like with a push to the iterations vector each cycle. +The `do` loop in `newtonraphson.cpp` is updated to include a `push_back` to the `iterations` vector. This way, we can record the value of relevant variables in each cycle, as follows: ```cpp #include "newtonraphson.hpp" @@ -72,7 +72,7 @@ float NewtonRaphson::solve(float initial_guess) { ``` File: _newtonraphson.cpp_. -Before we go into Emscripten world, lets first test our c++ code. We will check if the iteration property is actually populated correctly by wrapping the code in a main function, adding some print statements, compiling it and running it. +Before we go into Emscripten world, lets first test our C++ code. We will check if the iteration property is actually populated correctly by wrapping the code in a `main` function, adding some `print` statements, compiling it and running it. ```cpp #include @@ -101,13 +101,13 @@ int main() { ``` File: _cli.cpp_. -Compile it with +Compile it with: ```shell g++ -o cli.exe newtonraphson.cpp cli.cpp ``` -Run with +Run with: ```shell ./cli.exe @@ -119,14 +119,14 @@ index = 4 x = -1.02 y = -0.28 slope = 14.40 delta_x = -0.02 index = 5 x = -1.00 y = -0.00 slope = 14.01 delta_x = -0.00 ``` -The last iteration has `-1.00` as x, which is what we expected. +The last iteration has `x = -1.00`, which is what we expected. ## Bindings -Emscripten can handle simple types like float and int, but needs help exposing more complex types to JavaScript like the iterations property. -We need to use [value_object](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#value-types) to expose the Iteration struct and [register_vector](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#built-in-type-conversions) as the iterations property type. +Emscripten can handle simple types like `float` and `int`, but needs help exposing more complex types to JavaScript like the `iterations` property. +We need to use [`value_object`](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#value-types) to expose the `Iteration` `struct` and [`register_vector`](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#built-in-type-conversions) as the `iterations` property type. -So the bindings look like +So the bindings look like this: ```cpp #include @@ -154,7 +154,7 @@ EMSCRIPTEN_BINDINGS(newtonraphson) { ``` File: _bindings.cpp_. -Same as in [previous blog](TODO) we can compile to a WebAssembly module with Emscripten using `emcc` command +We can now compile our C++ code to a WebAssembly module with Emscripten using `emcc` command, exactly like we did [before](TODO): ```shell emcc -I. -o newtonraphson.js -Oz -s MODULARIZE=1 \ @@ -187,8 +187,9 @@ const initial_guess = -4; const tolerance = 0.001; const newtonraphson = new NewtonRaphson(tolerance); newtonraphson.solve(initial_guess); -// newtonraphson.iterations is a vector object which not consumeable by Vega -// So convert Emscripten vector of objects to JavaScript array of objects +// newtonraphson.iterations is a vector object, which is not +// consumeable by Vega, so we need to convert Emscripten's +// vector of objects to a JavaScript array of objects first const iterations = new Array( newtonraphson.iterations.size() ).fill().map( @@ -198,7 +199,7 @@ const iterations = new Array( ); ``` -Let's have a look at the data we want to plot, by logging it to the with `console.log(JSON.stringify(iterations, null, 2))` to get +Let's have a look at the data we want to plot, by logging it to the console with `console.log(JSON.stringify(iterations, null, 2))`, which should return the following data: ```json [ From 373ff9e4f5a194c014580c13c0f068457bd34f85 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 12:51:03 +0200 Subject: [PATCH 3/9] couple more cleanups --- show-me-the-visualization/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/show-me-the-visualization/README.md b/show-me-the-visualization/README.md index c98e398..85da1ae 100644 --- a/show-me-the-visualization/README.md +++ b/show-me-the-visualization/README.md @@ -72,7 +72,7 @@ float NewtonRaphson::solve(float initial_guess) { ``` File: _newtonraphson.cpp_. -Before we go into Emscripten world, lets first test our C++ code. We will check if the iteration property is actually populated correctly by wrapping the code in a `main` function, adding some `print` statements, compiling it and running it. +Before we go into Emscripten world, let's first test our C++ code. We can check if the iteration property is populated correctly by extending the command line interface we made in the [previous blog](../run-your-c++-code-on-the-web), as follows: ```cpp #include From d2ba4eb0a59b85c7b830dbb19638a18a78446592 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 12:52:05 +0200 Subject: [PATCH 4/9] cli.cpp had wrong type --- show-me-the-visualization/cli.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/show-me-the-visualization/cli.cpp b/show-me-the-visualization/cli.cpp index fb69bc9..8d4650b 100644 --- a/show-me-the-visualization/cli.cpp +++ b/show-me-the-visualization/cli.cpp @@ -4,8 +4,8 @@ #include "newtonraphson.hpp" int main() { - double initial_guess = -4; - double tolerance = 0.001; + float initial_guess = -4; + float tolerance = 0.001; NewtonRaphson newtonraphson(tolerance); newtonraphson.solve(initial_guess); From 5f0022303176ba20ba9bc26b883e44296798a89d Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 12:53:05 +0200 Subject: [PATCH 5/9] wrong indent --- show-me-the-visualization/bindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/show-me-the-visualization/bindings.cpp b/show-me-the-visualization/bindings.cpp index e6f81a2..3011d9c 100644 --- a/show-me-the-visualization/bindings.cpp +++ b/show-me-the-visualization/bindings.cpp @@ -5,7 +5,7 @@ using namespace emscripten; EMSCRIPTEN_BINDINGS(newtonraphson) { class_("NewtonRaphson") - .constructor() + .constructor() .function("solve", &NewtonRaphson::solve) .property("iterations", &NewtonRaphson::iterations) ; From b6d8862a5cfe2e786df5cffa37e186e0e1cf164d Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 13:29:10 +0200 Subject: [PATCH 6/9] more cleanup, style, rephrase --- show-me-the-visualization/README.md | 39 ++++++++--------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/show-me-the-visualization/README.md b/show-me-the-visualization/README.md index 85da1ae..5dd538c 100644 --- a/show-me-the-visualization/README.md +++ b/show-me-the-visualization/README.md @@ -2,7 +2,7 @@ Running C++ code in a web browser is all nice, but we really want to grab someones attention by visualizing something. In this blog we are going to make a plot from the results coming from our C++ code. -To make a plot we need some data. In a [previous](TODO fix url ../js-webapp) post we found the root of an equation using the Newton-Raphson algorithm implemented in C++ and compiled to a WebAsssembly module. +To make a plot we need some data. In the [previous post](../run-your-c++-on-the-web) we found the root of an equation using the Newton-Raphson algorithm implemented in C++ and compiled to a WebAsssembly module. A single root value makes for a depressing plot. The Newton-Raphson algorithm uses iterations to find the root so we will capture the data of each iteration and plot those. ![Image](root-plot.png) @@ -154,32 +154,13 @@ EMSCRIPTEN_BINDINGS(newtonraphson) { ``` File: _bindings.cpp_. -We can now compile our C++ code to a WebAssembly module with Emscripten using `emcc` command, exactly like we did [before](TODO): +We can now compile our C++ code to a WebAssembly module with Emscripten using `emcc` command, exactly [like we did before](../run-your-c++-code-on-the-web): ```shell emcc -I. -o newtonraphson.js -Oz -s MODULARIZE=1 \ -s EXPORT_NAME=createModule --bind newtonraphson.cpp bindings.cpp ``` - - To get the iteration data in JavaScript we use the following code ```javascript @@ -260,9 +241,9 @@ So let's plot the iteration index against the y found in each iteration to see h The Vega-Lite specification is constructed out of the following blocks -* data, the iterations we want to plot as an array of iteration objects -* mark, for line plot use [line](https://vega.github.io/vega-lite/docs/line.html) marker -* encoding, which field should go on which axis +* `"data"`, the iterations we want to plot as an array of iteration objects +* `"encoding"`, which field should go on which axis +* `"mark"`, for line plot use [line](https://vega.github.io/vega-lite/docs/line.html) marker ```js const spec = { @@ -287,7 +268,7 @@ const spec = { }; ``` -To render a specification we need to use the `vegaEmbed(element, spec)` method which accepts a HTML element and a Vega-Lite specification. +To render a specification we need to use the `vegaEmbed(element, spec)` method which accepts an HTML element and a Vega-Lite specification. ```html @@ -307,7 +288,7 @@ To render a specification we need to use the `vegaEmbed(element, spec)` method w ``` -The complete HTML pages looks like +The complete HTML page looks like this: ```html @@ -361,15 +342,15 @@ The complete HTML pages looks like ``` -File: _scatter.html. +File: _scatter.html_. -We'll need a web server to display the HTML page in a web browser. For this, we'll use the http.server module from Python 3 to host all files on port 8000, like so: +We'll need a web server to display the HTML page in a web browser. For this, we'll use the `http.server` module from Python 3 to host all files on port 8000, like so: ```shell python3 -m http.server 8000 ``` -When we visit the web page at [http://localhost:8000/scatter.html](http://localhost:8000/scatter.html), we will be greeted by the following plot. We can zoom with mouse wheel and pan by dragging. Also when we hover over a point we get a tooltip with all iteration data. +When we visit the web page at [http://localhost:8000/scatter.html](http://localhost:8000/scatter.html), we will be greeted by the following plot. We can zoom with the mouse wheel and pan by dragging. Hovering over a point shows a tooltip with relevant data at that point. [![Image](scatter.png)](https://nlesc-jcer.github.io/run-cpp-on-web/js-plot/scatter.html) (Click on image to get interactive version) From 4e0c3764aeec4f1bf1713534e5a9ab74e0711488 Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 13:32:28 +0200 Subject: [PATCH 7/9] Update README.md --- show-me-the-visualization/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/show-me-the-visualization/README.md b/show-me-the-visualization/README.md index 5dd538c..6a1bfc1 100644 --- a/show-me-the-visualization/README.md +++ b/show-me-the-visualization/README.md @@ -72,7 +72,7 @@ float NewtonRaphson::solve(float initial_guess) { ``` File: _newtonraphson.cpp_. -Before we go into Emscripten world, let's first test our C++ code. We can check if the iteration property is populated correctly by extending the command line interface we made in the [previous blog](../run-your-c++-code-on-the-web), as follows: +Before we go into the Emscripten world, let's first test our C++ code. We can check if the iteration property is populated correctly, by extending the command line interface we made in the [previous blog](../run-your-c++-code-on-the-web) as follows: ```cpp #include From 771d7174dc9f9dff18379004aa9505f32341041c Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 13:34:50 +0200 Subject: [PATCH 8/9] Update README.md --- show-me-the-visualization/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/show-me-the-visualization/README.md b/show-me-the-visualization/README.md index 6a1bfc1..d195f15 100644 --- a/show-me-the-visualization/README.md +++ b/show-me-the-visualization/README.md @@ -2,7 +2,7 @@ Running C++ code in a web browser is all nice, but we really want to grab someones attention by visualizing something. In this blog we are going to make a plot from the results coming from our C++ code. -To make a plot we need some data. In the [previous post](../run-your-c++-on-the-web) we found the root of an equation using the Newton-Raphson algorithm implemented in C++ and compiled to a WebAsssembly module. +To make a plot we need some data. In the [previous post](../run-your-c%2B%2B-code-on-the-web) we found the root of an equation using the Newton-Raphson algorithm implemented in C++ and compiled to a WebAsssembly module. A single root value makes for a depressing plot. The Newton-Raphson algorithm uses iterations to find the root so we will capture the data of each iteration and plot those. ![Image](root-plot.png) @@ -72,7 +72,7 @@ float NewtonRaphson::solve(float initial_guess) { ``` File: _newtonraphson.cpp_. -Before we go into the Emscripten world, let's first test our C++ code. We can check if the iteration property is populated correctly, by extending the command line interface we made in the [previous blog](../run-your-c++-code-on-the-web) as follows: +Before we go into the Emscripten world, let's first test our C++ code. We can check if the iteration property is populated correctly, by extending the command line interface we made in the [previous blog](../run-your-c%2B%2B-code-on-the-web) as follows: ```cpp #include @@ -154,7 +154,7 @@ EMSCRIPTEN_BINDINGS(newtonraphson) { ``` File: _bindings.cpp_. -We can now compile our C++ code to a WebAssembly module with Emscripten using `emcc` command, exactly [like we did before](../run-your-c++-code-on-the-web): +We can now compile our C++ code to a WebAssembly module with Emscripten using `emcc` command, exactly [like we did before](../run-your-c%2B%2B-code-on-the-web): ```shell emcc -I. -o newtonraphson.js -Oz -s MODULARIZE=1 \ @@ -359,7 +359,7 @@ When we visit the web page at [http://localhost:8000/scatter.html](http://localh In the first blog of this series we plotted the equation and root as -![equation.png](https://nlesc-jcer.github.io/run-cpp-on-web/run-your-c++-code-on-the-web/equation.png) +![equation.png](https://nlesc-jcer.github.io/run-cpp-on-web/run-your-c%2B%2B-code-on-the-web/equation.png) It would be nice to write a specification of this plot together with the iterations the root finding algorithm went through. Vega-Lite can superimpose one chart on top of another with [layers](https://vega.github.io/vega-lite/docs/layer.html) keyword. From e211118d61f5ecfc5ab2e8b031fb5157220965bf Mon Sep 17 00:00:00 2001 From: "Jurriaan H. Spaaks" Date: Thu, 24 Sep 2020 15:49:07 +0200 Subject: [PATCH 9/9] links updated --- show-me-the-visualization/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/show-me-the-visualization/README.md b/show-me-the-visualization/README.md index 5dd538c..6ef8ed5 100644 --- a/show-me-the-visualization/README.md +++ b/show-me-the-visualization/README.md @@ -352,7 +352,7 @@ python3 -m http.server 8000 When we visit the web page at [http://localhost:8000/scatter.html](http://localhost:8000/scatter.html), we will be greeted by the following plot. We can zoom with the mouse wheel and pan by dragging. Hovering over a point shows a tooltip with relevant data at that point. -[![Image](scatter.png)](https://nlesc-jcer.github.io/run-cpp-on-web/js-plot/scatter.html) +[![Image](scatter.png)](https://nlesc-jcer.github.io/run-cpp-on-web/show-me-the-visualization/scatter.html) (Click on image to get interactive version) ## Advanced plot @@ -527,7 +527,7 @@ File: _app.html_ Visiting the page should give us a plot like -[![Image](composite.png)](https://nlesc-jcer.github.io/run-cpp-on-web/js-plot/app.html) +[![Image](composite.png)](https://nlesc-jcer.github.io/run-cpp-on-web/show-me-the-visualization/app.html) (Click on image to get interactive version) ## Wrap up