@basic-genomics/hivdb-report
v0.0.5
Published
React component library for displaying HIV drug resistance analysis results
Maintainers
Readme
@basic-genomics/hivdb-report
React component library for displaying HIV drug resistance analysis results from the Stanford HIVDB.
Table of Contents
- Features
- Installation
- Quick Start
- Usage Modes
- Props
- Advanced Examples
- Configuration
- Data Structure
- API Integration
- Styling
- Browser Support
- TypeScript Support
- Development
- Troubleshooting
- Performance Considerations
- License
Features
- 📊 Complete Report Display - Sequence summary, drug resistance interpretation, mutation analysis
- 🎨 Customizable Theme - Configure primary colors to match your brand
- 📱 Responsive Design - Works on desktop and mobile devices
- 📤 Multiple Export Formats - HTML, CSV, JSON export support
- 🔄 Flexible Data Input - Direct data props or API-based sequence input
- 🔌 API Integration - Built-in support for custom API endpoints
- ⚡ Production Ready - Enterprise-grade code quality, used in production environments
Installation
npm install @basic-genomics/hivdb-report
# or
yarn add @basic-genomics/hivdb-report
# or
pnpm add @basic-genomics/hivdb-reportQuick Start
import { HIVDBReport } from '@basic-genomics/hivdb-report';
function App() {
// Data from HIVDB GraphQL API
const reportData = {
currentVersion: { text: 'HIVDB_9.8', publishDate: '2025-01-05' },
currentProgramVersion: { text: '3.5.3', publishDate: '2025-01-05' },
sequenceAnalysis: [
{
inputSequence: { header: 'Sample1' },
strain: { name: 'HIV1', display: 'HIV-1' },
bestMatchingSubtype: { display: 'B (2.26%)' },
// ... analysis results
}
]
};
return <HIVDBReport reportData={reportData} />;
}Usage Modes
The component supports two mutually exclusive modes:
Mode 1: Direct Data Mode (Default)
Provide analysis data directly via props. Best for pre-fetched data or GraphQL integration.
<HIVDBReport reportData={analysisData} />Mode 2: Sequence Input Mode
Enable user sequence input with API integration. Best for interactive applications.
<HIVDBReport
enableSequenceInput={true}
reportApiConfig={{
url: 'https://your-api.com/analyze',
authToken: 'your-token',
buildRequestBody: (sequences) => ({ sequences }),
transformResponse: (data) => data
}}
exportApiConfig={{
url: 'https://your-api.com/analyze-full',
// ... similar config
}}
/>Props
HIVDBReport
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| Data Props (Mode 1) |
| reportData | object | Conditional* | Analysis data for HTML report display |
| exportData | object | No | Analysis data for CSV/JSON export (includes additional fields) |
| analysisData | object | Conditional* | Legacy: single data source for both report and export |
| Sequence Input Props (Mode 2) |
| enableSequenceInput | boolean | No | Enable sequence input mode (default: false) |
| sequenceInputPlaceholder | string | No | Placeholder text for sequence input |
| reportApiConfig | object | Conditional** | API config for HTML report requests |
| exportApiConfig | object | Conditional** | API config for CSV/JSON export requests |
| General Props |
| config | object | No | Configuration overrides (see Configuration section) |
*In Mode 1: Either
reportDataoranalysisDatais required.
**In Mode 2:reportApiConfigis required for HTML reports,exportApiConfigis required for CSV/JSON exports.
API Configuration Object
When using enableSequenceInput={true}, configure API endpoints:
interface ApiConfig {
url: string; // Required: API endpoint URL
authToken?: string; // Optional: Bearer token for authentication
headers?: Record<string, string>; // Optional: Additional HTTP headers
buildRequestBody?: (sequences: string) => any; // Optional: Custom request body builder
transformResponse?: (data: any) => any; // Optional: Transform API response
}Data Source Options (Mode 1)
Option 1: Separate data sources (Recommended)
Use separate queries optimized for display vs export:
<HIVDBReport
reportData={reportQueryResult} // Lighter query for display
exportData={exportQueryResult} // Full query for export
/>Option 2: Single data source (Legacy)
Use one complete data object for both:
<HIVDBReport analysisData={fullQueryResult} />Advanced Examples
Complete Sequence Input Mode Example
import { HIVDBReport } from '@basic-genomics/hivdb-report';
function SequenceAnalyzer() {
return (
<HIVDBReport
enableSequenceInput={true}
sequenceInputPlaceholder="Enter or paste sequence(s) in FASTA format..."
// API config for HTML report
reportApiConfig={{
url: 'https://api.example.com/hivdb/analyze',
authToken: process.env.REACT_APP_API_TOKEN,
headers: {
'X-Custom-Header': 'value'
},
buildRequestBody: (sequences) => ({
sequences: sequences,
includeGenes: ['PR', 'RT', 'IN']
}),
transformResponse: (response) => response.data
}}
// API config for CSV/JSON export (with full data)
exportApiConfig={{
url: 'https://api.example.com/hivdb/analyze-full',
authToken: process.env.REACT_APP_API_TOKEN,
buildRequestBody: (sequences) => ({
sequences: sequences,
includeGenes: ['PR', 'RT', 'IN'],
includeAllGenes: true // Request additional fields for export
}),
transformResponse: (response) => response.data
}}
// Theme customization
config={{
themeColors: {
main: '#1565c0',
mainLighter: '#1e88e5'
}
}}
/>
);
}GraphQL Integration Example
import { useQuery } from '@apollo/client';
import { HIVDBReport } from '@basic-genomics/hivdb-report';
import { ANALYZE_SEQUENCES } from './queries';
function GraphQLReport({ sequences }) {
const { data, loading, error } = useQuery(ANALYZE_SEQUENCES, {
variables: { sequences }
});
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<HIVDBReport
reportData={data.viewer.sequenceAnalysis}
exportData={data.viewer.sequenceAnalysisWithGenes}
/>
);
}Configuration
Theme Colors
Customize the primary theme color to match your brand:
<HIVDBReport
reportData={data}
config={{
themeColors: {
main: '#1565c0', // Primary color (default: #8c1515 red)
mainLighter: '#1e88e5' // Hover/lighter variant (default: #d32424)
}
}}
/>Preset Theme Examples:
| Theme | main | mainLighter |
|-------|------|-------------|
| Red (default) | #8c1515 | #d32424 |
| Blue | #1565c0 | #1e88e5 |
| Green | #2e7d32 | #43a047 |
| Purple | #6a1b9a | #8e24aa |
| Teal | #00796b | #00897b |
| Orange | #e65100 | #f57c00 |
Full Configuration Example
import { HIVDBReport, defaultConfig } from '@basic-genomics/hivdb-report';
<HIVDBReport
reportData={data}
config={{
// Theme customization
themeColors: {
main: '#1565c0',
mainLighter: '#1e88e5'
},
// Gene display settings
allGenes: ['PR', 'RT', 'IN'],
highlightGenes: ['PR', 'RT', 'IN'],
// Display options
displayMutationScores: ['PR', 'RT', 'IN'],
displaySDRMs: ['PR', 'RT', 'IN'],
// Form settings
formEnableTabs: ['patterns', 'sequences', 'reads'],
// ... see defaultConfig for all options
}}
/>Data Structure
reportData / analysisData
The data should match the HIVDB GraphQL API response structure:
interface AnalysisData {
currentVersion?: {
text: string;
publishDate: string;
};
currentProgramVersion?: {
text: string;
publishDate: string;
};
sequenceAnalysis: Array<{
inputSequence: {
header: string;
};
strain: {
name: string;
display: string;
};
availableGenes: Array<{ name: string }>;
bestMatchingSubtype: {
display: string;
referenceAccession: string;
};
subtypes: Array<{
displayWithoutDistance: string;
distancePcnt: string;
referenceAccession: string;
referenceCountry: string;
referenceYear: number;
}>;
validationResults: Array<{
level: string;
message: string;
}>;
alignedGeneSequences: Array<{
gene: { name: string };
firstAA: number;
lastAA: number;
mutations: Array<{
text: string;
position: number;
primaryType: string;
}>;
}>;
drugResistance: Array<{
gene: { name: string };
drugScores: Array<{
drug: { name: string; displayAbbr: string };
score: number;
level: number;
text: string;
partialScores: Array<{
mutations: Array<{ text: string }>;
score: number;
}>;
}>;
}>;
}>;
mutationPrevalenceSubtypes?: Array<{
name: string;
stats: object;
}>;
}Exports
import {
HIVDBReport, // Main report component
defaultConfig // Default configuration object
} from '@basic-genomics/hivdb-report';API Integration
Request/Response Flow
When using enableSequenceInput={true}:
- User enters sequence(s) in FASTA format
- User selects output format (HTML Report / CSV/JSON)
- Component validates input and calls appropriate API
- API response is validated and transformed
- Results are displayed or downloaded
Error Handling
The component provides built-in error handling:
- Input validation: Empty sequences are rejected
- API errors: Network failures and HTTP errors are caught
- Data validation: API responses are validated for required fields
- User feedback: Clear error messages are displayed
Security Best Practices
When implementing API integration:
// ✅ Good: Use environment variables for sensitive data
reportApiConfig={{
url: process.env.REACT_APP_API_URL,
authToken: process.env.REACT_APP_API_TOKEN
}}
// ❌ Bad: Never hardcode tokens
reportApiConfig={{
url: 'https://api.example.com',
authToken: 'hardcoded-token-123' // Don't do this!
}}Styling
The component includes all necessary styles automatically. No additional style imports are needed.
Note: If you encounter style issues, ensure your build system supports SCSS. The component uses SCSS for styling internally.
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
TypeScript Support
While the component is written in JavaScript, TypeScript definitions are provided for better IDE support:
import { HIVDBReport } from '@basic-genomics/hivdb-report';
interface AnalysisData {
currentVersion?: {
text: string;
publishDate: string;
};
sequenceAnalysis: Array<{
inputSequence: { header: string };
// ... other fields
}>;
}
const MyComponent: React.FC = () => {
const data: AnalysisData = /* ... */;
return <HIVDBReport reportData={data} />;
};Development
# Install dependencies
yarn install
# Start development server (runs on port 3009)
yarn start
# Build for production
yarn build
# Run tests
yarn testTroubleshooting
Common Issues
Q: Styles are not loading correctly
A: Ensure your build system supports SCSS. If using Create React App, this is supported by default. For custom webpack configs, install sass-loader and node-sass.
Q: API requests are failing with CORS errors
A: Configure CORS on your API server to allow requests from your application's origin. Add appropriate CORS headers:
Access-Control-Allow-Origin: https://your-app.com
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, AuthorizationQ: Component shows "No valid sequence analysis data returned from API"
A: Ensure your API response includes a sequenceAnalysis array with at least one element. Check the transformResponse function if you're using custom response transformation.
Q: Export (CSV/JSON) option is disabled
A: In Direct Data Mode, provide exportData or ensure analysisData.allGenes exists. In Sequence Input Mode, configure exportApiConfig.
Performance Considerations
- Data optimization: Use separate
reportDataandexportDatato minimize initial load - API caching: Implement caching on your API server to improve response times
- Lazy loading: Consider code-splitting if the component is not needed on initial page load
- Large datasets: For sequences with many mutations, rendering may take a few seconds
License
MIT © Basic Genomics
Related
- Stanford HIVDB - HIV Drug Resistance Database
- HIVDB GraphQL API - Data source API
- React - JavaScript library for building user interfaces
Made with ❤️ by Basic Genomics
