콘텐츠로 이동

데이터 관리

modernGraphTool에 표시할 측정 데이터(Phone)와 타겟 커브(Target)를 다루는 방법을 안내합니다.

데이터 목록은 data/phone_book.json으로 관리합니다. 경로를 따로 바꾸지 않았다면 측정 데이터 파일은 data/phones에, 타겟 커브 파일은 data/target 폴더에 들어갑니다.

dist/data 폴더는 다음과 같이 구성됩니다.

data/
├── phones/ # 측정 데이터 파일 (.txt) 저장 위치
│ ├── PhoneA L.txt
│ ├── PhoneA R.txt
│ └── PhoneB.txt
├── target/ # 타겟 커브 데이터 파일 (.txt) 저장 위치
│ ├── X Target.txt
│ └── Y Target.txt
└── phone_book.json # 측정 기기 목록 및 관련 데이터 정의 파일
  • phones 폴더 — 각 Phone의 주파수 응답 측정 파일(.txt)을 저장합니다. 파일 이름은 자유지만, phone_book.json에는 정확히 같은 이름을 적어야 합니다. 좌/우 채널이 별도 파일이라면 파일명 끝에 공백을 하나 두고 L, R을 붙여 구분합니다.
  • target 폴더 — 타겟 커브 파일(.txt)을 저장합니다. config.js의 INITIAL_TARGETS나 TARGET_MANIFEST에 적는 이름과 정확히 일치해야 합니다.
  • phone_book.json — 기기 목록에 표시될 제품 이름과 부가 정보(리뷰 링크, 가격 등)를 JSON 형식으로 정의합니다.

JSON(JavaScript Object Notation)은 데이터를 구조적으로 표현하는 텍스트 형식입니다. 몇 가지 기본 규칙만 알면 쉽게 읽고 고칠 수 있습니다.

  • 데이터는 이름(Key)과 값(Value)의 쌍으로 이루어지며, 이름은 항상 따옴표로 감싼 문자열입니다.
  • 값은 문자열(따옴표), 숫자(따옴표 없음), 불리언(true/false, 따옴표 없음), 배열([·]로 감싸고 쉼표로 구분), 또는 다른 객체({·}로 감쌈)가 될 수 있습니다.
  • 객체 안의 각 키-값 쌍은 쉼표(,)로 구분합니다. 마지막 쌍 뒤에는 쉼표를 붙이지 않습니다.
  • 배열 안의 각 요소도 쉼표(,)로 구분합니다. 마지막 요소 뒤에도 쉼표는 없습니다.

phone_book.json은 하나의 큰 배열([])로 시작해서 끝납니다. 그 안에 여러 브랜드 객체({})가 들어갑니다.

각 브랜드 객체는 name 키(예: “Sennheiser”, “Sony”)와 phones 키로 구성됩니다.

phones 키 안에는 해당 브랜드의 모델(Phone) 정보가 담깁니다. 모델 정보는 단순 문자열로도, 객체로도 정의할 수 있습니다.

[
{
"name": "Brand A",
"suffix": "(Audio)", // Optional: Suffix for the brand name
"phones": [
"ModelX_Simple", // Simple definition: Assumes files "ModelX_Simple L.txt" and "ModelX_Simple R.txt"
{
"name": "Model Y",
"file": "BrandA ModelY", // File name (without L/R and .txt)
"suffix": ["(Setting 1)", "(Setting 2)"], // Optional: Suffixes for different versions
"reviewLink": "https://example.com/review/modely", // Optional: Review link
"price": "$199", // Optional: Price (string)
"description": "Some description about Model Y" // Optional: Extra description
}
// ... more models for Brand A
]
},
{
"name": "Brand B",
"phones": [
// ... models for Brand B
]
}
// ... more brands
]
  • name (문자열, 필수) — 브랜드 이름.
  • suffix (문자열, 선택) — 브랜드 이름 뒤에 붙어 UI에 표시되는 접미사.
  • phones (배열, 필수) — 해당 브랜드의 모든 Phone 정보를 담는 배열. 각 모델은 단순 문자열 또는 상세 객체로 정의합니다.

phones 배열에는 다음 형태로 데이터를 넣을 수 있습니다.

단순 문자열(예: "ModelX")을 넣으면 화면에는 “ModelX”라고 표시되고, 데이터 파일은 ModelX L.txt, ModelX R.txt라고 가정합니다.

{
"name": "BrandSimple",
"phones": [
"ModelS1", // Loads `~/ModelS1 L.txt`, `~/ModelS1 R.txt`
"ModelS2" // Loads `~/ModelS2 L.txt`, `~/ModelS2 R.txt`
]
}

더 자세한 설정이 필요하다면 Phone을 다음 키를 가진 객체로 정의합니다.

  • name (문자열, 필수) — 화면에 표시될 Phone 모델 이름.
  • file (문자열, 필수) — 측정 데이터 파일의 실제 이름(L/R 접미사와 .txt 확장자 제외). 예를 들어 파일이 MyPhone L.txt, MyPhone R.txt라면 "MyPhone"으로 설정합니다.
  • suffix (문자열, 선택) — 선택 목록의 이름 뒤에 붙는 접미사. 실제 데이터 파일 이름에도 같은 접미사가 들어 있어야 합니다(예: MyPhone (Foam Tip) L.txt).
  • reviewScore (문자열, 선택) — 리뷰 점수. "A+", 0~5 사이 숫자("3") 등 자유롭게 표기.
  • reviewLink (문자열, 선택) — Phone 리뷰 URL.
  • shopLink (문자열, 선택) — 상점 또는 구매 페이지 URL.
  • price (문자열, 선택) — 가격(예: "$299", "€250"). 문자열이라 통화 기호가 다른 표기도 그대로 허용됩니다.
  • description (문자열, 선택) — Phone과 함께 표시할 자유 서술 설명. 일부 인라인 HTML 태그를 사용할 수 있습니다. 아래 서식 있는 설명 참고.
  • links (객체 배열, 선택) — 기기를 그래프에 올렸을 때 기본 리뷰 / 상점 링크 옆에 함께 표시할 추가 링크. 아래 커스텀 링크 참고.
{
"name": "BrandDetailed",
"phones": [
{
"name": "Model D1",
"file": "ModelD1_Data",
"suffix": "Rev.2",
"reviewScore": "A+",
"reviewLink": "https://example.com/review/d1",
"shopLink": "https://example.com/shop/d1",
"price": "$299"
}
]
}

description에는 인라인 HTML 태그를 일부 쓸 수 있어서, 설명 안에 링크나 강조를 넣을 수 있습니다.

{
"name": "Model D1",
"file": "ModelD1_Data",
"description": "동일 개체의 B&K5128 측정치는 <a href=\"https://other.example/?share=Brand%20Model%20D1\">여기</a>에서 볼 수 있습니다."
}

허용되는 태그: a, abbr, b, br, code, del, em, i, ins, kbd, mark, s, small, span, strong, sub, sup, u, wbr.

그 외의 내용은 화면에 그려지기 전에 모두 정리됩니다.

  • 모르는 태그는 태그만 제거되고 내용은 남습니다. <div>text</div>는 text로 표시되므로 내용이 조용히 사라지는 일은 없습니다.
  • <script>, <style>, <iframe> 등은 내용까지 통째로 제거됩니다.
  • 속성은 전부 제거됩니다. 예외는 <a>의 href / title, <abbr>·<span>의 title뿐입니다. onclick 같은 이벤트 핸들러와 style은 남지 않습니다.
  • 링크는 http, https, mailto, tel 또는 상대 경로여야 합니다. javascript: URL은 제거되고 링크 텍스트만 일반 텍스트로 남습니다.
  • 링크는 새 탭에서 열립니다. rel="external noopener noreferrer"가 자동으로 붙으므로 target을 직접 쓸 필요가 없습니다.
  • &는 그대로 써도 됩니다. B&K5128은 쓴 그대로 표시됩니다(&amp;로 써도 동작합니다).

닫지 않은 태그는 자동으로 닫히므로, 오타 하나가 목록 전체의 레이아웃을 망가뜨리지 않습니다. 설명은 기기 항목 버튼 안에 렌더링되기 때문에 인라인 태그만 허용되며, 블록 태그(<p>, <ul> 등)는 태그만 제거됩니다.

설명이 잘려 있을 때 마우스를 올리면 나오는 툴팁에는 태그를 제거한 평문이 표시됩니다.

shopLink에는 URL을 하나만 넣을 수 있습니다. 상점 두 곳, 제조사 페이지, 측정 노트처럼 가리킬 곳이 여러 개라면 links를 쓰세요. 각 항목은 label과 url을 가진 객체입니다.

{
"name": "Model D1",
"file": "ModelD1_Data",
"links": [
{ "label": "Amazon", "url": "https://amazon.example/d1" },
{ "label": "공식 스토어", "url": "https://brand.example/shop/d1" },
{ "label": "측정 노트", "url": "/data/notes/d1.html" }
]
}
  • label (문자열, 필수) — 링크 텍스트. 평문으로만 표시되며 태그는 제거됩니다.
  • url (문자열, 필수) — http, https, mailto, tel 또는 사이트 기준 상대 경로. 그 외에는 무시됩니다.

링크는 적어 둔 순서대로, 기본 리뷰 / 상점 링크 뒤에 표시되며 기기를 그래프에 올린 뒤에만 나타납니다. links는 shopLink를 대체하지 않으므로 둘 중 하나만 써도 되고 둘 다 써도 됩니다.

label이나 url이 없거나 쓸 수 없는 URL인 항목은 (브라우저 콘솔에 경고를 남기고) 건너뛰며, 나머지 링크는 정상적으로 표시됩니다.

Variations (여러 데이터 파일을 하나로 묶기)

섹션 제목: “Variations (여러 데이터 파일을 하나로 묶기)”

EQ 설정이나 이어팁에 따라 여러 버전의 측정값이 있다면, 이들을 하나의 이름으로 묶어 UI에 보여줄 수 있습니다.

{
"name": "BrandVariations",
"phones": [
{
"name": "Model V1", // Base name for variations
"file": ["ModelV1_Foam", "ModelV1_Silicone", "ModelV1_Hybrid"],
"suffix": ["(Foam Tip)", "(Silicone Tip)", "(Hybrid Tip)"],
"price": "$150" // Applies to all V1 variations
}
]
}
  • name, file, suffix 배열을 함께 사용할 때
    • name (문자열 배열, 필수) — 모든 Variation의 기본 이름이 되는 문자열 배열.
    • file (문자열 배열, 필수) — 각 Variation의 기본 파일 이름 배열.
    • suffix (문자열 배열, 필수) — 각 파일에 대응하는 접미사 배열. UI에는 brand_name + name + suffix[i] 형태로 표시됩니다.
    • 위 예시는 “BrandVariations Model V1 (Foam Tip)”, “BrandVariations Model V1 (Silicone Tip)” 같은 항목으로 만들어집니다.
    • file과 suffix 배열 길이는 가급적 같아야 합니다. 다른 선택 키(reviewLink, price 등)를 추가하면 모든 Variation에 똑같이 적용됩니다.
{
"name": "BrandPrefix",
"phones": [
{
"name": "Model P1", // Base display name
"file": ["BrandP ModelP1 (Foam Tip)", "BrandP ModelP1 (Silicone Tip)"], // Actual files would be: BrandP ModelP1 (Foam Tip) L.txt, BrandP ModelP1 (Silicone Tip) L.txt, etc.
"prefix": "BrandP ModelP1", // Common file prefix
"description": "Uses different eartips"
}
]
}
  • prefix로 공통 파일 접두사 사용하기

Variation 파일들이 같은 접두사를 공유하지만 뒷부분이 명확히 구분된다면 prefix를 쓸 수 있습니다.

  • name (문자열 배열, 필수) — 모든 Variation의 기본 이름이 되는 문자열 배열.
  • file (문자열 배열, 필수) — 각 Variation의 기본 파일 이름 배열.
  • prefix (문자열, 필수) — 모든 파일에 공통으로 붙는 접두사.
  • UI에는 brand_name + name + suffix[i] 형태로 표시됩니다(예: “BrandPrefix Model P1 (Foam Tip)”, “BrandPrefix Model P1 (Silicone Tip)”).
  • 여러 이어팁이나 이어패드를 조합한 측정, 또는 착용 위치별 측정처럼 같은 기기에 속한 데이터를 한데 묶을 때 편리합니다.

샘플 세트는 한 variant를 여러 번 측정한 것입니다. 같은 착용 상태의 반복 측정, 착용 위치를 조금씩 바꾼 스윕, 이어패드별 측정, 여러 장비에서 측정한 같은 기기 등이 여기에 해당합니다. modernGraphTool은 세트를 세 가지 방식으로 그릴 수 있고, 이들은 자유롭게 조합됩니다.

토큰그려지는 것
avg모든 측정의 평균 곡선 하나 — 기기의 “대표” 선입니다.
curves각 측정을 개별 곡선으로. UI에서 하나씩 켜고 끌 수 있습니다.
fill모든 측정을 감싸는 최소/최대 음영 밴드 — 편차 포락선입니다.

샘플 세트는 variants 배열 안에서 variant별로 선언합니다.

{
"name": ["HD 600"],
"variants": [
{ "suffix": "Stock", "file": "HD600 Stock" },
{ "suffix": "Modded", "file": "HD600 Mod", "samples": 5 },
{
"suffix": "Leather Pad",
"file": "HD600 Leather",
"description": "Dekoni Elite Hybrid pads, reseated between runs",
"samples": {
"count": 5,
"labels": ["Center", "Front", "Back", "Up", "Down"],
"display": ["avg", "fill"],
"description": "(Positional Variance)"
}
},
{
"suffix": "Suede Pad",
"samples": {
"files": ["Suede Center", "Suede Front", "Suede Back"],
"labels": ["Center", "Front", "Back"],
"display": ["fill", "curves"]
}
}
]
}

variants의 각 항목이 받는 키:

  • suffix (문자열, 선택) — 기기 선택기 드롭다운에 표시되는 variant 라벨.
  • file (문자열, 선택) — 대표 L/R 쌍의 기본 파일 이름 — {file} L.txt / {file} R.txt. samples.files로 측정 파일을 직접 나열한다면 생략해도 됩니다.
  • description (문자열, 선택) — variant 자체에 대한 일반 텍스트 메모로, variant 선택기에서 suffix 아래에 표시됩니다(예: "Foam tips, deep insertion"). variant를 설명하는 내용은 여기에 쓰세요. 그래프에는 나타나지 않으며, 샘플 세트가 없는 일반 variant에도 쓸 수 있습니다.
  • samples (숫자 또는 객체, 선택) — 샘플 세트. 숫자만 쓰면 { "count": n }의 축약형입니다.

samples를 객체로 쓸 때의 키:

  • count (숫자) — 측정 횟수. {file} L1.txt…L{count}.txt와 대응하는 R 파일을 로드합니다. CrinGraph의 num_samples 사이트가 이미 쓰고 있는 파일 배치입니다.
  • files (문자열 배열) — 측정별 기본 파일 이름. {name} L.txt와 {name} R.txt를 로드합니다. count와 함께 쓰지 말고 둘 중 하나만 쓰세요.
  • labels (문자열 배열, 선택) — 측정별 표시 이름. 샘플 선택기와 그래프 라벨에 나타납니다(예: HD 600 Leather Pad (Center, R)). 생략하면 files 값이, count 형식에서는 “Sample 1”, “Sample 2”… 가 쓰입니다.
  • display (문자열 배열, 선택) — avg, curves, fill의 조합. 초기 토글 상태를 정할 뿐이고 사용자는 여전히 곡선별로 바꿀 수 있습니다. 생략하면 config.js의 SAMPLES.DEFAULT_DISPLAY를 따릅니다.
  • description (문자열, 선택) — 무엇이 달라지는지 나타내는 세트의 짧은 캡션입니다(예: "(Fit Position)", "(Rig Variance)", "(Insertion Depth)"). 기기 이름 옆에 표시되고, 편차 음영이 켜져 있으면 그래프 라벨에도 붙으므로 짧게 쓰세요.

count와 files의 차이는 파일 이름 규칙일 뿐이며 기능 차이가 아닙니다. 라벨, 음영, 개별 곡선은 어느 쪽에서도 똑같이 동작합니다.

variants 배열 없이, phone의 모든 file[] variant에 같은 측정 횟수를 한 번에 지정할 수 있습니다.

{ "name": ["Multi Sample"], "file": ["Multi Sample"], "samples": 3 }

"variants": [{ "file": "Multi Sample", "samples": 3 }]과 동등합니다. 이 형식은 계속 지원됩니다. phone 항목의 나머지 부분과 마찬가지로 CrinGraph 호환 구조를 공유하므로, 다른 도구용으로 작성한 phone_book.json도 그대로 동작합니다. 다만 한계가 있고, 그 한계가 variants가 존재하는 이유입니다. phone의 모든 variant가 같은 측정 횟수를 공유해야 하고, 측정별 라벨도 음영도 쓸 수 없습니다.

hptfs[]는 편차 세트를 위해 modernGraphTool이 자체적으로 만든 키였고, 이제 variants[]가 그 역할을 모두 대신합니다. 이 키는 사용 중단(deprecated)되었으며 향후 릴리스에서 제거될 예정입니다. 지금은 계속 읽히므로 업그레이드하는 순간 깨지지는 않지만, 새로 hptfs[] 항목을 작성하지 말고 편한 시점에 phone book을 변환해 두세요.

samples: N과 달리 CrinGraph 생태계의 다른 도구는 hptfs[]를 읽지 않으므로, 제거해도 호환성에 손해가 없습니다.

{
"name": ["HpTF Multi Pad"],
"hptfs": [
{
"suffix": "Leather Pad",
"files": ["Leather Center", "Leather Front", "Leather Back"],
"labels": ["Center", "Front", "Back"],
"description": "(Leather Pad Variance)",
"fillOnly": false
}
]
}

위 항목은 samples.files와 display: ["avg", "fill"]을 가진 variants 항목이 됩니다. fillOnly가 false이면 여기에 "curves"가 추가됩니다.

{
"name": ["HpTF Multi Pad"],
"variants": [
{
"suffix": "Leather Pad",
"samples": {
"files": ["Leather Center", "Leather Front", "Leather Back"],
"labels": ["Center", "Front", "Back"],
"display": ["avg", "fill", "curves"],
"description": "(Leather Pad Variance)"
}
}
]
}

config.js의 MULTI_SAMPLE, HPTF 섹션도 함께 사용 중단되었습니다. 대체 키는 SAMPLES를 참고하세요.

  1. 새 Phone 측정 파일(.txt)을 data/phones 폴더에 복사합니다.
  2. 텍스트 에디터로 phone_book.json을 엽니다.
  3. JSON 문법에 맞춰 새 Phone 정보를 추가하거나 기존 정보를 수정합니다.
  4. phone_book.json을 저장합니다.
  5. 웹 페이지를 새로고침해서 변경 사항이 잘 반영됐는지 확인합니다.