이 가이드는 도로교통공단(TAAS) 표준데이터(전국교통사고다발지역표준데이터-20260301.xls, 12,780행)를 가지고 5개 학습 가이드 HTML(js_charts.html, js_more_charts.html, js_network.html, js_map.html, js_scrollytelling.html)에 나오는 모든 시각화를 그대로 만들어 본다.
초보자를 위해 모든 프롬프트는 짧은 자연어 한두 문장으로 작성했다. 색상·크기·세부 옵션을 처음부터 다 적지 않는다. 첫 결과를 받은 뒤 마음에 안 드는 부분이 있으면 다음과 같이 자연어로 수정 요청하면 된다.
좋은 시각화는 첫 프롬프트로 끝나지 않는다. Gemini와 4~5번 주고받으며 다듬는 게 정상이다. 이 과정 자체가 데이터저널리즘 실습의 핵심이다.
---
| 축 | 컬럼 | 값 |
|---|---|---|
| 시간 | 사고연도 |
2012~2024 (13개년) |
| 분류 | 사고유형구분 |
보행노인 / 자전거 / 보행어린이 / 스쿨존어린이 (4종) |
| 지역 | 사고다발지역시도시군구, 사고지역위치명 |
17개 시도 |
| 공간 | 위도, 경도 |
WGS84 좌표 |
| 지표 | 사고건수, 사상자수, 사망자수, 중상자수, 경상자수, 부상신고자수 |
정수 |
| 메타 | 사고지역관리번호, 위치코드, 데이터기준일자, 제공기관명 |
— |
이 데이터에는 시간대·요일·월·차종·연령·위반항목 정보가 없다. 따라서 가이드 HTML의 일부 원전형 사례(시간대 Polar Area, 시간×요일 Matrix Heatmap 등)는 그대로 적용 불가이며, 같은 차트형을 가용한 축으로 재구성해야 한다. 데이터의 한계를 인식하고 가용한 축으로 질문을 재구성하는 것 자체가 학습 과정이 될 수 있다.
| 시각화 원본 사례 | 본 데이터 적용 시 |
|---|---|
| 시간대 Polar Area | → 사고유형 4종 분포 |
| 일자별 Calendar Heatmap | → 시도 × 연도 매트릭스 |
| 시간×요일 Matrix Heatmap | → 사고유형 × 시도 |
| 차종 기반 Sankey | → 사고유형 → 시도 → 상해등급 |
| 시간대 워드클라우드 | → 사고지역위치명 키워드 |
---
.xls는 JS에서 직접 못 읽고, CSV는 한글 인코딩과 따옴표 문제가 있다. JSON은 fetch().then(r => r.json()) 한 줄로 객체 배열이 된다. 그리고 Chart.js·Leaflet·D3·vis-network 등 본 강의에서 쓰는 모든 라이브러리가 객체 배열을 그대로 받아들인다.
초보자가 헷갈리지 않도록 모든 시각화가 단 하나의 data.json 파일을 참조한다. 다만 브라우저에서 fetch로 8MB JSON을 매번 받게 두면 file:// 차단·로딩 지연 문제가 생긴다. 그래서 본 가이드는 한 발 더 나가, 필요한 집계(연도별 합계, 시도별 합계, 상위 N개 행 등)를 LLM에게 미리 시킨 뒤 결과 데이터만 HTML <script> 안에 박아 넣어 단일 파일로 산출한다. 산출물은 인터넷·서버 없이 더블클릭만으로 즉시 보이고, 카카오톡·메일 첨부 한 방으로 공유 가능하다.
convert_to_json.py로 저장 후 한 번만 실행한다. 결과로 data.json 하나가 생긴다.
import pandas as pd
# 원본 로드 (xls는 xlrd 엔진 필요: pip install xlrd)
df = pd.read_excel(
"전국교통사고다발지역표준데이터-20260301.xls",
engine="xlrd"
)
# 시도 컬럼 파생: "서울특별시 강남구1" → "서울특별시"
df['시도'] = df['사고다발지역시도시군구'].str.split().str[0]
# 끝에 붙은 숫자 제거 (예: "세종특별자치시1" → "세종특별자치시")
df['시도'] = df['시도'].str.replace(r'\\d+$', '', regex=True)
# 한 줄짜리 폴리곤 컬럼은 너무 무거우니 제거 (시각화에 안 씀)
df = df.drop(columns=['사고다발지역폴리곤정보'])
# JSON으로 저장 (한글 그대로 유지)
df.to_json("data.json", orient="records", force_ascii=False, indent=2)
print(f"data.json 생성 완료: {len(df):,}행")
위 스크립트를 직접 짜지 않고 Gemini에게 맡길 때:
첨부한 교통사고 다발지역 xls 파일을 data.json 하나로 변환하는 Python 스크립트 만들어줘. 사고다발지역시도시군구 컬럼에서 시도(서울특별시, 경기도 등)를 따로 뽑아서 시도 컬럼을 추가해줘. 폴리곤 컬럼은 빼고. 한글 그대로 유지되게.
생성된 파일은 객체 배열이고 한 행은 다음과 같다.
{
"사고지역관리번호": 2025108,
"사고연도": 2024,
"사고유형구분": "보행어린이",
"사고다발지역시도시군구": "전북특별자치도 정읍시1",
"사고지역위치명": "전북특별자치도 정읍시 상동(한솔초등학교 부근)",
"사고건수": 3,
"사상자수": 3,
"사망자수": 0,
"중상자수": 0,
"경상자수": 3,
"부상신고자수": 0,
"위도": 35.560543,
"경도": 126.873488,
"데이터기준일자": "2025-09-24",
"시도": "전북특별자치도"
}
JS에서는 이렇게 쓴다.
fetch('./data.json')
.then(r => r.json())
.then(data => {
// data는 12,780개 객체의 배열
// 예: 연도별 사고건수 합계 만들기
const byYear = {};
data.forEach(d => {
byYear[d.사고연도] = (byYear[d.사고연도] || 0) + d.사고건수;
});
console.log(byYear);
});
위 패턴(fetch → forEach → 누적)만 익히면 어떤 시각화든 만들 수 있다.
---
js_charts.html) data.json에서 연도별 사고건수 합계를 막대 그래프로 그려줘. 연도별 합계를 미리 집계해서 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Bar 패턴을 참조할 것. 파란색 계열, 2020년 떨어진 게 잘 보이게.
다듬을 때: "2020년만 빨간색으로 강조" / "y축 숫자에 천 단위 콤마" / "막대 좀 더 두껍게"
data.json에서 연도별 사고건수와 사망자수를 두 줄의 라인차트로 그려줘. 두 합계를 연도별로 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Line 이중축 패턴을 참조할 것. 단위가 다르니 좌우 축 따로, 사고건수는 파란색·사망자는 빨간색.
다듬을 때: "마우스 올리면 두 값 동시에 보이게" / "선 아래 영역도 색칠해줘"
data.json의 사고유형구분 4가지(보행노인·자전거·보행어린이·스쿨존어린이) 비율을 파이차트와 도넛차트 두 개로 나란히 그려줘. 4유형 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Pie/Doughnut 패턴을 참조할 것. 마우스 올리면 % 같이 보이게.
다듬을 때: "범례 위치를 오른쪽으로" / "도넛 가운데에 합계 숫자 넣어줘"
data.json에서 사고건수 상위 7개 시도의 사고건수와 사망자수를 레이더차트로 그려줘. 시도별 두 합계 + 0~100 정규화 결과까지 미리 계산해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Radar 패턴을 참조할 것. 사고건수는 파란색·사망자는 빨간 면.
다듬을 때: "도형 더 진하게" / "꼭짓점에 점 표시"
data.json으로 17개 시도를 버블차트로 그려줘 (x=사고건수, y=사망자수, 원 크기=사상자수). 시도별 세 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Bubble 패턴을 참조할 것. 시도마다 다른 색, 원 크기는 제곱근 변환.
다듬을 때: "버블 크기 차별화 잘 안 되니 더 크게 차이내" / "각 점에 시도명 라벨 붙여"
data.json에서 시도별 사고건수(x)와 사망률(y, 사망자÷사상자×100) 산점도를 그려줘. 시도별 합계와 사망률을 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Scatter 패턴을 참조할 것. 점에 시도 이름 붙여 마우스 올리면 보이게, 보라색 점.
다듬을 때: "추세선 그어줘" / "점 더 크게"
data.json의 사고유형 4가지를 polarArea로 그려줘. 4유형 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 Polar Area 패턴을 참조할 것. 4가지 다른 색, 차트 아래에 작게 "원래는 시간대 분포가 표준이지만, 이 데이터에 시간 정보가 없어 사고유형으로 대체"라고 적어줘.
data.json으로 연도별 사고건수는 막대(파란색), 사망률(사망자÷사상자×100)은 빨간 선으로 그려줘. 연도별 합계와 사망률을 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js mixed 사용 — 같은 폴더 js_charts.html의 Mixed 패턴을 참조할 것. 두 지표 단위가 달라 좌우 축 따로.
다듬을 때: "막대 좀 투명하게" / "선 끝에 점 표시"
data.json으로 시도×사고유형 트리맵 만들어줘. 17×4 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 트리맵 플러그인 사용 — 같은 폴더 js_charts.html의 Treemap 패턴을 참조할 것. 시도가 큰 박스·그 안에 사고유형이 작은 박스, 시도마다 다른 색.
다듬을 때: "박스 안에 숫자 보이게" / "테두리 흰색으로 명확히"
data.json으로 인터랙티브 차트 만들어줘 (위에 드롭다운 세 개: 지표·차트 종류·표시 기간). 5개 지표(사고건수/사망자/사상자/중상/경상)의 연도별 합계 13개년을 모두 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js 사용 — 같은 폴더 js_charts.html의 인터랙티브 필터 패턴을 참조할 것. 차트 종류는 막대/선/레이더/폴라, 기간은 2~13년, 드롭다운 바꿀 때마다 다시 그려지게.
다듬을 때: "차트 바뀔 때 부드럽게 애니메이션" / "드롭다운 라벨 한국어로 명확히"
---
js_more_charts.html) data.json의 사고지역위치명 12,780개로 워드클라우드 만들어줘. 한국어 불용어(은/는/이/가 등) 제외 후 단어 빈도 상위 80개를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). D3 + d3-cloud 사용 — 같은 폴더 js_more_charts.html의 워드클라우드 패턴을 참조할 것. 색은 알록달록하게.
다듬을 때: "'부근' 단어가 너무 커서 빼줘" / "회전 0도만"
data.json으로 Sankey 다이어그램 만들어줘 (사고유형 4가지 → 상위 5개 시도 → 상해등급 3단계). 3단계 흐름 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js sankey 플러그인 사용 — 같은 폴더 js_more_charts.html의 Sankey 패턴을 참조할 것. 상해등급은 경상·중상·사망, 흐름 두께가 사고건수.
다듬을 때: "사망 흐름만 빨간색으로" / "라벨 글자 크기 키워"
data.json으로 시도(세로) × 연도(가로) 히트맵 그려줘. 17×13 사고건수 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). ApexCharts 사용 — 같은 폴더 js_more_charts.html의 Calendar Heatmap 패턴을 참조할 것. 칸 색은 분홍 그라디언트(진할수록 사고 많은 칸), 차트 아래에 "원래 캘린더 히트맵은 일자별이지만 이 데이터에 일자가 없어 연도로 변형"이라고 적어줘.
data.json으로 권역→시도→사고유형 3단계 sunburst 만들어줘 (5권역: 수도권/영남/호남/충청/강원·제주). 3단계 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Plotly 사용 — 같은 폴더 js_more_charts.html의 Sunburst 패턴을 참조할 것. 권역 매핑: 수도권(서울·경기·인천)/영남(부산·대구·울산·경남·경북)/호남(광주·전남·전북)/충청(대전·세종·충남·충북)/강원·제주, 핑크 계열 색.
다듬을 때: "각 조각에 % 같이 표시" / "가운데 색 더 진하게"
data.json으로 17개 시도를 평행좌표로 그려줘 (4개 축: 사고건수·사망자·사망률·사상자). 시도별 4개 값을 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Plotly parcoords 사용 — 같은 폴더 js_more_charts.html의 Parallel Coordinates 패턴을 참조할 것. 선 색은 사망률에 따라 그라디언트.
다듬을 때: "축 라벨 잘려서 안 보이니 위쪽 여백 늘려" / "특정 시도 강조해줘"
data.json으로 사고유형 4개 × 시도 17개 매트릭스 히트맵 만들어줘. 사고건수 합계를 미리 집계해서 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Chart.js matrix 플러그인 사용 — 같은 폴더 js_more_charts.html의 ⑥ Matrix 섹션 패턴을 참조할 것. 사고건수가 많을수록 진한 분홍, 마우스 올리면 칸 정보 보이게.
data.json에서 다발지역이 많은 상위 7개 시도의 다발지역별 사고건수 분포를 박스플롯으로 그려줘. 시도별 사고건수 배열(상위 7개)만 미리 추려 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Plotly 사용 — 같은 폴더 js_more_charts.html의 Box Plot 패턴을 참조할 것. 이상치는 점으로 표시.
다듬을 때: "박스 너비 더 넓게" / "각 박스 아래에 시도 이름과 평균값 표시"
data.json에서 2024 vs 2023 비교 4개 KPI 카드 만들어줘 (사고건수·사망자·사상자·사망률). 연도별 4개 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Plotly indicator 사용 — 같은 폴더 js_more_charts.html의 Gauge/KPI 패턴을 참조할 것. 게이지+숫자+전년 대비 화살표, 2×2 격자, 악화는 빨강·개선은 초록.
다듬을 때: "악화한 건 빨간 화살표 개선한 건 초록 화살표" / "카드 제목 더 크게"
data.json의 2024년 합계로 깔때기 차트 그려줘 (사고→사상자→경상→중상→사망). 2024년 5개 단계 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Plotly funnel 사용 — 같은 폴더 js_more_charts.html의 Funnel 패턴을 참조할 것. 단계마다 절대값과 첫 단계 대비 비율도 표시.
---
js_network.html) data.json에서 사망자 2명 이상 다발지역 5~10개를 노드로 만들어 vis-network로 기초 그래프 그려줘. 노드와 엣지 목록을 미리 추려 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). vis-network 사용 — 같은 폴더 js_network.html의 N1 기본 패턴을 참조할 것. 같은 시도면 선 연결, 점은 둥글게.
data.json으로 17개 시도(파란) × 사고유형 4개(주황) 양분 네트워크 만들어줘. 17×4=68개 엣지의 사고건수 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). vis-network 사용 — 같은 폴더 js_network.html의 양분 네트워크 패턴을 참조할 것. 선 두께가 사고건수, 노드 크기도 합계에 따라 다르게.
다듬을 때: "선 너무 많아서 헷갈려 — 상위 30개만" / "범례 추가"
data.json으로 4계층 트리 그려줘 (전국→5권역→17시도→사고유형). 권역·시도·유형 3단계 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). vis-network 계층 레이아웃 사용 — 같은 폴더 js_network.html의 계층 Tree 패턴을 참조할 것. 5권역=수도권/영남/호남/충청/강원·제주, 위에서 아래로, 권역은 진한 파란색.
다듬을 때: "방향 좌→우로" / "각 노드에 합계 숫자 같이"
data.json으로 3그룹 force-directed 네트워크 만들어줘 (시도 상위 7개·사고유형 4개·연도구간 3개). 노드 목록과 엣지 가중치를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). D3 v7 사용 — 같은 폴더 js_network.html의 Force-Directed 패턴을 참조할 것. 연도구간=2012-2015/2016-2019/2020-2024, 그룹마다 다른 색, 자기들끼리 자동 배치.
data.json으로 23개 노드 트리(전국+5권역+17시도)를 그려줘. 시도 합계만 미리 계산해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Cytoscape + dagre 사용 — 같은 폴더 js_network.html의 Cytoscape Dagre 패턴을 참조할 것. 위에 드롭다운으로 dagre/cose/circle/grid/concentric 즉시 전환.
data.json의 시도 5개 + 사고유형 4개를 베이스로 vis-network 인터랙티브 편집기 만들어줘. 초기 노드와 엣지 목록을 미리 만들어 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). vis-network 사용 — 같은 폴더 js_network.html의 인터랙티브 조작 패턴을 참조할 것. 버튼: 노드 추가/엣지 추가/선택 삭제/화면 맞춤/초기화. 노드 클릭 시 직접 연결된 이웃만 진하고 나머지는 흐리게.
data.json의 사고지역위치명 전체로 의미연결망 만들어줘. 한국어 불용어 제거 후 단어 빈도와 동시출현 행렬을 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). vis-network 사용 — 같은 폴더 js_network.html의 의미연결망 패턴을 참조할 것. 상위 25개 단어=노드, 동시출현 2회 이상=엣지, 상단에 단어 수와 최소 동시출현 컨트롤.
다듬을 때: "'부근' 단어가 거의 모든 단어와 연결돼서 의미 흐려져 — 빼줘" / "노드 크기 차이 더 크게"
---
js_map.html) 본 데이터의 위경도가 가장 빛나는 영역. 모두 변형 없이 적용 가능.
data.json에서 사망자 1명 이상 중 상위 10개 다발지역을 Leaflet 지도에 마커로 찍어줘. 상위 10개 행만 필터해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Leaflet 사용 — 같은 폴더 js_map.html의 기초 마커 패턴을 참조할 것. 마커 클릭 시 위치명·연도·사고유형·사망자수 팝업.
data.json 12,780개 전부를 Leaflet markercluster로 클러스터 지도 만들어줘. 필요한 컬럼만(위경도·사고유형·위치명) 추려 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게 — 임베드 시 약 1MB). Leaflet + markercluster 사용 — 같은 폴더 js_map.html의 마커 클러스터 패턴을 참조할 것. 사고유형별 색(보행노인 파랑/자전거 빨강/보행어린이 주황/스쿨존어린이 녹색), 상단에 4개 유형 켜고 끄는 체크박스.
다듬을 때: "처음 줌 레벨 좀 더 가깝게" / "마커 좀 더 작게"
data.json에서 사고건수 상위 30개 다발지역을 Leaflet에 원형 마커로 그려줘. 상위 30개 행만 필터해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Leaflet 사용 — 같은 폴더 js_map.html의 원형 마커 패턴을 참조할 것. 원 크기는 사고건수에 √ 비례, 빨간 반투명, 클릭 시 위치명·시도·사고건수·사망자수.
다듬을 때: "원이 너무 커서 겹쳐 — 다 줄여" / "사망자 있는 곳만 다른 색"
data.json 12,780개 전부로 Leaflet 히트맵 만들어줘. 필요한 컬럼만(위경도·사고건수) 추려 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게 — 임베드 시 약 0.5MB). leaflet.heat 사용 — 같은 폴더 js_map.html의 히트맵 패턴을 참조할 것. 강도는 사고건수에 비례, 상단에 슬라이더 두 개로 반지름·흐림 정도 조절.
다듬을 때: "기본 반지름 더 크게" / "색 변화 더 강렬하게"
data.json으로 시도별 사고건수 합계를 Leaflet 코로플레스로 그려줘. 17개 시도 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). 단, 시도 경계 GeoJSON만 외부에서 fetch (cdn.jsdelivr.net/gh/southkorea/southkorea-maps). Leaflet 사용 — 같은 폴더 js_map.html의 코로플레스 패턴을 참조할 것. 시도명 매핑(서울특별시→서울 등) 포함, 색은 파랑 농도, 마우스 강조·클릭 팝업·범례 추가.
다듬을 때: "강원특별자치도/전북특별자치도가 매칭 안 돼서 흰색 — 매핑 추가" / "색 단계 5단계 → 7단계로"
data.json으로 한 지도에 세 가지 도형 그려줘 (상위 7개 시도 잇는 빨간 폴리라인·수도권 4개 파란 폴리곤·사망자 상위 5개 녹색 원). 시도 중심점·다발지역 상위 5개 좌표를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Leaflet 사용 — 같은 폴더 js_map.html의 폴리라인/폴리곤/원 패턴을 참조할 것. 수도권=서울·경기·인천·세종, 원 반경 2km.
Leaflet 종합 지도 만들어줘 (베이스맵 3개 라디오 + 데이터 레이어 4개 토글). M1·M3·M4·M5에서 만든 사전 집계 데이터를 모두 합쳐 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게 — 단, 시도 GeoJSON만 외부 fetch). Leaflet 사용 — 같은 폴더 js_map.html의 레이어 컨트롤 패턴을 참조할 것. 베이스맵=OSM/어두움/밝음, 레이어=주요 사망사고/상위 30 원형/전체 히트맵/시도 코로플레스, 처음엔 OSM+사망사고+코로플레스만 켜져 있게.
---
js_scrollytelling.html) data.json으로 시도 17개 통계 표 만들어줘. 17개 시도의 7개 컬럼(다발지역수·사고건수·사망자·사상자·사망률·인구10만명당)을 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). DataTables.js 사용 — 같은 폴더 js_scrollytelling.html의 DataTables 패턴을 참조할 것. 헤더 클릭 정렬·검색창·페이지 이동, 한국어 UI, 처음 정렬은 사고건수 내림차순.
data.json의 13개년 연도별 사고건수를 박스 13개로 세로 나열한 학습 데모 만들어줘. 연도별 합계를 미리 집계해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). 브라우저 기본 Intersection Observer API 사용 — 같은 폴더 js_scrollytelling.html의 Intersection Observer 패턴을 참조할 것. 박스가 화면에 들어오면 보라색으로 활성, 아래에 "현재 보이는 연도" 실시간 표시.
data.json으로 5단계 인라인 스크롤리텔링 만들어줘 (왼쪽 sticky 차트 + 오른쪽 5개 텍스트). 각 단계에 필요한 사전 집계(연도별 사고/사망, 사고유형 합계, 시도별 합계, 13년 누적 사망자 등)를 모두 미리 해 HTML 안에 데이터로 박아 넣은 단일 파일로 줘 (fetch 없이 더블클릭하면 바로 보이게). Scrollama + Chart.js 사용 — 같은 폴더 js_scrollytelling.html의 Scrollama 패턴을 참조할 것. 단계마다 차트 바뀌게:
- 13년 사고건수 라인차트
- 같은 데이터 막대로, 2020년만 빨간색 강조
- 사고유형 도넛
- 시도별 가로막대 상위 10
- 차트 대신 거대한 숫자 — 13년 누적 사망자 합계와 "다발지역에서만 X명, 하루 평균 Y명"
다듬을 때: "각 단계 글자 더 크게" / "차트 바뀔 때 부드럽게"
이 가이드의 5개 HTML 파일에서 사용하는 모든 라이브러리·플러그인·외부 데이터를 정리한 참고 목록입니다.
js_charts.html| 라이브러리 | 역할 | CDN |
|---|---|---|
| Chart.js | Bar, Line, Pie, Doughnut, Radar, Bubble, Scatter, Polar Area, Mixed, Treemap 등 기본 차트 전반 | https://cdn.jsdelivr.net/npm/chart.js |
js_more_charts.html| 라이브러리 | 역할 | CDN |
|---|---|---|
| D3.js v7 | Calendar Heatmap, Sunburst, Parallel Coordinates 등 커스텀 SVG 시각화 | https://cdn.jsdelivr.net/npm/d3@7 |
| d3-cloud | 워드클라우드 레이아웃 (D3 확장 플러그인) | https://cdn.jsdelivr.net/npm/d3-cloud/build/d3.layout.cloud.js |
| chartjs-chart-sankey | Sankey 다이어그램 (Chart.js 플러그인 — Chart.js 로드 후 삽입) | https://cdn.jsdelivr.net/npm/chartjs-chart-sankey |
| Plotly.js | Parallel Coordinates (대안 라이브러리) | https://cdn.plot.ly/plotly-latest.min.js |
| ApexCharts | Matrix Heatmap, Gauge·KPI 카드 (대안 라이브러리) | https://cdn.jsdelivr.net/npm/apexcharts |
js_network.html| 라이브러리 | 역할 | CDN |
|---|---|---|
| vis-network | 노드+엣지 기본 그래프, 양분 네트워크, 인터랙티브 조작, 의미연결망 | https://cdn.jsdelivr.net/npm/vis-network/standalone/umd/vis-network.min.js |
| D3.js v7 + d3-force | Force-Directed 물리 시뮬레이션 그래프 | https://cdn.jsdelivr.net/npm/d3@7 (d3-force 내장) |
| Cytoscape.js | 계층 Tree, 레이아웃 전환, 권역 계층 그래프 | https://cdn.jsdelivr.net/npm/cytoscape/dist/cytoscape.min.js |
| dagre | 방향성 비순환 그래프(DAG) 레이아웃 엔진 (cytoscape-dagre의 의존 라이브러리) | https://cdn.jsdelivr.net/npm/dagre/dist/dagre.min.js |
| cytoscape-dagre | Cytoscape.js용 Dagre 레이아웃 플러그인 (Cytoscape + dagre 로드 후 삽입) | https://cdn.jsdelivr.net/npm/cytoscape-dagre/cytoscape-dagre.js |
⚠️ 로드 순서 주의:
cytoscape.min.js→dagre.min.js→cytoscape-dagre.js순서를 반드시 지켜야 합니다.
js_map.html| 라이브러리 | 역할 | CDN |
|---|---|---|
| Leaflet.js | 인터랙티브 지도 기반 (기본 마커, 원형 마커, 코로플레스, 레이어 컨트롤) | https://cdn.jsdelivr.net/npm/leaflet/dist/leaflet.js |
| Leaflet CSS | Leaflet 기본 스타일 (JS와 함께 반드시 로드) | https://cdn.jsdelivr.net/npm/leaflet/dist/leaflet.css |
| Leaflet.markercluster | 12,780개 마커 자동 클러스터링 플러그인 | https://cdn.jsdelivr.net/npm/leaflet.markercluster/dist/leaflet.markercluster.js |
| MarkerCluster CSS | 클러스터 아이콘 스타일 (2개 파일 모두 필요) | MarkerCluster.css + MarkerCluster.Default.css |
| leaflet.heat | 사고 밀집도 히트맵 레이어 플러그인 | https://cdn.jsdelivr.net/npm/leaflet.heat/dist/leaflet-heat.js |
| skorea-provinces GeoJSON | 한국 시도 경계 폴리곤 데이터 (코로플레스용 외부 지리 데이터) | https://cdn.jsdelivr.net/gh/southkorea/southkorea-maps@master/kostat/2018/json/skorea-provinces-2018-geo.json |
js_scrollytelling.html| 라이브러리 | 역할 | CDN |
|---|---|---|
| Chart.js | 스크롤 단계마다 업데이트되는 차트 | https://cdn.jsdelivr.net/npm/chart.js |
| Scrollama | 스크롤 단계 감지·트리거 (데이터 저널리즘 표준 스크롤리텔링 라이브러리) | https://cdn.jsdelivr.net/npm/scrollama |
| Intersection Observer API | 스크롤 뷰포트 감지 — 별도 설치 불필요한 브라우저 내장 Web API | 내장 (CDN 불필요) |
| jQuery | DataTables.js의 의존 라이브러리 | https://code.jquery.com/jquery-3.7.0.min.js |
| DataTables.js | 정렬·검색·페이징 가능한 인터랙티브 표 | https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js |
| DataTables CSS | DataTables 기본 스타일 | https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css |
| 난이도 | 라이브러리 | 주요 용도 |
|---|---|---|
| ★☆☆ 쉬움 | Chart.js, ApexCharts, vis-network, Leaflet.js, DataTables.js | 기본 차트·지도·표 |
| ★★☆ 보통 | Plotly.js, Cytoscape.js, Scrollama, d3-cloud, chartjs-chart-sankey, Leaflet 플러그인들 | 특수 시각화·네트워크·스크롤 서사 |
| ★★★ 어려움 | D3.js (d3-force 포함) | 완전 커스텀 시각화 |
💡 초보자 학습 순서 추천: Chart.js → Leaflet → vis-network → D3.js 기초 → 플러그인 조합 → D3 심화