StripPlot

Data Visualization

visx 기반 지터 산점 스트립 플롯.

Usage

범주별 모든 관측값을 점으로 펼쳐 분포와 겹침을 살펴볼 때 사용한다.

import

import

import { StripPlot } from '@mildang/design-system/Chart';

예제를 복사해 쓸 때 필요한 준비

@mildang/styled-system 은 이 저장소에서 Panda 가 생성하는 산출물이다. 저장소 안에서는 turbo run ship 이후 쓸 수 있고, 패키지 소비자는 자기 Panda 산출물이나 다른 레이아웃 수단으로 바꿔야 한다.

API Reference

StripPlot Props

Prop

Type

Default

categoryKey
필수

string

지정 안 함

data
필수

TDatum[]

지정 안 함

valueKey
필수

string

지정 안 함

className

string

지정 안 함

colors

string[]

지정 안 함

jitterWidth

number

0.6

labels

Record<string, string>

지정 안 함

layout

"horizontal" | "vertical"

vertical

legendPosition

"bottom" | "left" | "right" | "top"

bottom

margin

Partial<ChartMargin>

지정 안 함

opacity

number

0.7

pointRadius

number

4

showGrid

boolean

true

showLegend

boolean

false

showTooltip

boolean

false

showXAxis

boolean

true

showYAxis

boolean

true

예제

기본 (세로)

import { StripPlot } from '@mildang/design-system/Chart';

// 반별 영어 시험 점수 (long 형태 원시 값)
const scoreData = [
  { class: '1반', score: 72 },
  { class: '1반', score: 85 },
  { class: '1반', score: 64 },
  { class: '1반', score: 78 },
  { class: '1반', score: 91 },
  { class: '1반', score: 58 },
  { class: '1반', score: 83 },
  { class: '1반', score: 69 },
  { class: '2반', score: 87 },
  { class: '2반', score: 93 },
  { class: '2반', score: 76 },
  { class: '2반', score: 81 },
  { class: '2반', score: 66 },
  { class: '2반', score: 96 },
  { class: '2반', score: 88 },
  { class: '2반', score: 74 },
  { class: '3반', score: 61 },
  { class: '3반', score: 55 },
  { class: '3반', score: 79 },
  { class: '3반', score: 71 },
  { class: '3반', score: 84 },
  { class: '3반', score: 63 },
  { class: '3반', score: 57 },
  { class: '3반', score: 75 },
];

const StripPlotBasicExample = () => <StripPlot data={scoreData} categoryKey="class" valueKey="score" />;

export default StripPlotBasicExample;

Hover Tooltip

import { StripPlot } from '@mildang/design-system/Chart';

// 반별 영어 시험 점수 (long 형태 원시 값)
const scoreData = [
  { class: '1반', score: 72 },
  { class: '1반', score: 85 },
  { class: '1반', score: 64 },
  { class: '1반', score: 78 },
  { class: '1반', score: 91 },
  { class: '1반', score: 58 },
  { class: '1반', score: 83 },
  { class: '1반', score: 69 },
  { class: '2반', score: 87 },
  { class: '2반', score: 93 },
  { class: '2반', score: 76 },
  { class: '2반', score: 81 },
  { class: '2반', score: 66 },
  { class: '2반', score: 96 },
  { class: '2반', score: 88 },
  { class: '2반', score: 74 },
  { class: '3반', score: 61 },
  { class: '3반', score: 55 },
  { class: '3반', score: 79 },
  { class: '3반', score: 71 },
  { class: '3반', score: 84 },
  { class: '3반', score: 63 },
  { class: '3반', score: 57 },
  { class: '3반', score: 75 },
];

const StripPlotHoverTooltipExample = () => <StripPlot data={scoreData} categoryKey="class" valueKey="score" showTooltip />;

export default StripPlotHoverTooltipExample;

가로 레이아웃

import { StripPlot } from '@mildang/design-system/Chart';

// 반별 영어 시험 점수 (long 형태 원시 값)
const scoreData = [
  { class: '1반', score: 72 },
  { class: '1반', score: 85 },
  { class: '1반', score: 64 },
  { class: '1반', score: 78 },
  { class: '1반', score: 91 },
  { class: '1반', score: 58 },
  { class: '1반', score: 83 },
  { class: '1반', score: 69 },
  { class: '2반', score: 87 },
  { class: '2반', score: 93 },
  { class: '2반', score: 76 },
  { class: '2반', score: 81 },
  { class: '2반', score: 66 },
  { class: '2반', score: 96 },
  { class: '2반', score: 88 },
  { class: '2반', score: 74 },
  { class: '3반', score: 61 },
  { class: '3반', score: 55 },
  { class: '3반', score: 79 },
  { class: '3반', score: 71 },
  { class: '3반', score: 84 },
  { class: '3반', score: 63 },
  { class: '3반', score: 57 },
  { class: '3반', score: 75 },
];

const StripPlotHorizontalExample = () => <StripPlot data={scoreData} categoryKey="class" valueKey="score" layout="horizontal" />;

export default StripPlotHorizontalExample;

좁은 지터 폭

import { StripPlot } from '@mildang/design-system/Chart';

// 반별 영어 시험 점수 (long 형태 원시 값)
const scoreData = [
  { class: '1반', score: 72 },
  { class: '1반', score: 85 },
  { class: '1반', score: 64 },
  { class: '1반', score: 78 },
  { class: '1반', score: 91 },
  { class: '1반', score: 58 },
  { class: '1반', score: 83 },
  { class: '1반', score: 69 },
  { class: '2반', score: 87 },
  { class: '2반', score: 93 },
  { class: '2반', score: 76 },
  { class: '2반', score: 81 },
  { class: '2반', score: 66 },
  { class: '2반', score: 96 },
  { class: '2반', score: 88 },
  { class: '2반', score: 74 },
  { class: '3반', score: 61 },
  { class: '3반', score: 55 },
  { class: '3반', score: 79 },
  { class: '3반', score: 71 },
  { class: '3반', score: 84 },
  { class: '3반', score: 63 },
  { class: '3반', score: 57 },
  { class: '3반', score: 75 },
];

const StripPlotNarrowJitterExample = () => <StripPlot data={scoreData} categoryKey="class" valueKey="score" jitterWidth={0.2} />;

export default StripPlotNarrowJitterExample;

포인트 크기·투명도

import { StripPlot } from '@mildang/design-system/Chart';

// 학생별 일일 학습 시간(분) — 지터 폭·포인트 스타일 데모용
const studyData = [
  { subject: '영어', minutes: 45 },
  { subject: '영어', minutes: 62 },
  { subject: '영어', minutes: 38 },
  { subject: '영어', minutes: 71 },
  { subject: '영어', minutes: 54 },
  { subject: '영어', minutes: 49 },
  { subject: '수학', minutes: 82 },
  { subject: '수학', minutes: 95 },
  { subject: '수학', minutes: 67 },
  { subject: '수학', minutes: 78 },
  { subject: '수학', minutes: 88 },
  { subject: '수학', minutes: 73 },
];

const StripPlotPointStyleExample = () => (
    <StripPlot data={studyData} categoryKey="subject" valueKey="minutes" pointRadius={7} opacity={0.45} />
  );

export default StripPlotPointStyleExample;

범례 + 커스텀 색상

import { StripPlot } from '@mildang/design-system/Chart';
import { token } from '@mildang/styled-system/tokens';

// 반별 영어 시험 점수 (long 형태 원시 값)
const scoreData = [
  { class: '1반', score: 72 },
  { class: '1반', score: 85 },
  { class: '1반', score: 64 },
  { class: '1반', score: 78 },
  { class: '1반', score: 91 },
  { class: '1반', score: 58 },
  { class: '1반', score: 83 },
  { class: '1반', score: 69 },
  { class: '2반', score: 87 },
  { class: '2반', score: 93 },
  { class: '2반', score: 76 },
  { class: '2반', score: 81 },
  { class: '2반', score: 66 },
  { class: '2반', score: 96 },
  { class: '2반', score: 88 },
  { class: '2반', score: 74 },
  { class: '3반', score: 61 },
  { class: '3반', score: 55 },
  { class: '3반', score: 79 },
  { class: '3반', score: 71 },
  { class: '3반', score: 84 },
  { class: '3반', score: 63 },
  { class: '3반', score: 57 },
  { class: '3반', score: 75 },
];

const StripPlotWithLegendExample = () => (
    <StripPlot
      data={scoreData}
      categoryKey="class"
      valueKey="score"
      colors={[
        token('colors.blue.light.400'),
        token('colors.green.light.400'),
        token('colors.orange.light.400'),
      ]}
      labels={{ '1반': '1반 (오전)', '2반': '2반 (오후)', '3반': '3반 (저녁)' }}
      showLegend
    />
  );

export default StripPlotWithLegendExample;

빈 데이터

import { StripPlot } from '@mildang/design-system/Chart';

const StripPlotEmptyExample = () => <StripPlot data={[]} categoryKey="class" valueKey="score" />;

export default StripPlotEmptyExample;

데이터 1개

import { StripPlot } from '@mildang/design-system/Chart';

const StripPlotSingleDatumExample = () => <StripPlot data={[{ class: '1반', score: 80 }]} categoryKey="class" valueKey="score" />;

export default StripPlotSingleDatumExample;

0값 포함

import { StripPlot } from '@mildang/design-system/Chart';

const StripPlotWithZeroValuesExample = () => (
    <StripPlot
      data={[
        { class: '1반', score: 0 },
        { class: '1반', score: 45 },
        { class: '1반', score: 80 },
        { class: '2반', score: 0 },
        { class: '2반', score: 62 },
        { class: '2반', score: 91 },
      ]}
      categoryKey="class"
      valueKey="score"
    />
  );

export default StripPlotWithZeroValuesExample;

반응형 (너비 자동 조정)

import { StripPlot } from '@mildang/design-system/Chart';

// 반별 영어 시험 점수 (long 형태 원시 값)
const scoreData = [
  { class: '1반', score: 72 },
  { class: '1반', score: 85 },
  { class: '1반', score: 64 },
  { class: '1반', score: 78 },
  { class: '1반', score: 91 },
  { class: '1반', score: 58 },
  { class: '1반', score: 83 },
  { class: '1반', score: 69 },
  { class: '2반', score: 87 },
  { class: '2반', score: 93 },
  { class: '2반', score: 76 },
  { class: '2반', score: 81 },
  { class: '2반', score: 66 },
  { class: '2반', score: 96 },
  { class: '2반', score: 88 },
  { class: '2반', score: 74 },
  { class: '3반', score: 61 },
  { class: '3반', score: 55 },
  { class: '3반', score: 79 },
  { class: '3반', score: 71 },
  { class: '3반', score: 84 },
  { class: '3반', score: 63 },
  { class: '3반', score: 57 },
  { class: '3반', score: 75 },
];

const StripPlotResponsiveExample = () => (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 32, width: '100%' }}>
      {([280, 480, 720] as const).map((w) => (
        <div key={w} style={{ width: w, height: 240 }}>
          <StripPlot data={scoreData} categoryKey="class" valueKey="score" />
        </div>
      ))}
    </div>
  );

export default StripPlotResponsiveExample;