137 lines
6.4 KiB
JavaScript
137 lines
6.4 KiB
JavaScript
import React from 'react';
|
|
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
|
|
|
|
const CircularRNAPipeline = ({
|
|
title = "Bioinformatics Pipeline",
|
|
leftSteps = [
|
|
"Raw Sequencing Data (fastq files)",
|
|
"Quality Control and Preprocessing of Data",
|
|
"High Quality Sequencing Data (fastq file)",
|
|
"Alignment to Reference Genome"
|
|
],
|
|
rightSteps = [
|
|
"Downstream Advanced Analysis",
|
|
"Circular RNA Identification",
|
|
"Circular RNA Prediction",
|
|
"Back Splicing Junction Reads"
|
|
],
|
|
backgroundColor = "bg-gray-50",
|
|
cardColor = "bg-gray-300",
|
|
textColor = "text-teal-600",
|
|
arrowColor = "text-gray-600",
|
|
className = "",
|
|
cardClassName = "",
|
|
titleClassName = ""
|
|
}) => {
|
|
// Combine steps for mobile layout
|
|
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
|
|
|
|
return (
|
|
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
|
|
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
|
|
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
|
|
{title}
|
|
</h2>
|
|
|
|
{/* Pipeline Flowchart */}
|
|
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
|
|
<div className="flex justify-center">
|
|
<div className="w-full max-w-5xl">
|
|
<div className="relative">
|
|
{/* Mobile Layout - Single Column */}
|
|
<div className="block sm:hidden">
|
|
<div className="flex flex-col items-center space-y-3">
|
|
{mobileSteps.map((step, index) => (
|
|
<React.Fragment key={index}>
|
|
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
|
|
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
|
|
</div>
|
|
{index < mobileSteps.length - 1 && (
|
|
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
|
|
)}
|
|
</React.Fragment>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Tablet and Desktop Layout - Two Columns */}
|
|
<div className="hidden sm:block">
|
|
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
|
|
{/* Left Column */}
|
|
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
|
|
{leftSteps.map((step, index) => (
|
|
<React.Fragment key={index}>
|
|
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
|
|
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
|
|
</div>
|
|
{index < leftSteps.length - 1 && (
|
|
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
|
|
)}
|
|
</React.Fragment>
|
|
))}
|
|
</div>
|
|
|
|
{/* Right Column */}
|
|
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
|
|
{rightSteps.map((step, index) => (
|
|
<React.Fragment key={index}>
|
|
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
|
|
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
|
|
</div>
|
|
{index < rightSteps.length - 1 && (
|
|
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
|
|
)}
|
|
</React.Fragment>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Custom arrows from "Alignment to Reference Genome" */}
|
|
<div className="absolute bottom-12 sm:bottom-16 lg:bottom-[2rem] left-1/2 transform -translate-x-1/2">
|
|
<div className="relative w-0 h-0">
|
|
|
|
{/* Arrow 1: Straight horizontal to "Back Splicing Junction Reads" (Unmapped Reads) */}
|
|
<div className="absolute top-0 left-0">
|
|
<div className="relative">
|
|
{/* Horizontal line */}
|
|
<div className="w-16 sm:w-20 lg:w-28 h-0.5 bg-gray-600"></div>
|
|
{/* Arrowhead */}
|
|
<div className="absolute right-0 -top-1 w-2 h-2 border-r-2 border-t-2 border-gray-600 rotate-45"></div>
|
|
{/* Label */}
|
|
<div className="absolute top-2 left-4 sm:left-6 lg:left-10 text-xs text-gray-700 font-medium whitespace-nowrap">
|
|
Unmapped Reads
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Arrow 2: Diagonal upward to "Circular RNA Prediction" (Mapped Reads) */}
|
|
<div className="absolute top-0 left-0">
|
|
<div className="relative">
|
|
{/* Diagonal line going up and right */}
|
|
<div className="absolute origin-left w-20 sm:w-24 lg:w-32 h-0.5 bg-gray-600 transform -rotate-45"></div>
|
|
{/* Arrowhead positioned at the end of diagonal line */}
|
|
<div className="absolute w-2 h-2 border-r-2 border-t-2 border-gray-600 transform rotate-0"
|
|
style={{
|
|
left: 'calc(20 * 0.25rem * 0.707 - 4px)', // cos(45deg) ≈ 0.707
|
|
top: 'calc(-20 * 0.25rem * 0.707 - 4px)' // -sin(45deg) ≈ -0.707
|
|
}}></div>
|
|
{/* Label */}
|
|
<div className="absolute -top-8 left-6 sm:left-8 lg:left-12 text-xs text-gray-700 font-medium whitespace-nowrap">
|
|
Mapped Reads
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default CircularRNAPipeline; |