diff --git a/src/components/tools/astro-plot.html b/src/components/tools/astro-plot.html new file mode 100644 index 000000000..135d786df --- /dev/null +++ b/src/components/tools/astro-plot.html @@ -0,0 +1,16 @@ + + diff --git a/src/components/tools/astro-plot.js b/src/components/tools/astro-plot.js new file mode 100644 index 000000000..6eed758d8 --- /dev/null +++ b/src/components/tools/astro-plot.js @@ -0,0 +1,180 @@ +import Morph from 'src/components/widgets/lively-morph.js'; + +import * as d3 from "https://d3js.org/d3.v4.min.js" +import * as Plotly from "https://cdn.plot.ly/plotly-2.32.0.min.js" + +const traceConfig = { + +} + +export default class AstroPlot extends Morph { + showFeature(feature) { + const container = this.get('#embedding_plot'); + const existingTraceIndex = this.plot && this.plot.data.findIndex(trace => trace.name === 'live_embedding'); + if (existingTraceIndex > -1) { + Plotly.deleteTraces(container, existingTraceIndex); + } + + const { umap_embedding, content, cluster } = feature; + + // Add the new yellow point + const newTrace = { + x: [umap_embedding[0]], + y: [umap_embedding[1]], + z: [umap_embedding[2]], + mode: 'markers', + marker: { + size: 8, + color: cluster, + colorscale: 'Viridis', + line: { + color: 'rgba(20, 20, 20, 0.8)', + width: 2 + }, + opacity: 0.8, + }, + hoverlabel: { + align: 'left' + }, + customdata: [{ + cluster: 'Cluster ' + cluster, + contentAbbr: `${this.displayContent(content)}...` + }], + hovertemplate: ` + %{customdata.cluster}
+ +
+ + Code:
+ %{customdata.contentAbbr} + + `, + name: 'live_embedding', + type: 'scatter3d' + }; + + Plotly.addTraces(container, newTrace) + } + + displayContent(str) { + return str.slice(0, 100).replace('\n', '
'); + } + + async initialize() { + this.windowTitle = "AstroPlot"; + + lively.html.registerKeys(this); // automatically installs handler for some methods + + + let container = this.get('#embedding_plot') + let getExampleData = () => new Promise((resolve, reject) => { + d3.csv( + 'https://raw.githubusercontent.com/plotly/datasets/master/3d-scatter.csv', + (err, rows) => { + if (err) reject(err) else resolve(rows) + } + ) + }); + + const getRealData2 = async () => { + const response = await fetch("http://127.0.0.1:5000/dataset/d3-force-main/umap"); + return await response.json(); + } + + const getRealData = async () => await fetch("http://127.0.0.1:5000/dataset/d3-force-main/umap") + .then(response => response.json()); + const getClusters = async () => await fetch("http://127.0.0.1:5000/dataset/d3-force-main/clusters") + .then(response => response.json()); + + //const getRealData = async () => await fetch("http://127.0.0.1:5000/dataset/d3-force-main/umap") + + // const response = await getRealData(); + const features = await getRealData(); //await response.json() + const clusters = await getClusters(); + + const dataframe = { + _push(el) { + Object.entries(el).forEach(([key, value]) => { + if (!(key in this)) this[key] = []; + this[key].push(value); + }); + } + }; + + features.forEach(({ + umap_embedding, + function_name, + content, + id + }, i) => dataframe._push({ + x: umap_embedding[0], + y: umap_embedding[1], + z: umap_embedding[2], + text: function_name, + color: clusters[i], + customdata: { + cluster: 'Cluster ' + clusters[i], + content, + contentAbbr: `${this.displayContent(content)}...` + }, + ids: id + })); + + const data = [ + { + ...dataframe, + mode: 'markers+text', + marker: { + size: 8, + line: { + color: 'rgba(217, 217, 217, 0.14)', + width: 0.5 + }, + opacity: 0.8, + color: clusters, + colorscale: 'Viridis', + }, + hoverlabel: { + align: 'left' + }, + hovertemplate: ` +%{customdata.cluster}
+%{text} +

+ +Code:
+%{customdata.contentAbbr} +`, + type: 'scatter3d' + } + ] + + var layout = {margin: { + l: 0, + r: 0, + b: 0, + t: 0 + }}; + + this.plot = await Plotly.newPlot(container, data, layout, { + responsive: true, + displayModeBar: false + }); + } + +/* + livelyInspect(contentNode, inspector) { + // overrides how the inspector displays this component + } +*/ + + async livelyExample() { + // this customizes a default instance to a pretty example + // this is used by the + // this.style.backgroundColor = "lightgray" + // this.someJavaScriptProperty = 42 + // this.appendChild(
This is my content
) + } + + +} \ No newline at end of file diff --git a/src/components/tools/astro-view.html b/src/components/tools/astro-view.html index 26aed4a36..40c3264f0 100644 --- a/src/components/tools/astro-view.html +++ b/src/components/tools/astro-view.html @@ -97,20 +97,32 @@ AST + +
Tokens
xxx
+ +
+ Pool Embedding +
+
+
+
+
- Embeddings + Embeddings
xxxx
+ + - - + + \ No newline at end of file diff --git a/src/components/tools/astro-view.js b/src/components/tools/astro-view.js index 576fc5b84..b14f1ea6f 100644 --- a/src/components/tools/astro-view.js +++ b/src/components/tools/astro-view.js @@ -17,7 +17,6 @@ export default class AstroView extends Morph { get container() { return this.get("#content"); } get sourceEditor() { return this.get("#source"); } - get workspaceEditor() { return this.get("#workspace"); } get sourceLCM() { return this.sourceEditor.livelyCodeMirror(); } get sourceCM() { return this.sourceEditor.currentEditor(); } @@ -31,10 +30,6 @@ export default class AstroView extends Morph { set sourceURL(urlString) { this.sourcePath.value = urlString; } onSourcePathEntered(urlString) { this.loadSourceFile(urlString); } - get workspaceURL() { return this.workspaceEditor.getURL(); } - set workspaceURL(urlString) { - this.workspaceEditor.setURL(urlString) } - get updateButton() { return this.get("#update"); } get autoUpdate() { return this._autoUpdate; } @@ -61,14 +56,6 @@ export default class AstroView extends Morph { await this.sourceEditor.loadFile(); await this.update(); } - - async loadWorkspaceFile(urlString) { - console.log("LOAD Workspace", urlString); - this.workspaceURL = urlString; - this.workspaceEditor.setURL(lively.paths.normalizePath(urlString, "")); - await this.workspaceEditor.loadFile(); - } - async initialize() { this.windowTitle = "Astro View"; @@ -113,18 +100,7 @@ export default class AstroView extends Morph { const source = this.getAttribute("source"); if (source) this.loadSourceFile(source); this.autoUpdate = true; - - - const workspace = this.getAttribute("workspace"); - if (workspace) this.loadWorkspaceFile(workspace); - - this.workspaceEditor.awaitEditor().then(() => { - // this object for workspace.... - this.workspaceEditor.livelyCodeMirror().getDoitContext = () => this - }) - - - + this.dispatchEvent(new CustomEvent("initialize")); } @@ -137,6 +113,8 @@ export default class AstroView extends Morph { async updateTokens() { let api = "http://127.0.0.1:5000"; + let dataset = "d3-force-main"; + try { this.tokens = null; @@ -159,6 +137,29 @@ export default class AstroView extends Morph { this.log(`error fetching tokens: ${e}`); } + try { + let response = await fetch(`${api}/dataset/${dataset}/embedding`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + text: this.source + }), + }) + + let embedding = await response.json() + this.embedding = embedding; + } catch (e) { + this.log(`error fetching embedding: ${e}`); + } + + if (this.embedding) { + let formatted = JSON.stringify(this.embedding) + this.get('#pool_embedding').innerText = formatted + this.get('#astro-plot').showFeature(this.embedding) + } + this.log('fetched tokens', this.tokens) if (this.tokens) { @@ -227,7 +228,7 @@ export default class AstroView extends Morph { this.astInspector.inspect({Error: e.message}); } - this.updateTokens() + this.updateTokens(); } async save() { @@ -249,7 +250,5 @@ export default class AstroView extends Morph { async livelyExample() { await this.loadSourceFile(AstroView.defaultSourceURL); - await this.loadWorkspaceFile(AstroView.defaultWorkspaceURL); - } } \ No newline at end of file