Skip to content

Commit

Permalink
use tanstack
Browse files Browse the repository at this point in the history
  • Loading branch information
theosanderson committed Feb 15, 2023
1 parent 79f8d05 commit 28c29e0
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 40 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@tanstack/react-virtual": "^3.0.0-beta.48",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
141 changes: 101 additions & 40 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useRef, useMemo, useLayoutEffect } from "react";

import './App.css';

import { genbankToJson } from "bio-parsers";
import { useMeasure } from 'react-use'; // or just 'react-use-measure'
import {FaSearch,FaTimes} from 'react-icons/fa';
import {DebounceInput} from 'react-debounce-input';

import { useVirtualizer, useWindowVirtualizer} from '@tanstack/react-virtual';
const Tooltip = ({ hoveredInfo }) => {
const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });

Expand Down Expand Up @@ -193,12 +193,8 @@ const codonToAminoAcid = (codon) => {
}
};

const SingleRow = ({ parsedSequence, rowStart, rowEnd, setHoveredInfo, rowId, searchInput, renderProperly }) => {
if (!renderProperly)
{
return <div style={{height:60, borderBottom: "1px solid #eee"}}
id={`row-${rowId}`}></div>
}
const SingleRow = ({ parsedSequence, rowStart, rowEnd, setHoveredInfo, rowId, searchInput }) => {


const isSelected = searchInput>=rowStart && searchInput<=rowEnd;
if(isSelected){
Expand All @@ -209,6 +205,7 @@ const SingleRow = ({ parsedSequence, rowStart, rowEnd, setHoveredInfo, rowId, se

const fullSequence = parsedSequence.sequence;
const rowSequence = fullSequence.slice(rowStart, rowEnd);

const relevantFeatures = parsedSequence.features.filter(
(feature) => (
feature.type !== "source" &&
Expand Down Expand Up @@ -393,7 +390,7 @@ const SingleRow = ({ parsedSequence, rowStart, rowEnd, setHoveredInfo, rowId, se
>
{codon.aminoAcid}
</text>
<text key={j} x={codon.start*10} y={y-1} textAnchor="middle" fontSize="7" fillOpacity={0.4}>
<text key={"bb"+j} x={codon.start*10} y={y-1} textAnchor="middle" fontSize="7" fillOpacity={0.4}>
{codon.codonIndex+1}
</text>

Expand Down Expand Up @@ -547,7 +544,7 @@ function App() {
};
}, []);
const [ref, { width }] = useMeasure();
//console.log("width", width);

const [hoveredInfo, setHoveredInfo] = useState(null);
const [genbankData, setGenbankData] = useState(null);
const [searchInput, setSearchInput] = useState(null);
Expand Down Expand Up @@ -614,41 +611,76 @@ function App() {
if (rowWidth < 40) {
rowWidth = 40;
}
//console.log("rowWidth", rowWidth);



let fullSequence, sequenceLength;
if(genbankData){
fullSequence = genbankData.parsedSequence.sequence;
sequenceLength = fullSequence.length;
}


const rowData = useMemo(() => {
if (!fullSequence) return [];
const rowData = [];



for (let i = 0; i < sequenceLength; i += rowWidth) {

rowData.push({
rowStart: i,
rowEnd: (i + rowWidth > sequenceLength ? sequenceLength : i + rowWidth)
});
}
return rowData;
}
, [fullSequence, rowWidth,sequenceLength]);


const parentRef = useRef(null);
const parentOffsetRef = useRef(0);

useLayoutEffect(() => {
parentOffsetRef.current = parentRef.current?.offsetTop ?? 0
}, [])




const rowVirtualizer = useWindowVirtualizer({
count: rowData.length,
estimateSize: () => 60,
scrollMargin: parentOffsetRef.current,
})



const virtualItems = rowVirtualizer.getVirtualItems();


// useEffect
useEffect(() => {
if(!intSearchInput) return;
const row = Math.floor(intSearchInput / rowWidth);
console.log("row", row);
rowVirtualizer.scrollToIndex(row, {align:"center",
smoothScroll:true});



setTimeout(() => {
const rowElement = document.getElementById(`row-${row}`);
if (!rowElement) return;
rowElement.scrollIntoView({ behavior: "smooth", block: "center" });
}, 100);
setTimeout(() => {
const rowElement = document.getElementById(`row-${row}`);
if (!rowElement) return;
rowElement.scrollIntoView({ behavior: "smooth", block: "center" });
}, 1000);
}, [intSearchInput]);


//console.log("virtualItems", virtualItems);

if (!genbankData ) {
return <div>Loading...</div>;
}

const rowData = [];
const fullSequence = genbankData.parsedSequence.sequence;
const sequenceLength = fullSequence.length;
for (let i = 0; i < sequenceLength; i += rowWidth) {
rowData.push({
rowStart: i,
rowEnd: (i + rowWidth > sequenceLength ? sequenceLength : i + rowWidth)
});
}




if(!width){
return (
Expand Down Expand Up @@ -676,10 +708,10 @@ function App() {



<div ref={ref} className="w-full">
<div className="w-full">
<Tooltip hoveredInfo={hoveredInfo} />
{genbankData && (
<div>
<div ref={ref} >
<h2 className="text-2xl"
>{genbankData.parsedSequence.name}</h2>
<div>
Expand All @@ -689,18 +721,47 @@ function App() {


</div>
<div className="mt-5">
{rowData.map((row, index) => (
<SingleRow key={index} parsedSequence={genbankData.parsedSequence} rowStart={row.rowStart} rowEnd={row.rowEnd}
<div ref={parentRef} className="mt-5 h-80">
<div
style={{
height: rowVirtualizer.getTotalSize(),
width: '100%',
position: 'relative',
}}
>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
transform: `translateY(${
virtualItems[0].start - rowVirtualizer.options.scrollMargin
}px)`,
}}
>

{virtualItems.map((virtualitem) => {
const row = rowData[virtualitem.index];
//return (<div>{genbankData.parsedSequence.sequence.slice(row.start,row.end)}</div>)
return (
<div ref={rowVirtualizer.measureElement}
data-index={virtualitem.index}
key={virtualitem.key}>
<SingleRow key={virtualitem.index} parsedSequence={genbankData.parsedSequence} rowStart={row.rowStart} rowEnd={row.rowEnd}
rowWidth={rowWidth}
setHoveredInfo={setHoveredInfo}
rowId={index}
rowId={virtualitem.index}
searchInput={intSearchInput-1}
renderProperly={(Math.abs(whereOnPage - (index / rowData.length)) < 0.2)
|| (row.rowStart>=intSearchInput && row.rowEnd<=intSearchInput)}
renderProperly={true}

/>
))}
</div>)
}
)
}
</div>
</div>
</div>


Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,18 @@
"@svgr/plugin-svgo" "^5.5.0"
loader-utils "^2.0.0"

"@tanstack/react-virtual@^3.0.0-beta.48":
version "3.0.0-beta.48"
resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.0.0-beta.48.tgz#c5055f78b84bf5cb37ee3ca612edf3b19ddf7e10"
integrity sha512-zNNEtCF5clBLhqvUZPfmGaOiWrqdgIc7IzrT/HiAKFkFTF4R30b/mfY4+wCJ9tW95Tvs1Ml4THUA3s/vIHMHQg==
dependencies:
"@tanstack/virtual-core" "3.0.0-beta.48"

"@tanstack/[email protected]":
version "3.0.0-beta.48"
resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.0.0-beta.48.tgz#bcc5737dc0b9bd3e3c61e75b319c1b5edf30c621"
integrity sha512-W57cC4J1rd3fvWfiio1EteZiokZL8/CvDK/wo+C7xkgYrFw4BXr2P3mvo0HFxCDb15KeqyuF2pTpGWN+D1OXIg==

"@testing-library/dom@^8.5.0":
version "8.20.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.0.tgz#914aa862cef0f5e89b98cc48e3445c4c921010f6"
Expand Down

1 comment on commit 28c29e0

@vercel
Copy link

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