Grid View
grid view(또는 datagrid)는 데이터의 표 형식 보기를 제공하는 그래픽 제어 요소입니다.
일반적으로 다음 중 일부 또는 전부를 지원합니다.
- 열 머리글을 클릭하여 그리드의 정렬 순서 변경
- 열 머리글을 끌어서 크기 및 순서 변경
- 보기 데이터의 제자리 편집
- 행과 열 구분 기호 및 행 배경색 번갈아 지정하기
- Cornerstone.js HTML5 canvas를 지원하는 웹 브라우저에서 가벼운 의료 이미지 표시에 사용되는 JavaScript 라이브러리
- OpenSeadragon 데스크톱 및 모바일에서 사용 가능한 고해상도 줌 가능한 이미지를 위한 순수 JavaScript 뷰어
- dicomParser DICOM 파일을 처리하여 의료 이미지 데이터를 JavaScript 객체로 변환하는 라이브러리
- AMI Medical Imaging (AMI) 웹에서 의료 영상을 효과적으로 표시하고 주석을 추가하는 데 사용되는 JavaScript 라이브러리
- OHIF Medical Imaging Viewer
- itk-wasm 의료 영상 처리를 위한 JavaScript 라이브러리
- Brainchop
예전에 관련 회사 기술 블로그 보다가 생각나서 찾아본 라이브러리 리스트. 대용량, 의학용 이미지 포멧을 다루기 위한 도구들.
Astro를 사용한 프로젝트에서 빌드를 하는데 JavaScript heap out of memory 에러가 발생했다.
쉽게 해결하자면 NODE_OPTIONS=--max_old_space_size(in megabytes) 설정해서 우회할수는 있겠지만 정리가 필요해서 메모를 남겨본다.
일단 원인은 파일사이즈가 크다는 점, 그리고 카테고리(국가)별 데이터가 많다는 점인데 개선할만한 부분은 두가지 정도인 듯.
- 가능한 전처리해서 데이터를 다시 생성해서 참조
Astro.glob을 사용해서 조건부로 데이터를 가져오기
예상치 못한 에러였는데 역시 트레이드오프는 존재하기 마련이다.
로컬에서만 실행 해야하는 프로젝트가 있길래 아무래도 사전설정 같은 귀찮은 문제가 있으니 pkg를 사용하면 좋을 것 같아서 들어가봤는데 개발이 중단 되었다.
노드 21버젼에서 해당 기능이 지원되는데 재미있는 시도들이 많이 나왔으면 좋겠다.
[data-scope='slider'][data-part='thumb']
[data-scope='slider'][data-part='track']
[data-scope='slider'][data-part='control']
Ark UI의 각 컴포넌트 파트는
data-scope및data-part속성으로 지정됩니다.data-scope속성은 컴포넌트를 식별하고,data-part속성은 컴포넌트의 개별 부분을 지정합니다.
ark-ui에서 사용하는 방식인데 적용해볼만한 컨셉이라고 생각한다.
as로 간단하게 처리가 가능할정도의 복잡도라면 괜찮다고 보는데 더 복잡하게 된다면 asChild가 최선의 방법.
function Button({ asChild, ...props }) {
const Comp = asChild ? Slot : 'button'
return <Comp {...props} />
}
Bottom Sheet 라이브러리 비교
react-modal-sheet 추천:
- 활발한 유지보수 (v5 최근 릴리즈)
- Framer Motion 기반, Compound component 패턴
avoidKeyboard,disableDismiss등 유용한 옵션
import { Sheet } from 'react-modal-sheet'
<Sheet isOpen={isOpen} onClose={() => setOpen(false)}>
<Sheet.Container>
<Sheet.Header />
<Sheet.Content>콘텐츠</Sheet.Content>
</Sheet.Container>
<Sheet.Backdrop />
</Sheet>
WARNING
react-spring-bottom-sheet는 3년간 업데이트 없음. 신규 프로젝트에선 피할 것.
- react-modal-sheet
- vaul - Radix 기반 대안
- Material Design - Bottom Sheet
- Apple HIG - Sheet
class CustomError extends Error {
name = 'CustomError'
constructor(message?: string) {
super(message)
Object.setPrototypeOf(this, CustomError.prototype)
}
}
try {
throw new CustomError('This is a custom error message.')
} catch (error) {
if (error instanceof CustomError) {
console.log('CustomError occurred:', error.message)
console.log('Error name:', error.name)
} else {
console.log('An error occurred:', error)
}
}
enum LogLevel {
DEBUG = 'debug',
INFO = 'info',
WARN = 'warn',
ERROR = 'error',
}
type Message = string
class Logger {
private level: LogLevel
constructor(level: LogLevel = LogLevel.DEBUG) {
this.level = level
}
private log(level: LogLevel, message: Message) {
if (this.level === LogLevel.DEBUG || level !== LogLevel.DEBUG) {
const label = level.toUpperCase()
console.log(`[${label}] ${message}`)
}
}
/**
* - 개발 혹은 테스트 단계
* - 운영 환경에서는 남기고 싶지 않은 로그 메세지
*/
public debug(message: Message) {
this.log(LogLevel.DEBUG, message)
}
/**
* - 정상 작동에 대한 정보
* - 시스템을 파악하는데 유익한 정보
*/
public info(message: Message) {
this.log(LogLevel.INFO, message)
}
/**
* - 잠재적으로 문제가 될 수 있는 상황
* - 언제든 발생할 수 있는 일반적인 문제 상황
* - 사용자에게 노출되는 메세지에 상세한 가이드가 필요
*/
public warn(message: Message) {
this.log(LogLevel.WARN, message)
}
/**
* - 심각한 오류나 예외 상황
* - 즉시 조치가 필요할때
*/
public error(message: Message) {
this.log(LogLevel.ERROR, message)
}
}
import z from 'zod'
const envSchema = z.object({
REACT_APP_FEATURE_VAC_ASK: z.string(),
REACT_APP_FEATURE_RECORDS: z.string(),
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
})
const windowSchema = z.object({
SOMETHING_COOL: z.string()
})
export const ENV = envSchema.parse(process.env)
export const WINDOW = windowSchema.parse(window)