From 5efc18d4c30d717ecac4b70ed45255561f207c71 Mon Sep 17 00:00:00 2001 From: Zachary Charlop-Powers Date: Tue, 15 Oct 2024 11:41:09 -0400 Subject: [PATCH 1/5] start specccing out an example --- src/components/fasta_processing.js | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/components/fasta_processing.js diff --git a/src/components/fasta_processing.js b/src/components/fasta_processing.js new file mode 100644 index 0000000..6a9a715 --- /dev/null +++ b/src/components/fasta_processing.js @@ -0,0 +1,43 @@ +import { dialog, invoke } from "@tauri-apps/api"; + +let open = dialog.open; + +async function choosefasta() { + const selected = open({ + multiple: false, + filters: [ + { + name: "Fasta", + extensions: ["fa", "fasta", "fna"], + }, + ], + }); + return selected; +} + +async function choosefastq() { + const selected = open({ + multiple: false, + filters: [ + { + name: "Fastq", + extensions: ["fq", "fastq"], + }, + ], + }); + return selected; +} + +const fasta_stats = view( + Inputs.button("Get Fasta Stats", { + value: null, + reduce: () => + choosefasta().then((fname) => { + console.log("Selected file:", fname); + return invoke("get_stats", { filename: fname }); + }), + }), +); + +let fasta_stats_realized = + fasta_stats == null ? "Click Above to Get Fasta Statistics" : fasta_stats; From 626ef87455b7afa2285e59b239ca3cd21812696d Mon Sep 17 00:00:00 2001 From: Zachary Charlop-Powers Date: Tue, 15 Oct 2024 12:13:23 -0400 Subject: [PATCH 2/5] begin porting simple fast example --- observablehq.config.ts | 6 ++- package.json | 6 +-- src/components/fasta_processing.js | 62 ++++++++++++++++++++++-------- src/fastx/fasta_simple.md | 31 +++++++++++++++ 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/observablehq.config.ts b/observablehq.config.ts index d2637a7..b510531 100644 --- a/observablehq.config.ts +++ b/observablehq.config.ts @@ -14,6 +14,7 @@ export default { { name: "Simple", path: "fastx/fasta_simple" }, { name: "FQ->Fasta", path: "fastx/fastq_to_fasta" }, { name: "Fastx Stats", path: "fastx/fastx_stats" }, + { name: "Test", path: "fastx/test" }, ], }, { @@ -41,17 +42,18 @@ export default { ], // Some additional configuration options and their defaults: - theme: "default", // try "light", "dark", "slate", etc. + // theme: "default", // try "light", "dark", "slate", etc. // header: "", // what to show in the header (HTML) // head: ({ // path, // }) => ` // // `, + head: '', // footer: "Built with Observable.", // what to show in the footer (HTML) toc: true, // whether to show the table of contents // pager: true, // whether to show previous & next links in the footer // output: "dist", // path to the output root for build - dynamicPaths: ["./icon.png"], + //dynamicPaths: ["./icon.png", "./src/components/timeline.js"], }; diff --git a/package.json b/package.json index 1ff51cd..5d2835a 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,10 @@ "tauri": "tauri" }, "dependencies": { - "@observablehq/framework": "latest", + "@observablehq/framework": "^1.12.0", "@tauri-apps/api": "latest", - "@tauri-apps/plugin-dialog": "^2.0.0", - "@tauri-apps/plugin-shell": "^2.0.0", + "@tauri-apps/plugin-dialog": "latest", + "@tauri-apps/plugin-shell": "latest", "d3-dsv": "^3.0.1", "d3-time-format": "^4.1.0", "ideogram": "^1.47", diff --git a/src/components/fasta_processing.js b/src/components/fasta_processing.js index 6a9a715..fd8f788 100644 --- a/src/components/fasta_processing.js +++ b/src/components/fasta_processing.js @@ -1,8 +1,8 @@ -import { dialog, invoke } from "@tauri-apps/api"; +import { open } from "@tauri-apps/plugin-dialog"; +import { invoke } from "npm:@tauri-apps/api/core"; +import { html } from "npm:htl"; -let open = dialog.open; - -async function choosefasta() { +function choosefasta() { const selected = open({ multiple: false, filters: [ @@ -15,7 +15,7 @@ async function choosefasta() { return selected; } -async function choosefastq() { +function choosefastq() { const selected = open({ multiple: false, filters: [ @@ -28,16 +28,44 @@ async function choosefastq() { return selected; } -const fasta_stats = view( - Inputs.button("Get Fasta Stats", { - value: null, - reduce: () => - choosefasta().then((fname) => { - console.log("Selected file:", fname); - return invoke("get_stats", { filename: fname }); - }), - }), -); +export function getFastaStats() { + try { + // File selection + const selected = open({ + multiple: false, + filters: [ + { + name: "Fasta", + extensions: ["fa", "fasta", "fna"], + }, + ], + }); + + if (!selected) { + return html`
No file selected
`; + } + + console.log("Selected file:", selected); -let fasta_stats_realized = - fasta_stats == null ? "Click Above to Get Fasta Statistics" : fasta_stats; + // Invoke Rust command + const stats = invoke("get_stats", { filename: selected }); + + // Render stats + return html` +
+

Fasta Statistics

+

Filename: ${stats.filename}

+

Number of Sequences: ${stats.num_seqs}

+

Total Length: ${stats.total_length}

+

Minimum Length: ${stats.min_length}

+

Maximum Length: ${stats.max_length}

+

Average Length: ${stats.avg_length.toFixed(2)}

+

N50: ${stats.n50}

+

GC Content: ${(stats.gc_content * 100).toFixed(2)}%

+
+ `; + } catch (error) { + console.error("Error:", error); + return html`
Error: ${error.message}
`; + } +} diff --git a/src/fastx/fasta_simple.md b/src/fastx/fasta_simple.md index 2bdc1c0..30a2d8c 100644 --- a/src/fastx/fasta_simple.md +++ b/src/fastx/fasta_simple.md @@ -52,3 +52,34 @@ let fasta_stats_realized = ```js display(fasta_stats_realized) ``` + + +```js +import {getFastaStats} from "../components/fasta_processing.js"; +``` + +```js +const fasta_stats2 = view( +Inputs.button("Get Fasta Stats: Part 2 ", { + value: null, + reduce: () => getFastaStats() +})); +``` + +```js +import {timeline} from "../components/timeline.js"; +``` + +```js +let events = [ + {"name": "Sputnik 1", "year": 1957, "y": 10}, + {"name": "Apollo 11", "year": 1969, "y": 20}, + {"name": "Viking 1 and 2", "year": 1975, "y": 30}, + {"name": "Space Shuttle Columbia", "year": 1981, "y": 40}, + {"name": "Hubble Space Telescope", "year": 1990, "y": 50}, + {"name": "ISS Construction", "year": 1998, "y": 60} +]; + +display(timeline(events, {height: 300})); + +``` From 3d7bf652104fe0d6be4425000a5fc2e2303b7292 Mon Sep 17 00:00:00 2001 From: Zachary Charlop-Powers Date: Tue, 15 Oct 2024 16:51:58 -0400 Subject: [PATCH 3/5] remove global tauri --- src-tauri/tauri.conf.json | 2 +- src/components/fasta_processing.js | 48 +++--------------- src/dna/restriction_enzyme_analysis.md | 3 +- src/dna/translation.md | 3 +- src/fastx/fasta_simple.md | 69 ++------------------------ src/fastx/fastq_to_fasta.md | 14 ++---- src/fastx/fastx_stats.md | 5 +- src/rna/rna_rnapkin_viz.md | 14 +++--- 8 files changed, 32 insertions(+), 126 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e7f7058..c03fb73 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -12,7 +12,7 @@ "security": { "csp": null }, - "withGlobalTauri": true, + "withGlobalTauri": false, "windows": [ { "fullscreen": false, diff --git a/src/components/fasta_processing.js b/src/components/fasta_processing.js index fd8f788..4f16613 100644 --- a/src/components/fasta_processing.js +++ b/src/components/fasta_processing.js @@ -28,44 +28,12 @@ function choosefastq() { return selected; } -export function getFastaStats() { - try { - // File selection - const selected = open({ - multiple: false, - filters: [ - { - name: "Fasta", - extensions: ["fa", "fasta", "fna"], - }, - ], - }); - - if (!selected) { - return html`
No file selected
`; - } - - console.log("Selected file:", selected); - - // Invoke Rust command - const stats = invoke("get_stats", { filename: selected }); - - // Render stats - return html` -
-

Fasta Statistics

-

Filename: ${stats.filename}

-

Number of Sequences: ${stats.num_seqs}

-

Total Length: ${stats.total_length}

-

Minimum Length: ${stats.min_length}

-

Maximum Length: ${stats.max_length}

-

Average Length: ${stats.avg_length.toFixed(2)}

-

N50: ${stats.n50}

-

GC Content: ${(stats.gc_content * 100).toFixed(2)}%

-
- `; - } catch (error) { - console.error("Error:", error); - return html`
Error: ${error.message}
`; - } +export async function getFastaStats() { + const fasta = await choosefasta(); + const stats = await invoke("get_stats", { filename: fasta }); + return html`
+

Fasta Statistics

+

Record Count: ${stats.recordcount}

+

Maximum Length: ${stats.maxlength}

+
`; } diff --git a/src/dna/restriction_enzyme_analysis.md b/src/dna/restriction_enzyme_analysis.md index e7ab367..483167c 100644 --- a/src/dna/restriction_enzyme_analysis.md +++ b/src/dna/restriction_enzyme_analysis.md @@ -6,6 +6,8 @@ ```js +import { invoke } from "npm:@tauri-apps/api/core"; + let invoke = window.__TAURI__.core.invoke; let text = view(Inputs.textarea({label: "DNA For Searching", placeholder: "DNA Goes here", submit: true})); // let re_sites = (text == "") ? []: invoke("check_restriction_sites", {sequence: text}) @@ -23,4 +25,3 @@ if (text != "") { // display( re_sites) ``` - diff --git a/src/dna/translation.md b/src/dna/translation.md index 60985a4..2a87254 100644 --- a/src/dna/translation.md +++ b/src/dna/translation.md @@ -7,6 +7,7 @@ Simple DNA->Protiein Translation using the [protein_translate](https://docs.rs/p ```js +import { invoke } from "npm:@tauri-apps/api/core"; let invoke = window.__TAURI__.core.invoke; let dna_text = view(Inputs.textarea({label: "DNA For Translation", placeholder: "DNA Here", submit: true})); let dna_text_realized; @@ -28,4 +29,4 @@ display(dna_text) >NC_000913.3:1728347-1728994 rnt [organism=Escherichia coli str. K-12 substr. MG1655] [GeneID=946159] [chromosome=] ATGTCCGATAACGCTCAACTTACCGGTCTGTGCGACCGTTTTCGTGGTTTTTATCCTGTTGTGATCGATGTTGAAACAGCCGGATTTAACGCCAAAACCGATGCGCTGCTTGAGATTGCCGCCATCACCCTGAAAATGGATGAACAAGGCTGGCTGATGCCGGACACCACATTACATTTCCACGTCGAACCATTTGTCGGCGCAAATTTGCAACCAGAAGCCCTCGCCTTCAACGGCATTGACCCGAACGATCCCGATCGCGGCGCGGTCAGCGAATACGAGGCGCTGCACGAAATTTTTAAAGTTGTACGTAAAGGTATTAAAGCGAGCGGCTGTAACCGCGCCATTATGGTGGCGCACAATGCCAATTTTGATCACAGCTTTATGATGGCCGCCGCAGAACGCGCCTCACTGAAACGTAACCCGTTCCACCCTTTCGCCACTTTTGACACTGCTGCACTGGCCGGGCTGGCACTCGGACAAACCGTATTGTCAAAGGCTTGCCAGACCGCTGGCATGGACTTCGACAGCACCCAGGCGCACTCCGCGCTGTACGACACCGAACGCACTGCTGTGCTGTTTTGTGAAATCGTCAACCGCTGGAAACGTCTGGGAGGCTGGCCGCTATCTGCCGCCGAAGAGGTGTAA -``` \ No newline at end of file +``` diff --git a/src/fastx/fasta_simple.md b/src/fastx/fasta_simple.md index 30a2d8c..7de9cde 100644 --- a/src/fastx/fasta_simple.md +++ b/src/fastx/fasta_simple.md @@ -4,82 +4,21 @@ title: "Simple Fasta" Simplest example. uses Noodles to loop throught a fasta file and return the record count and maximul length in the file -```js -let open = window.__TAURI__.dialog.open; -let invoke = window.__TAURI__.core.invoke; - -// use the tauri open to get absolute file paths -async function choosefasta(){ - const selected = open({ - multiple: false, - filters: [{ - name: 'Fasta', - extensions: ['fa', 'fasta', 'fna']}] - }); - return selected -}; - -async function choosefastq(){ - const selected = open({ - multiple: false, - filters: [{ - name: 'Fastq', - extensions: ['fq', 'fastq']}] - }); - return selected -}; - -``` - -```js - -const fasta_stats = view( - Inputs.button("Get Fasta Stats", { - value: null, - reduce: () => choosefasta().then((fname) => { - console.log('Selected file:', fname); - return invoke("get_stats", { filename: fname }); - }) - }), -); - -let fasta_stats_realized = - fasta_stats == null ? "Click Above to Get Fasta Statistics" : fasta_stats; - -``` - - -```js -display(fasta_stats_realized) -``` - ```js import {getFastaStats} from "../components/fasta_processing.js"; -``` -```js -const fasta_stats2 = view( +const fasta_stats = view( Inputs.button("Get Fasta Stats: Part 2 ", { value: null, reduce: () => getFastaStats() })); -``` -```js -import {timeline} from "../components/timeline.js"; ``` ```js -let events = [ - {"name": "Sputnik 1", "year": 1957, "y": 10}, - {"name": "Apollo 11", "year": 1969, "y": 20}, - {"name": "Viking 1 and 2", "year": 1975, "y": 30}, - {"name": "Space Shuttle Columbia", "year": 1981, "y": 40}, - {"name": "Hubble Space Telescope", "year": 1990, "y": 50}, - {"name": "ISS Construction", "year": 1998, "y": 60} -]; - -display(timeline(events, {height: 300})); +if (fasta_stats != null) { + display(fasta_stats) +} ``` diff --git a/src/fastx/fastq_to_fasta.md b/src/fastx/fastq_to_fasta.md index e6ebdfe..ac06bd6 100644 --- a/src/fastx/fastq_to_fasta.md +++ b/src/fastx/fastq_to_fasta.md @@ -6,12 +6,8 @@ This function will take a fasq file and convert it to a fasta file. ```js -let open = window.__TAURI__.dialog.open; -let invoke = window.__TAURI__.core.invoke; -``` - - -```js +import { open } from "@tauri-apps/plugin-dialog"; +import { invoke } from "npm:@tauri-apps/api/core"; async function choosefastq(){ const selected = open({ @@ -24,9 +20,9 @@ async function choosefastq(){ }; const convert_stats = view(Inputs.button( - "Convert FastQ to Fasta", - { - value: null, + "Convert FastQ to Fasta", + { + value: null, reduce: () => choosefastq() .then( function (fqname) { // console.log(fqname); diff --git a/src/fastx/fastx_stats.md b/src/fastx/fastx_stats.md index 860f244..5dbfbbb 100644 --- a/src/fastx/fastx_stats.md +++ b/src/fastx/fastx_stats.md @@ -4,8 +4,9 @@ title: "Fastx stats" ```js -let open = window.__TAURI__.dialog.open; -let invoke = window.__TAURI__.core.invoke; +import { open } from "@tauri-apps/plugin-dialog"; +import { invoke } from "npm:@tauri-apps/api/core"; + // use the tauri open to get absolute file paths async function choosefasta(){ diff --git a/src/rna/rna_rnapkin_viz.md b/src/rna/rna_rnapkin_viz.md index f32a269..83636ab 100644 --- a/src/rna/rna_rnapkin_viz.md +++ b/src/rna/rna_rnapkin_viz.md @@ -2,7 +2,8 @@ ```js import {svg, html} from "npm:htl"; -let invoke = window.__TAURI__.core.invoke; +import { invoke } from "npm:@tauri-apps/api/core"; + function unsafe_html() { const span = document.createElement("span"); @@ -60,13 +61,12 @@ if (rnapkin_params.rna != "") { // retunrs text. I need a propr DOM element rna_text_realized = await invoke("rnapkin_fn", { sequence: rnapkin_params.rna, - height: rnapkin_params.height, + height: rnapkin_params.height, color_theme: rnapkin_params.color_theme, - mirror_x: rnapkin_params.mirror_x, - mirror_y: rnapkin_params.mirror_y, - rotation_angle:rnapkin_params.angle, - bubble_radius: rnapkin_params.bubble_radius}); + mirror_x: rnapkin_params.mirror_x, + mirror_y: rnapkin_params.mirror_y, + rotation_angle:rnapkin_params.angle, + bubble_radius: rnapkin_params.bubble_radius}); console.log(rna_text_realized); display(unsafe_html`${rna_text_realized}`); } - From a5361bac7ce5691db605090e2635e989de7da47c Mon Sep 17 00:00:00 2001 From: Zachary Charlop-Powers Date: Tue, 15 Oct 2024 16:54:07 -0400 Subject: [PATCH 4/5] update observable --- observablehq.config.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/observablehq.config.ts b/observablehq.config.ts index b510531..997cb4e 100644 --- a/observablehq.config.ts +++ b/observablehq.config.ts @@ -14,7 +14,6 @@ export default { { name: "Simple", path: "fastx/fasta_simple" }, { name: "FQ->Fasta", path: "fastx/fastq_to_fasta" }, { name: "Fastx Stats", path: "fastx/fastx_stats" }, - { name: "Test", path: "fastx/test" }, ], }, { @@ -55,5 +54,4 @@ export default { toc: true, // whether to show the table of contents // pager: true, // whether to show previous & next links in the footer // output: "dist", // path to the output root for build - //dynamicPaths: ["./icon.png", "./src/components/timeline.js"], }; From 2f25c21a96e2cde71427a586167c53b1e3f750c9 Mon Sep 17 00:00:00 2001 From: Zachary Charlop-Powers Date: Tue, 15 Oct 2024 16:56:31 -0400 Subject: [PATCH 5/5] update MD --- src/dna/restriction_enzyme_analysis.md | 2 -- src/dna/translation.md | 1 - 2 files changed, 3 deletions(-) diff --git a/src/dna/restriction_enzyme_analysis.md b/src/dna/restriction_enzyme_analysis.md index 483167c..8cb5a98 100644 --- a/src/dna/restriction_enzyme_analysis.md +++ b/src/dna/restriction_enzyme_analysis.md @@ -7,8 +7,6 @@ ```js import { invoke } from "npm:@tauri-apps/api/core"; - -let invoke = window.__TAURI__.core.invoke; let text = view(Inputs.textarea({label: "DNA For Searching", placeholder: "DNA Goes here", submit: true})); // let re_sites = (text == "") ? []: invoke("check_restriction_sites", {sequence: text}) text diff --git a/src/dna/translation.md b/src/dna/translation.md index 2a87254..1863190 100644 --- a/src/dna/translation.md +++ b/src/dna/translation.md @@ -8,7 +8,6 @@ Simple DNA->Protiein Translation using the [protein_translate](https://docs.rs/p ```js import { invoke } from "npm:@tauri-apps/api/core"; -let invoke = window.__TAURI__.core.invoke; let dna_text = view(Inputs.textarea({label: "DNA For Translation", placeholder: "DNA Here", submit: true})); let dna_text_realized;