-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(web-vis): refactor app.js into web components (#101)
- Move out logic for manipulating vector data into its own file - Refactor app.js into web components for better separation
- Loading branch information
1 parent
d8a4603
commit eb8790f
Showing
5 changed files
with
138 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,135 +1,95 @@ | ||
import "./styles.css"; | ||
import * as wasm from "web-vis"; | ||
import { RrbVec } from "./rrbtree"; | ||
import { VectorFactory, VectorVis } from "./vector"; | ||
|
||
class Vector { | ||
constructor(id) { | ||
this._id = id; | ||
class VectorComponent extends HTMLElement { | ||
constructor(vectorVis) { | ||
super(); | ||
this.vectorVis = vectorVis; | ||
} | ||
|
||
id() { | ||
return this._id; | ||
} | ||
connectedCallback() { | ||
this.id = this.vectorVis.id(); | ||
this.classList.add("vector"); | ||
|
||
setSize(size) { | ||
wasm.set_vec_size(this._id, size); | ||
} | ||
const sliderContainer = document.createElement("div"); | ||
sliderContainer.classList.add("slider-container"); | ||
|
||
json() { | ||
return JSON.parse(wasm.get(this._id)); | ||
} | ||
} | ||
const sliderTooltip = document.createElement("output"); | ||
sliderTooltip.classList.add("tooltip-value"); | ||
|
||
class VectorVis { | ||
constructor(vector) { | ||
this.vector = vector; | ||
} | ||
|
||
id() { | ||
return `tree${this.vector.id()}`; | ||
} | ||
const slider = document.createElement("input"); | ||
slider.addEventListener("change", () => | ||
this.vectorVis.setSize(slider.value) | ||
); | ||
slider.type = "range"; | ||
slider.min = 1; | ||
slider.max = 512; | ||
|
||
setSize(size) { | ||
if (this.rrbVecVis === undefined) { | ||
this.rrbVecVis = new RrbVec(`#${this.id()}`); | ||
} | ||
sliderContainer.appendChild(slider); | ||
sliderContainer.appendChild(sliderTooltip); | ||
|
||
this.vector.setSize(size); | ||
const rrbVec = this.vector.json(); | ||
const updateTooltip = () => { | ||
const offset = | ||
((slider.value - slider.min) * 100) / (slider.max - slider.min); | ||
sliderTooltip.innerHTML = `<span>${slider.value}</span>`; | ||
|
||
this.rrbVecVis.set(rrbVec); | ||
} | ||
} | ||
// Kind of magic numbers based on size of the native UI thumb | ||
sliderTooltip.style.left = `calc(${offset}% + (${5 - offset * 0.1}px))`; | ||
}; | ||
|
||
class VectorFactory { | ||
static create() { | ||
const vecId = wasm.len(); | ||
slider.addEventListener("input", updateTooltip); | ||
updateTooltip(); | ||
|
||
wasm.push_vec(); | ||
this.appendChild(sliderContainer); | ||
|
||
return new Vector(vecId); | ||
if (this.vectorVis.size() > 0) { | ||
slider.value = this.vectorVis.size(); | ||
slider.dispatchEvent(new Event("input")); | ||
slider.dispatchEvent(new Event("change")); | ||
} | ||
} | ||
} | ||
|
||
function createTree(vectorVis) { | ||
const tree = document.createElement("div"); | ||
tree.id = vectorVis.id(); | ||
tree.classList.add("tree"); | ||
|
||
const sliderContainer = document.createElement("div"); | ||
sliderContainer.classList.add("slider-container"); | ||
|
||
const sliderTooltip = document.createElement("output"); | ||
sliderTooltip.classList.add("tooltip-value"); | ||
|
||
const slider = document.createElement("input"); | ||
slider.addEventListener("change", () => vectorVis.setSize(slider.value)); | ||
slider.type = "range"; | ||
slider.min = 1; | ||
slider.max = 512; | ||
|
||
sliderContainer.appendChild(slider); | ||
sliderContainer.appendChild(sliderTooltip); | ||
|
||
const updateTooltip = () => { | ||
const offset = | ||
((slider.value - slider.min) * 100) / (slider.max - slider.min); | ||
sliderTooltip.innerHTML = `<span>${slider.value}</span>`; | ||
|
||
// Kind of magic numbers based on size of the native UI thumb | ||
sliderTooltip.style.left = `calc(${offset}% + (${5 - offset * 0.1}px))`; | ||
}; | ||
|
||
slider.addEventListener("input", updateTooltip); | ||
updateTooltip(); | ||
|
||
tree.appendChild(sliderContainer); | ||
return { tree, slider }; | ||
} | ||
|
||
function createAddTreeButton(onClick) { | ||
const container = document.createElement("div"); | ||
container.classList.add("button-add-tree-container"); | ||
|
||
const button = document.createElement("button"); | ||
button.type = "button"; | ||
button.classList.add("button-add-tree"); | ||
class AddVectorButtonComponent extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.onClick = null; | ||
} | ||
|
||
const plusIcon = document.createElement("span"); | ||
plusIcon.classList.add("button-add-tree-icon"); | ||
plusIcon.innerHTML = "+"; | ||
connectedCallback() { | ||
const plusIcon = document.createElement("span"); | ||
plusIcon.classList.add("button-add-vector"); | ||
plusIcon.innerHTML = "+"; | ||
|
||
button.appendChild(plusIcon); | ||
button.addEventListener("click", () => onClick(container)); | ||
this.classList.add("button-add-vector-container"); | ||
this.addEventListener("click", (event) => { | ||
this.onClick(event); | ||
}); | ||
|
||
container.appendChild(button); | ||
return container; | ||
this.appendChild(plusIcon); | ||
} | ||
} | ||
|
||
function createGrid() { | ||
const grid = document.createElement("div"); | ||
grid.classList.add("grid-tree"); | ||
|
||
return grid; | ||
class GridComponent extends HTMLElement { | ||
connectedCallback() { | ||
this.classList.add("grid-vector"); | ||
} | ||
} | ||
const grid = createGrid(); | ||
|
||
const addTree = (button, initialSize) => { | ||
const vector = VectorFactory.create(); | ||
const vectorVis = new VectorVis(vector); | ||
const { tree, slider } = createTree(vectorVis); | ||
customElements.define("vector-component", VectorComponent); | ||
customElements.define("add-vector-button-component", AddVectorButtonComponent); | ||
customElements.define("grid-component", GridComponent); | ||
|
||
grid.insertBefore(tree, button); | ||
const grid = new GridComponent(); | ||
const addVectorButton = new AddVectorButtonComponent(); | ||
addVectorButton.onClick = (event) => { | ||
const vectorVis = new VectorVis(VectorFactory.create(64)); | ||
const vectorComponent = new VectorComponent(vectorVis); | ||
|
||
if (initialSize !== undefined) { | ||
slider.value = initialSize; | ||
slider.dispatchEvent(new Event("input")); | ||
slider.dispatchEvent(new Event("change")); | ||
} | ||
grid.insertBefore(vectorComponent, event.currentTarget); | ||
}; | ||
const addTreeButton = createAddTreeButton(addTree); | ||
|
||
grid.appendChild(addTreeButton); | ||
grid.appendChild(addVectorButton); | ||
document.body.appendChild(grid); | ||
|
||
addTree(addTreeButton, 256); | ||
addVectorButton.dispatchEvent(new Event("click")); |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { RrbVec } from "./rrbvec.js"; | ||
import * as wasm from "web-vis"; | ||
|
||
export class Vector { | ||
constructor(id) { | ||
this._id = id; | ||
} | ||
|
||
id() { | ||
return this._id; | ||
} | ||
|
||
setSize(size) { | ||
wasm.set_vec_size(this._id, size); | ||
} | ||
|
||
size() { | ||
return wasm.get_vec_size(this._id); | ||
} | ||
|
||
json() { | ||
return JSON.parse(wasm.get(this._id)); | ||
} | ||
} | ||
|
||
export class VectorFactory { | ||
static create(initialSize) { | ||
const vecId = wasm.len(); | ||
|
||
wasm.push_vec(); | ||
|
||
const vector = new Vector(vecId); | ||
if (initialSize !== undefined) { | ||
vector.setSize(initialSize); | ||
} | ||
return vector; | ||
} | ||
} | ||
|
||
export class VectorVis { | ||
constructor(vector) { | ||
this.vector = vector; | ||
} | ||
|
||
id() { | ||
return `vec${this.vector.id()}`; | ||
} | ||
|
||
setSize(size) { | ||
if (this.rrbVecVis === undefined) { | ||
this.rrbVecVis = new RrbVec(`#${this.id()}`); | ||
} | ||
|
||
this.vector.setSize(size); | ||
const rrbVec = this.vector.json(); | ||
|
||
this.rrbVecVis.set(rrbVec); | ||
} | ||
|
||
size() { | ||
return this.vector.size(); | ||
} | ||
} |
eb8790f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
pvec-rs – ./
pvec-rs-git-trunk-arazabishov.vercel.app
pvec-rs-arazabishov.vercel.app
pvec-rs.vercel.app