본문으로 이동

차트

차트는 차트 카드(chart 이름 "제목" 종류 { ... })와 plot 보기로 그립니다. 값은 카드 안의 row, point, cell, sample 줄이나 JSON 파일에서 읽고, 장면의 reveal로 계열을 차례로 드러냅니다. 차트 종류는 열여섯 가지이고, 종류마다 예제가 하나씩 있습니다.

종류 보여 줄 것 계열 수 행 줄 예제
bar 조건별 값과 신뢰구간 1 이상 row "항목" 계열=값 bar
stacked 구성값과 합계. 음수는 0 왼쪽에 쌓입니다 1 이상 row "항목" 계열=값 stacked
percent 행마다 합을 100%로 놓은 몫 2 이상 row "항목" 계열=값 percent
dumbbell 같은 입력에서 두 방식 비교 정확히 2 row "항목" 계열=값 계열=값 dumbbell
difference 음수일 수 있는 차이와 신뢰구간 정확히 1 row "항목" 계열=값 difference
line 순서나 시간에 따른 변화 1 이상 point x=값 계열=값 line
step 값이 바뀔 때만 움직이는 계단 변화 1 이상 point x=값 계열=값 step
area 0 기준선까지 채운 변화. 계열은 겹쳐 그립니다 1 이상 point x=값 계열=값 area
scatter 두 변수의 관계 0 이상 point "이름" x=값 y=값 [series=계열], link "이름" -> "이름" scatter
histogram 원시 관측값의 구간별 건수 0 sample 값, bins 최솟값 최댓값 구간수 또는 bins auto histogram
box 연속값 분포 0 row "항목" min=값 q1=값 median=값 q3=값 max=값 box
ecdf 표본의 누적분포 0 이상 sample 값 [series=계열] ecdf
heatmap 교차표의 값 크기 0 cell "행" "열" 값 heatmap
donut, pie 전체에서 차지하는 몫 0 row "항목" value=값 donut, pie
waterfall 증감과 중간·최종 합계 0 row "항목" value=값, total "이름" waterfall

최소 예제

계열은 series 이름 "표시 이름" [role=main|compare|reference]로 선언하고, 값 축 제목에는 괄호 단위를 붙입니다. 카드 제목과 부제는 카드 줄(chart 줄)에 적고, plot 보기는 카드 하나를 문서 폭으로 보입니다. 보기에 아직 배치하지 않은 카드가 차트와 추적뿐이고 그룹에 속한 카드나 명시한 graph 보기가 없으면, 각 차트에 plot 보기가 기본으로 생깁니다. 연결선 유무는 기준이 아닙니다. 아직 어느 보기에 배치하지 않은 일반 카드와 섞이면 그래프에 놓이므로 독립 차트로 보이려면 view plot에 명시합니다. 라벨을 붙이거나 순서를 정하려면 view plot "라벨" {로 적습니다.

문법

줄 종류와 선택 사항은 그림 문법의 문법 표가 정본이고, 종류별 행 줄, 머리 줄, 값 출처, 시간 흐름은 차트에 있습니다.

  • 역할. main과 compare는 각각 하나 이하입니다. 하나뿐인 계열은 생략한 역할이 main입니다. 두 계열이면 아직 쓰지 않은 main, compare를 선언 순서대로 받으며, 덤벨은 시작점인 compare를 먼저 받습니다. 계열이 셋 이상이면 역할을 생략한 계열 모두 역할 없이 남습니다. reference는 계획이나 목표처럼 x마다 값이 있는 기대값 계열이고, 막대 차트는 행을 가로지르는 세로 눈금, 선은 점선으로 그려 실제값과 구분합니다. stacked, percent, dumbbell, donut, pie에서는 쓸 수 없습니다.
  • 색. 계열 색은 범주 번호로 정합니다. 일곱 색(blue, yellow, red, green, orange, purple, cyan)을 넘으면 같은 색에 무늬가 더해집니다. 점 모양(원, 사각형, 마름모, 삼각형)은 색 수와 상관없이 범주 번호를 따라 돌므로 파랑과 주황처럼 모양이 같은 쌍도 있습니다. 막대 계열은 범례로, 산점도 계열은 범례와 점 모양으로, 선, 계단, 면적, 누적분포가 둘 이상이면 끝 이름으로 구분합니다. 원과 도넛의 조각은 바깥에 이름과 값·비율을 직접 적고 안내선으로 잇습니다. 누적, 퍼센트, 원, 도넛에서 몫이 5% 미만인 항목이 둘 이상이거나 항목이 일곱 색을 넘으면 작은 쪽을 회색 기타 하나로 묶어 적습니다(값에 묶인 차트는 묶지 않습니다). 색만으로 구분하지 않습니다. 무늬 정의는 SVG마다 한 번만 들어갑니다.
  • 빠진 값과 0. -는 측정이 없다는 뜻이고 0과 다릅니다. 막대는 missing "글" 문구를 보이고, 선과 계단은 그 점에서 끊기며, 누적과 퍼센트의 행은 그 행을 정하지 않습니다. 퍼센트는 합이 0인 행도 합계 0 · 비율 정의 불가로 알리고 0%로 그리지 않습니다. 값이 모두 0이거나 모두 빠져도 오류가 아닙니다. 0은 길이 0의 값으로 그리고, 모두 빠졌으면 틀과 축만 그리며 어떤 표식에도 0을 주지 않습니다. 히스토그램의 sample -는 관측에서 빼고 결측 k개 제외로 알리며 비율의 분모에도 넣지 않습니다. 워터폴의 value=-는 막대 없이 값 없음으로 쓰고 그 뒤의 누계는 알 수 없습니다. 상자는 다섯 값 가운데 하나라도 빠진 행에 모양 없이 적힌 숫자만 보입니다. 면(area)은 빠진 값을 받지 않습니다.
  • 신뢰구간과 기준선. 막대, 덤벨, 선, 차이 차트는 계열.low=값 계열.high=값을 받습니다. rule 값 "라벨"은 모든 행의 기준선이고, 막대 행의 rule=값은 그 행에만 겹칩니다.
  • 값 묶기. 행의 숫자 자리에 값 이름(ms=p95)을 쓰면 그 값이 바뀔 때 차트가 바뀝니다. 바뀐 표식만 강조하고 축은 움직이지 않습니다. metric 예제와 donut 예제가 카드의 값과 차트를 함께 움직입니다.

metric 예제의 API 1 CPU 기록(%)은 급증 장면의 마지막 도착 때 snapshot:=cpu1로 복사한 값이다. 기록 전에는 미기록을 표시하고 다음 장면에서도 keep으로 마지막 기록을 유지한다. 이는 현재 CPU나 기간 중 최댓값의 자동 집계가 아니며, 기록 뒤 API 1의 CPU가 바뀌어도 함께 바뀌지 않는다. ref=p95로 묶은 대시보드 값과 차트는 원천 값의 변화를 계속 따른다.

장면과 움직임

reveal 차트.계열이 계열을 드러냅니다. 막대는 값 축 시작에서 자라고, 덤벨은 compare 값에서 화살표가 자라며, 선은 왼쪽부터 그어집니다. light 차트 "행"은 행이나 점을 밝히고 나머지를 흐리게 하고(히트맵은 흐리지 않고 밝힌 칸의 숫자만 굵게 합니다), 선과 계단은 light 차트 x=값을 씁니다. 남은 light는 정지 장면과 멈춘 SVG의 마지막 모습에도 그대로 보입니다. 한 장면의 reveal에 나온 계열만 그 장면이 시작할 때 숨고, 나오지 않은 계열은 처음부터 보입니다. 장면의 mode=static은 마지막 상태 하나를 보여 줍니다.

히스토그램: 지연이 몰리는 구간

Plain text
thinkflow
chart latency "응답 지연 분포" histogram {
  x "응답 지연(ms)"
  y "요청(건)"
  bins 0 300 3
  sample 20
  sample 80
  sample 100
  sample 150
  sample 300
}
scene "가장 많은 구간" mode=static
  light latency x=0

각 구간의 건수는 2·2·1입니다. 100ms는 두 번째 구간에, 300ms는 마지막 구간에 포함됩니다. 범위를 벗어난 값은 오류이며 버리지 않습니다. 범위를 직접 정하지 않으려면 bins auto(Sturges 방식)를 쓰고, 자동 구간은 경계를 알 수 없어 light로 고를 수 없습니다. measure=count|probability|density로 건수, 비율, 확률밀도를 고릅니다. histogram 예제는 같은 표본을 두 방식으로 나란히 보입니다.

워터폴: 무엇이 최종 값을 바꿨는가

Plain text
thinkflow
chart cost "응답 시간 개선" waterfall {
  x "시간(ms)"
  row "기본 처리" value=120
  row "데이터 조회" value=80
  total "개선 전"
  row "캐시 적용" value=-50
  total "최종 응답"
}
scene "캐시 효과" mode=static
  light cost "캐시 적용"

개선 전 합계는 200ms이고, 캐시 적용 뒤 최종 응답은 150ms입니다. total은 값을 다시 입력하지 않고, 중간 합계를 추가해도 이후 누계가 바뀌지 않습니다.

흔한 오류

원인 메시지 code 고치는 방법
계열 수가 종류의 한도를 벗어남 a dumbbell chart takes 2 series. Found 3 syntax 차트를 나눕니다
기대값 계열을 쓸 수 없는 종류 a stacked chart has no expected-value series, so role=reference is not allowed. It stacks, divides, or pairs its series syntax 선, 막대, 계단에서 씁니다
퍼센트에 음수 a percent chart shares a whole, so values cannot be negative syntax 음수가 있는 구성은 stacked를 씁니다
행이 없음 a chart needs at least one row syntax 종류의 행 줄을 적습니다
없는 행을 밝힘 light target "q" is not in the chart syntax 차트에 있는 행 이름을 적습니다
숫자가 아닌 값에 묶음 chart "c" reads "v", which holds "none" at the start. A chart value is a number value-type 값의 시작 값을 숫자로 둡니다
묶은 값이 장면 중에 차트의 값 범위를 어김 chart "c" reads v=-5: values cannot be negative value-type 같은 숫자를 행에 적어도 거절되는 값이면 묶어도 거절됩니다. 값이 범위 안에 머물게 합니다. 오류는 묶은 행의 줄에 붙습니다
data 파일을 읽지 못함 cannot read data "a.json" at "/rows": ENOENT 또는 not valid JSON at position 12 syntax 경로와 JSON을 고칩니다. 메시지에 파일의 내용은 싣지 않습니다
값 축 제목에 단위 없음 the value axis title needs a unit in parentheses, such as x "latency(ms)" syntax 제목에 (단위)를 붙입니다(경고, --strict에서 실패)

code는 thinkflow check figure.thinkflow --json으로 봅니다.