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 9bd7851 commit d5fe8b1
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 12 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"react-router-dom": "^6.8.1",
"react-scripts": "5.0.1",
"react-spinners": "^0.13.8",
"react-toastify": "^9.1.1",
"react-tooltip": "^5.7.5",
"react-use": "^17.4.0",
"tailwindcss": "^3.2.6",
Expand Down
103 changes: 91 additions & 12 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,32 @@ 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 { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

import qs from "qs"
import { U } from "ve-sequence-utils/lib/DNAComplementMap";
var colorHash = new ColorHash({lightness: [0.75, 0.9, 0.7,0.8]});


const filterFeatures = (features, search) => {
return features.filter((feature) => {
// if feature name contains search string
if(feature.name.toLowerCase().includes(search.toLowerCase())){
return true;
}
const product = feature.notes && feature.notes.product ? feature.notes.product[0] : "";
if(product.toLowerCase().includes(search.toLowerCase())){
return true;
}
const locus_tag = feature.notes && feature.notes.locus_tag ? feature.notes.locus_tag[0] : "";
if(locus_tag.toLowerCase().includes(search.toLowerCase())){
return true;
}
return false;
});
}

const useQueryState = query => {
const location = useLocation()
const navigate = useNavigate()
Expand Down Expand Up @@ -247,7 +269,7 @@ const getReverseComplement = (sequence) => {
return sequence.split("").map((base) => baseToComplement[base]).reverse().join("");
}

const SingleRow = ({ parsedSequence, rowStart, rowEnd, setHoveredInfo, rowId, searchInput , zoomLevel, whereMouseWentDown, setWhereMouseWentDown,
const SingleRow = ({ parsedSequence, rowStart, rowEnd, setHoveredInfo, rowId, intSearchInput,annotSearchInput , zoomLevel, whereMouseWentDown, setWhereMouseWentDown,
whereMouseWentUp, setWhereMouseWentUp,
whereMouseCurrentlyIs,setWhereMouseCurrentlyIs}) => {

Expand All @@ -257,7 +279,9 @@ whereMouseCurrentlyIs,setWhereMouseCurrentlyIs}) => {
const sep = 10 * zoomFactor;


const isSelected = searchInput>=rowStart && searchInput<=rowEnd;






Expand All @@ -276,6 +300,11 @@ whereMouseCurrentlyIs,setWhereMouseCurrentlyIs}) => {
(feature.start <= rowStart && feature.end >= rowEnd))
)
);

const searchFeatures = !annotSearchInput ? [] : filterFeatures(relevantFeatures,annotSearchInput)

const isSelected = (intSearchInput>=rowStart && intSearchInput<=rowEnd) || searchFeatures.length>0;

if (rowStart==0){
//console.log(relevantFeatures);
}
Expand Down Expand Up @@ -521,17 +550,17 @@ const codonZoomThreshold = -2

// create a tick specifically at searchInput
let searchTick = null;
if (searchInput != null && searchInput >= rowStart && searchInput <= rowEnd) {
if (intSearchInput != null && intSearchInput >= rowStart && intSearchInput <= rowEnd) {
searchTick = (
<g key={-1}>
<line x1={(searchInput-rowStart)*sep} y1={0} x2={(searchInput-rowStart)*sep} y2={10} stroke="red" />
<line x1={(intSearchInput-rowStart)*sep} y1={0} x2={(intSearchInput-rowStart)*sep} y2={10} stroke="red" />
{//rect behind tick
}
<rect x={(searchInput-rowStart)*sep-30} y={0} width={60} height={30} fill="#ffffee" />
<text x={(searchInput-rowStart)*sep} y={20} textAnchor="middle" fontSize="10"
<rect x={(intSearchInput-rowStart)*sep-30} y={0} width={60} height={30} fill="#ffffee" />
<text x={(intSearchInput-rowStart)*sep} y={20} textAnchor="middle" fontSize="10"
fill="red"
>
{searchInput+1}
{intSearchInput+1}
</text>
</g>
);
Expand Down Expand Up @@ -634,23 +663,49 @@ const codonZoomThreshold = -2
);
};

function SearchPanel({ searchPanelOpen,setSearchPanelOpen,searchInput,setSearchInput }) {
function SearchPanel({ searchPanelOpen,setSearchPanelOpen,searchInput,setSearchInput,searchType, setSearchType }) {


const handleInputChange = (event) => {
setSearchInput(event.target.value);
// if event.target.value has non-numeric characters, then set searchType to annot
if (event.target.value.match(/[^0-9]/)) {
setSearchType("annot");
console.log("setting searchType to annot");
}

};

const searchOption = [
{ value: "nuc", label: "nucleotide" },
{ value: "annot", label: "annotation" },
];

return (
<div className="bg-white p-1 text-sm shadow rounded flex items-center">
{searchPanelOpen ? ((<>
<select

value={searchType}
onChange={(option) => setSearchType(option.value)}
className="bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold py-2 px-2 rounded inline-flex items-center"
>
{searchOption.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>



<DebounceInput
minLength={2}
debounceTimeout={300}
type="text"
value={searchInput}
onChange={handleInputChange}
className="mx-2 bg-white focus:outline-none focus:shadow-outline border border-gray-300 rounded-lg py-2 px-4 block w-full appearance-none leading-normal"
placeholder="nuc index"
id="search-input"
// don't autocomplete
Expand Down Expand Up @@ -710,7 +765,8 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {
const [zoomLevel, setRawZoomLevel] = useState(0);
const [whereMouseWentDown, setWhereMouseWentDown] = useState(null);
const [whereMouseWentUp, setWhereMouseWentUp] = useState(null);
const [whereMouseCurrentlyIs, setWhereMouseCurrentlyIs] = useState(null);
const [whereMouseCurrentlyIs, setWhereMouseCurrentlyIs] = useState(null);
const [searchType, setSearchType] = useState("nuc");

const [ref, { width }] = useMeasure();

Expand All @@ -719,7 +775,8 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {


// safely convert searchInput to int
const intSearchInput = parseInt(searchInput);
const intSearchInput = searchType === "nuc" ? parseInt(searchInput) : null;
const annotSearchInput = searchType === "annot" ? searchInput : null;

const [whereOnPage, setWhereOnPage] = useState(0);

Expand Down Expand Up @@ -907,7 +964,7 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {

const [lastSearch, setLastSearch] = useState(null);



useEffect(() => {
if(!intSearchInput) return;
Expand All @@ -929,6 +986,24 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {


}, [intSearchInput, rowWidth]);
useEffect(() => {
if(!annotSearchInput) return;
const strippedAnnotInput = annotSearchInput.replace(/\s/g, "");
if (strippedAnnotInput === "") return;
// search the features for one that matches
const matchingFeatures = filterFeatures(genbankData.parsedSequence.features, strippedAnnotInput);
if(matchingFeatures.length === 0){
toast.error("No matching features found");
return;
}
const firstMatchingFeature = matchingFeatures[0];
const row = Math.floor(firstMatchingFeature.start / rowWidth);
rowVirtualizer.scrollToIndex(row+1, {align:"center"});
setLastSearch(annotSearchInput);
}, [annotSearchInput]);





//console.log("virtualItems", virtualItems);
Expand All @@ -953,13 +1028,16 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {

return (
<div className="w-full p-5">
<ToastContainer />
{true && (
<div className="fixed top-0 right-0 z-10">
<SearchPanel
searchInput = {searchInput}
setSearchInput = {setSearchInput}
searchPanelOpen={searchPanelOpen}
setSearchPanelOpen={setSearchPanelOpen}
searchType={searchType}
setSearchType={setSearchType}

/>
</div>
Expand Down Expand Up @@ -1036,7 +1114,8 @@ function GensploreView({genbankString, searchInput, setSearchInput}) {
rowWidth={rowWidth}
setHoveredInfo={setHoveredInfo}
rowId={virtualitem.index}
searchInput={intSearchInput-1}
intSearchInput={intSearchInput-1}
annotSearchInput={annotSearchInput}

renderProperly={true}
zoomLevel={zoomLevel}
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3154,6 +3154,11 @@ cliui@^7.0.2:
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"

clsx@^1.1.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==

co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
Expand Down Expand Up @@ -7800,6 +7805,13 @@ react-spinners@^0.13.8:
resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.13.8.tgz#5262571be0f745d86bbd49a1e6b49f9f9cb19acc"
integrity sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==

react-toastify@^9.1.1:
version "9.1.1"
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.1.tgz#9280caea4a13dc1739c350d90660a630807bf10b"
integrity sha512-pkFCla1z3ve045qvjEmn2xOJOy4ZciwRXm1oMPULVkELi5aJdHCN/FHnuqXq8IwGDLB7PPk2/J6uP9D8ejuiRw==
dependencies:
clsx "^1.1.1"

react-tooltip@^5.7.5:
version "5.7.5"
resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.7.5.tgz#f3487e000a24b6ff84c8181064809a57b43c2e99"
Expand Down

1 comment on commit d5fe8b1

@vercel
Copy link

@vercel vercel bot commented on d5fe8b1 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.