Skip to content

Commit 9c24427

Browse files
adding web demo using web assembly support (#257)
1 parent 5694574 commit 9c24427

16 files changed

+605
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
4+
## 16.17.13
5+
- Added Decision Tree web demo using Web Assembly
6+
37
## 16.17.12
48
- update in README
59
- mention that web is possible

example/wasm/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# https://dart.dev/guides/libraries/private-files
2+
# Created by `dart pub`
3+
.dart_tool/

example/wasm/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0
2+
3+
- Initial version.

example/wasm/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# wasm (dart)
2+
3+
A simple demo for [ml_algo](https://pub.dev/packages/ml_algo)
4+
Decision tree example for predicting an iris' species based on its dimensions.
5+
This simple js web demo uses Dart Web Assembly support
6+
7+
## building/running
8+
- Serve the output, example
9+
10+
$ cd site
11+
$ dart pub global activate dhttpd
12+
$ dart pub global run dhttpd
13+
14+
- Open your brwoser at : http://localhost:8080/site/index.html
15+
16+
- type flower dimensions and run either using :
17+
- a preloaded model (faster)
18+
- training a (small) model on on the fly
19+
20+
![screenshot](screenshot.png)
21+
22+
23+
- Compile with Wasm to a new site output directory:
24+
25+
mywebapp$ dart compile wasm web/main.dart -o site/test.wasm
26+
27+
For more details see documentation from https://dart.dev/web/wasm

example/wasm/analysis_options.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file configures the static analysis results for your project (errors,
2+
# warnings, and lints).
3+
#
4+
# This enables the 'recommended' set of lints from `package:lints`.
5+
# This set helps identify many issues that may lead to problems when running
6+
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
7+
# style and format.
8+
#
9+
# If you want a smaller set of lints you can change this to specify
10+
# 'package:lints/core.yaml'. These are just the most critical lints
11+
# (the recommended set includes the core lints).
12+
# The core lints are also what is used by pub.dev for scoring packages.
13+
14+
include: package:lints/recommended.yaml
15+
16+
# Uncomment the following section to specify additional rules.
17+
18+
# linter:
19+
# rules:
20+
# - camel_case_types
21+
22+
# analyzer:
23+
# exclude:
24+
# - path/to/excluded/files/**
25+
26+
# For more information about the core and recommended set of lints, see
27+
# https://dart.dev/go/core-lints
28+
29+
# For additional information about configuring this file, see
30+
# https://dart.dev/guides/language/analysis-options

example/wasm/pubspec.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: wasm
2+
description: An absolute bare-bones web app.
3+
version: 1.0.0
4+
# repository: https://github.com/my_org/my_repo
5+
6+
environment:
7+
sdk: ^3.5.0
8+
9+
# Add regular dependencies here.
10+
dependencies:
11+
web: ^0.5.1
12+
ml_algo: ^16.17.11
13+
ml_dataframe: ^1.6.0
14+
ml_preprocessing: ^7.0.2
15+
16+
dev_dependencies:
17+
build_runner: ^2.4.8
18+
build_web_compilers: ^4.0.9
19+
lints: ^4.0.0

example/wasm/screenshot.png

56.2 KB
Loading

example/wasm/site/index.html

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Test ml dart wasm</title>
5+
<link rel="preload" href="/test.wasm" as="fetch" crossorigin>
6+
</head>
7+
<body>
8+
<h1>What iris is this ?</h1>
9+
<h2>
10+
<form onsubmit="return getValue('commands')">
11+
SepalLengthCm: <input type="number" name="int1" id="int1"><br />
12+
SepalWidthCm: <input type="number" name="int2" id="int2"><br />
13+
PetalLengthCm: <input type="number" name="int3" id="int3"><br />
14+
PetalWidthCm: <input type="number" name="int4" id="int4"><br />
15+
<br>
16+
</form>
17+
<p></p>
18+
<div id="decisionTreeLoaded_output">decisionTreeLoaded: Not run yet.</div>
19+
<div id="decisionTreeFull">decisionTreeFull: Not run yet.</div>
20+
</h2>
21+
<script type="module">
22+
const dartModulePromise = WebAssembly.compileStreaming(fetch('/test.wasm'));
23+
const imports = {};
24+
let dart2wasm_runtime = await import('/test.mjs');
25+
let moduleInstance =
26+
await dart2wasm_runtime.instantiate(dartModulePromise, imports);
27+
dart2wasm_runtime.invoke(moduleInstance);
28+
</script>
29+
<script>
30+
function testDecisionTreePreLoaded() {
31+
let int1 = parseInt(document.getElementById('int1').value);
32+
let int2 = parseInt(document.getElementById('int2').value);
33+
let int3 = parseInt(document.getElementById('int3').value);
34+
let int4 = parseInt(document.getElementById('int4').value);
35+
console.log(`int1 ${int1}`);
36+
if (isNaN(parseInt(int1)) || isNaN(parseInt(int2)) || isNaN(parseInt(int3)) || isNaN(parseInt(int4))) {
37+
document.querySelector("#decisionTreeLoaded_output").innerHTML = "decisionTreeLoaded: " + "invalid";
38+
} else {
39+
const result = foo.decisionTreeLoaded(int1, int2, int3, int4);
40+
document.querySelector("#decisionTreeLoaded_output").innerHTML = "decisionTreeLoaded: " + result;
41+
}
42+
}
43+
async function testDecisionTreeFull() {
44+
let int1 = parseInt(document.getElementById('int1').value);
45+
let int2 = parseInt(document.getElementById('int2').value);
46+
let int3 = parseInt(document.getElementById('int3').value);
47+
let int4 = parseInt(document.getElementById('int4').value);
48+
console.log(`int1 ${int1}`);
49+
if (isNaN(parseInt(int1)) || isNaN(parseInt(int2)) || isNaN(parseInt(int3)) || isNaN(parseInt(int4))) {
50+
document.querySelector("#decisionTreeFull").innerHTML = "decisionTreeFull: " + "invalid";
51+
} else {
52+
const result = foo.decisionTreeFull(int1, int2, int3, int4);
53+
document.querySelector("#decisionTreeFull").innerHTML = "decisionTreeFull: " + result;
54+
}
55+
}
56+
</script>
57+
<div style="display: flex;justify-content: center;">
58+
<button onclick="testDecisionTreePreLoaded()" style="margin-right: 10px;">test loading model </button>
59+
<button onclick="testDecisionTreeFull()">test decision tree model</button>
60+
</div>
61+
</body>
62+
63+
</html>

example/wasm/site/main.dart.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(async function () {
2+
let dart2wasm_runtime;
3+
let moduleInstance;
4+
try {
5+
const dartModulePromise = WebAssembly.compileStreaming(fetch('main.wasm'));
6+
const imports = {};
7+
dart2wasm_runtime = await import('./main.mjs');
8+
moduleInstance = await dart2wasm_runtime.instantiate(dartModulePromise, imports);
9+
} catch (exception) {
10+
console.error(`Failed to fetch and instantiate wasm module: ${exception}`);
11+
console.error('See https://dart.dev/web/wasm for more information.');
12+
}
13+
14+
if (moduleInstance) {
15+
try {
16+
await dart2wasm_runtime.invoke(moduleInstance);
17+
} catch (exception) {
18+
console.error(`Exception while invoking test: ${exception}`);
19+
}
20+
}
21+
})();

example/wasm/site/styles.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
2+
3+
html, body {
4+
width: 100%;
5+
height: 100%;
6+
margin: 0;
7+
padding: 0;
8+
font-family: 'Roboto', sans-serif;
9+
}
10+
11+
#output {
12+
padding: 20px;
13+
text-align: center;
14+
}

0 commit comments

Comments
 (0)