Your First React Section
Display a seismic file selected in the browser, with cancellation, error handling and cleanup.
Compare seismic displays
Compare density and wiggles on the same synthetic section. Drag a box to zoom; double-click to reset.
<SectionView source={source} path="demo"
display={{ colormap: 'Seismic', wiggle: false, agc: false }}
rangeBars style={{ height: 340 }} />Goal: display a selected SEG-Y or SU file, then release it when the component leaves.
Connect the File to the View
sequenceDiagram
accTitle: Opening and displaying a local section
accDescr: The application opens a chosen file, passes the source and returned path to SectionView, then disposes its session when the component leaves.
participant App
participant Source as LocalDataSource
participant View as SectionView
App->>Source: open(file, signal)
Source-->>App: FileInfo with session path
App->>View: source and path
View->>Source: Metadata and visible tiles
Source-->>View: Typed data for rendering
App->>Source: dispose on cleanup
Copy the Component
Install core, React and readers. Pass a File from a file input or drop handler:
'use client'
import { useEffect, useState } from 'react'
import { SectionView } from '@bs/outkrop-react'
import { LocalDataSource } from '@bs/outkrop-readers/browser'
type Session = { source: LocalDataSource; path: string }
export function LocalSection({ file }: { file: File }) {
const [session, setSession] = useState<Session | null>(null)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
const source = new LocalDataSource()
const controller = new AbortController()
setSession(null)
setError(null)
void source
.open(file, { signal: controller.signal })
.then((info) => {
if (controller.signal.aborted) return
if (info.kind !== 'seismic') {
source.dispose()
setError('Choose a SEG-Y or SU file.')
return
}
setSession({ source, path: info.path })
})
.catch((reason: unknown) => {
if (!controller.signal.aborted) setError(String(reason))
})
return () => {
controller.abort()
source.dispose()
}
}, [file])
if (error) return <p role="alert">{error}</p>
if (!session) return <p role="status">Opening {file.name}…</p>
return (
<SectionView
source={session.source}
path={session.path}
style={{ height: 520 }}
display={{ colormap: 'Seismic', clipMode: 'percentile', clipPercent: 98 }}
onError={(reason) => setError(String(reason))}
/>
)
}
Give this component a new key for each selection. Its effect owns the source, aborts unfinished opening and disposes it on cleanup, including StrictMode effect replay.
Adjust the View
| Task | Prop |
|---|---|
| Switch to wiggles | display={{ wiggle: true }} |
| Change clipping | clipMode: 'auto', 'percentile' or 'manual' inside display |
| Pan with dragging | dragMode="pan" |
| Show per-axis navigation | rangeBars |
| Save a window | onWindowChange |
Windows use 1-based trace numbers and milliseconds from the first sample. For depth-domain data, build a core view using its metadata; do not relabel a time axis as depth.
Use view handles for reset, zoom and export. For hosted data, replace the source with HttpDataSource.