Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
theosanderson committed Feb 15, 2023
1 parent 386995d commit ca6867a
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 24 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@testing-library/user-event": "^13.5.0",
"autoprefixer": "^10.4.13",
"bio-parsers": "^9.3.0",
"color-hash": "^2.0.2",
"postcss": "^8.4.21",
"qs": "^6.11.0",
"rc-slider": "^10.1.1",
Expand Down
89 changes: 65 additions & 24 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import { useVirtualizer, useWindowVirtualizer} from '@tanstack/react-virtual';
import Slider, {Range} from "rc-slider";
import {AiOutlineZoomIn,AiOutlineZoomOut} from 'react-icons/ai';
import {GiDna1} from 'react-icons/gi';

import ColorHash from 'color-hash';
import { useNavigate, useLocation } from "react-router-dom"

import qs from "qs"
var colorHash = new ColorHash({lightness: [0.75, 0.9, 0.7,0.8]});

const useQueryState = query => {
const location = useLocation()
Expand Down Expand Up @@ -78,12 +79,14 @@ const Tooltip = ({ hoveredInfo }) => {
{hoveredInfo && <span>{hoveredInfo.label}</span>}
{hoveredInfo && hoveredInfo.product && (
<div className="text-xs">{hoveredInfo.product}</div>

)}

</div>
);
};

const getColor = (feature) => {
const getColor = (feature, product) => {
switch (feature.type) {
case "CDS":
switch (feature.name){
Expand Down Expand Up @@ -131,7 +134,7 @@ const getColor = (feature) => {
return "#ff7f50";

default:
return "#c39797";
return colorHash.hex(feature.name+ product+feature.type);
}
case "gene":
return "blue";
Expand All @@ -142,7 +145,7 @@ const getColor = (feature) => {
case "3'UTR":
return "orange";
default:
return "black";
return colorHash.hex(feature.name+ product+feature.type);
}
};

Expand Down Expand Up @@ -312,7 +315,7 @@ whereMouseCurrentlyIs,setWhereMouseCurrentlyIs}) => {
const seqLength = locations.reduce((acc, location) => acc + location.end - location.start + 1, 0);

const codonMap = [];
if (feature.type=="CDS" ){
if (feature.type=="CDS" | feature.type=="mat_peptide"){

for (let j = rowStart; j < rowEnd; j++) {
let positionSoFar = 0;
Expand Down Expand Up @@ -431,18 +434,25 @@ const codonZoomThreshold = -2
const extraFeat=5*zoomFactor;
const codonPad =15*zoomFactor;

const product = feature.notes ? feature.notes.product : "";
let betterName = product ? product : feature.name;
const altName = betterName == feature.name ? "" : feature.name;
if (betterName=="Untitled Feature") betterName=feature.type;




return (
<g key={i}>
<rect x={x-extraFeat} y={y} width={width+extraFeat*2} height={10} fill={
getColor(feature)
getColor(feature, product)
}
onMouseEnter={
() => {
if (zoomLevel< codonZoomThreshold) setHoveredInfo({
label: `${feature.name}: ${feature.type}`,
product: feature.notes && feature.notes.product ? feature.notes.product : null,
product: altName,
locusTag: feature.notes && feature.notes.locus_tag ? feature.notes.locus_tag : null,
})}
}
onMouseLeave={() => {
Expand All @@ -452,7 +462,7 @@ const codonZoomThreshold = -2
/>
<text x={x-10} y={y} textAnchor="left" fontSize="10"
>
{feature.name == "Untitled Feature" ? feature.type : feature.name}
{betterName}
</text>
{
feature.codonMap.map((codon, j) => {
Expand All @@ -461,8 +471,9 @@ const codonZoomThreshold = -2
zoomLevel> codonZoomThreshold && <text key={j} x={codon.start*sep} y={y+9} textAnchor="middle" fontSize="10"
onMouseOver={
() => setHoveredInfo({
label: `${codon.gene}: ${codon.aminoAcid}${codon.codonIndex+1}`,
product: feature.notes && feature.notes.product ? feature.notes.product : null,
label: `${betterName}: ${codon.aminoAcid}${codon.codonIndex+1}`,
product: altName,
locusTag: feature.notes && feature.notes.locus_tag ? feature.notes.locus_tag : null,

})
}
Expand Down Expand Up @@ -868,6 +879,7 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {

const virtualItems = rowVirtualizer.getVirtualItems();
const [centeredNucleotide, setCenteredNucleotide] = useState(null);


const setZoomLevel = (x) => {
const middleRow = virtualItems[Math.floor(virtualItems.length / 2)].index
Expand Down Expand Up @@ -1051,13 +1063,27 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {


const App = () => {
const addlExamples = [
["Monkeypox clade II","NC_063383.1"],
["HIV-1","NC_001802.1"],


]

// option to either load from URL or upload a file
const [genbankString, setGenbankString] = useState(null);
const [loading, setLoading] = useState(false);
const loadFromUrl = async (url) => {
setGenbankString(null);
setLoading(true);
const response = await fetch(url);
// check for errors
if (!response.ok) {
setLoading(false);
window.alert("Error loading file: for large Genbank files, try using the 'Load from file' option instead.");
return;
}

const text = await response.text();
setGenbankString(text);
setLoading(false);
Expand Down Expand Up @@ -1089,7 +1115,17 @@ const App = () => {
const [beingDraggedOver, setBeingDraggedOver] = useState(false);
const [genbankId, setGenbankId] = useState(null);

const loadFromGenbankId = async (id) => {

const strippedOfWhitespace = id.replace(/\s/g, '')
// if no length, do nothing
if (strippedOfWhitespace.length<= 3) {
return
}

const url = `https://genbank-api.vercel.app/api/genbank/${strippedOfWhitespace}`
setGbUrl(url)
}


// create UI for loading from URL or file
Expand Down Expand Up @@ -1126,6 +1162,9 @@ onDrop={(e) => {
}}





>
<div className="fixed bottom-5 text-center w-full">
<a className="text-gray-300 hover:text-gray-500" href="https://github.com/theosanderson/gensplore">View code on GitHub</a>
Expand Down Expand Up @@ -1168,14 +1207,7 @@ onDrop={(e) => {
<button
className="bg-gray-100 ml-3 hover:bg-gray-200 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow"
onClick={() =>{
const strippedOfWhitespace = genbankId.replace(/\s/g, '')
// if no length, do nothing
if (strippedOfWhitespace.length<= 3) {
return
}

const url = `https://genbank-api.vercel.app/api/genbank/${strippedOfWhitespace}`
setGbUrl(url)
loadFromGenbankId(genbankId)
}
}
>
Expand All @@ -1193,32 +1225,41 @@ onDrop={(e) => {
<ul>
<li>
<button
className="text-blue-500 hover:text-blue-800 mb-3 mt-3"
className="text-blue-400 hover:text-blue-700 mb-3 mt-3"
onClick={() => setGbUrl("/sequence.gb")}
>
SARS-CoV-2 reference genome
</button>
</li>
<li>
<button
className="text-blue-500 hover:text-blue-800 mb-3"
className="text-blue-400 hover:text-blue-700 mb-3"
onClick={() => setGbUrl("/sequence2.gb")}
>
<i>P. falciparum</i> chromosome 14
</button>
</li>
{addlExamples.map((example) => (
<li>
<button
className="text-blue-400 hover:text-blue-700 mb-3"
onClick={() => loadFromGenbankId(example[1])}
>
{example[0]}
</button>
</li>
))}
</ul>
</div>
</div>
</div>

</div>
</div>

)}
</>);
};






export default App;
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3187,6 +3187,11 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"

color-hash@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/color-hash/-/color-hash-2.0.2.tgz#abf735705da71874ddec7dcef50cd7479e7d64e9"
integrity sha512-6exeENAqBTuIR1wIo36mR8xVVBv6l1hSLd7Qmvf6158Ld1L15/dbahR9VUOiX7GmGJBCnQyS0EY+I8x+wa7egg==

[email protected]:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
Expand Down

1 comment on commit ca6867a

@vercel
Copy link

@vercel vercel bot commented on ca6867a Feb 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.