SlopeChart

Data Visualization

두 시점의 변화를 연결선으로 보여주는 슬로프 차트.

Usage

두 시점 사이에서 여러 항목의 값이 증가·감소한 방향과 크기를 비교할 때 사용한다.

import

import

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

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

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

API Reference

SlopeChart Props

Prop

Type

Default

data
필수

TDatum[]

지정 안 함

seriesKey
필수

string

지정 안 함

valueKey
필수

string

지정 안 함

xKey
필수

string

지정 안 함

className

string

지정 안 함

colorMode

"series" | "trend"

series

colors

string[]

지정 안 함

legendPosition

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

bottom

margin

Partial<ChartMargin>

지정 안 함

paints

ChartPaint[]

지정 안 함

showLegend

boolean

false

showTooltip

boolean

false

showValueLabels

boolean

true

valueFormat

(value: number) => string

지정 안 함

예제

항목별 색 vs 방향별 색

colorMode="series" 는 항목 구분에, "trend" 는 증가·감소·변화없음 방향에 먼저 시선이 가게 한다.

코드

'use client';

import { SlopeChart } from '@mildang/design-system/Chart';
import { Text } from '@mildang/design-system/Text';
import { HStack, VStack } from '@mildang/styled-system/jsx';
import { css } from '@mildang/styled-system/css';

/**
 * `colorMode="series"` 는 시리즈별로 색을 고정해 항목 자체를 구분하고,
 * `colorMode="trend"` 는 증가·감소·변화없음에 따라 색이 정해져 방향에 시선이 먼저 간다.
 */
const data = [
  { term: '1학기', subject: '국어', score: 72 },
  { term: '2학기', subject: '국어', score: 81 },
  { term: '1학기', subject: '수학', score: 88 },
  { term: '2학기', subject: '수학', score: 76 },
  { term: '1학기', subject: '영어', score: 65 },
  { term: '2학기', subject: '영어', score: 65 },
];

const frame = css({ width: '100%', height: '[220px]' });

export default function SlopeChartColorModesExample() {
  return (
    <HStack gap="6" alignItems="flex-start" flexWrap="wrap">
      <VStack gap="2" alignItems="stretch" flex="1" minWidth="[220px]">
        <Text variant="caption-md" color="neutral.text.low">
          series(기본) — 과목별 색 고정
        </Text>
        <div className={frame}>
          <SlopeChart data={data} xKey="term" seriesKey="subject" valueKey="score" colorMode="series" />
        </div>
      </VStack>
      <VStack gap="2" alignItems="stretch" flex="1" minWidth="[220px]">
        <Text variant="caption-md" color="neutral.text.low">
          trend — 증가·감소·변화없음으로 색 결정
        </Text>
        <div className={frame}>
          <SlopeChart data={data} xKey="term" seriesKey="subject" valueKey="score" colorMode="trend" />
        </div>
      </VStack>
    </HStack>
  );
}

기본

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

const SlopeChartDefaultExample = () => <SlopeChart data={examData} xKey="exam" seriesKey="subject" valueKey="score" />;

export default SlopeChartDefaultExample;

추세 색상 (증가·감소·변화없음)

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

const SlopeChartTrendColorsExample = () => (
    <SlopeChart
      data={examData}
      xKey="exam"
      seriesKey="subject"
      valueKey="score"
      colorMode="trend"
      valueFormat={(v) => `${v.toLocaleString()}점`}
    />
  );

export default SlopeChartTrendColorsExample;

Hover Tooltip

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

const SlopeChartHoverTooltipExample = () => (
    <SlopeChart data={examData} xKey="exam" seriesKey="subject" valueKey="score" showTooltip />
  );

export default SlopeChartHoverTooltipExample;

범례 (값 라벨 숨김)

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

const SlopeChartWithLegendExample = () => (
    <SlopeChart
      data={examData}
      xKey="exam"
      seriesKey="subject"
      valueKey="score"
      showValueLabels={false}
      showLegend
    />
  );

export default SlopeChartWithLegendExample;

기간 3개 — 앞 2개만 사용

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

// 기간이 3개인 long 데이터 — 앞의 두 기간(3월·6월)만 사용된다
const threePeriodData = [
  ...examData,
  { exam: '9월 모의고사', subject: '국어', score: 88 },
  { exam: '9월 모의고사', subject: '수학', score: 79 },
];

const SlopeChartExtraPeriodsExample = () => (
    <SlopeChart data={threePeriodData} xKey="exam" seriesKey="subject" valueKey="score" />
  );

export default SlopeChartExtraPeriodsExample;

값이 0인 경우

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

// 주간 학습 시간 — 0값 포함
const studyData = [
  { week: '지난주', student: '김민준', minutes: 0 },
  { week: '지난주', student: '이서연', minutes: 45 },
  { week: '지난주', student: '박지호', minutes: 120 },
  { week: '이번주', student: '김민준', minutes: 90 },
  { week: '이번주', student: '이서연', minutes: 0 },
  { week: '이번주', student: '박지호', minutes: 120 },
];

const SlopeChartWithZeroValuesExample = () => (
    <SlopeChart
      data={studyData}
      xKey="week"
      seriesKey="student"
      valueKey="minutes"
      colorMode="trend"
      valueFormat={(v) => `${v.toLocaleString()}분`}
    />
  );

export default SlopeChartWithZeroValuesExample;

빈 데이터

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

const SlopeChartEmptyExample = () => <SlopeChart data={[]} xKey="exam" seriesKey="subject" valueKey="score" />;

export default SlopeChartEmptyExample;

시리즈 1개

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

const SlopeChartSingleSeriesExample = () => (
    <SlopeChart
      data={examData.filter((d) => d.subject === '국어')}
      xKey="exam"
      seriesKey="subject"
      valueKey="score"
    />
  );

export default SlopeChartSingleSeriesExample;

반응형 (너비 자동 조정)

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

// 과목별 모의고사 점수 변화 — 상승(국어·수학) / 변화없음(영어) / 하락(과학)
const examData = [
  { exam: '3월 모의고사', subject: '국어', score: 72 },
  { exam: '3월 모의고사', subject: '수학', score: 61 },
  { exam: '3월 모의고사', subject: '영어', score: 85 },
  { exam: '3월 모의고사', subject: '과학', score: 78 },
  { exam: '6월 모의고사', subject: '국어', score: 81 },
  { exam: '6월 모의고사', subject: '수학', score: 74 },
  { exam: '6월 모의고사', subject: '영어', score: 85 },
  { exam: '6월 모의고사', subject: '과학', score: 69 },
];

const SlopeChartResponsiveExample = () => (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 32, width: '100%' }}>
      {([360, 520, 720] as const).map((w) => (
        <div key={w} style={{ width: w, height: 240 }}>
          <SlopeChart data={examData} xKey="exam" seriesKey="subject" valueKey="score" />
        </div>
      ))}
    </div>
  );

export default SlopeChartResponsiveExample;