Customizing the Page
You can change the initial display content, design theme, etc., of the modernGraphTool page to suit your needs.
You will primarily personalize the page by editing index.html, theme.css, and config.js — in that order, from simplest to most involved.
Changing Page Metadata (index.html)
Section titled “Changing Page Metadata (index.html)”The index.html file defines the basic HTML structure and metadata for modernGraphTool — the page title, description, preview image, favicon, and other <head> fields picked up by browsers and social media scrapers.
<title>modernGraphTool</title><meta name="title" content="modernGraphTool" /><meta property="og:title" content="modernGraphTool" />Sets the page title.
DESCRIPTION
Section titled “DESCRIPTION”<meta name="description" content="View and compare frequency response graphs for earphones/headphones."/><meta property="og:description" content="View and compare frequency response graphs for earphones/headphones."/>Sets the page description.
KEYWORDS
Section titled “KEYWORDS”Sets the page keywords (used for search engine optimization).
<meta name="keywords" content="earphone,headphone,IEM,frequency response,graph,comparison,measurement,FR"/>URL / LINK
Section titled “URL / LINK”Sets the page URL and link.
<meta property="og:url" content="/?" /> <link rel="canonical" href="/?" />Sets the page preview image.
<meta property="og:image" content="/preview.png" />FAVICON
Section titled “FAVICON”Sets the page favicon (tab icon).
<link rel="icon" type="image/png" sizes="32x32" href="/favicon.png" />Customizing Page Styles (theme.css)
Section titled “Customizing Page Styles (theme.css)”The theme.css file contains CSS custom properties (variables) that drive modernGraphTool’s visual theme — both the D3.js frequency response graph and the surrounding UI chrome. All variables switch automatically between light and dark mode.
Graph Variables
Section titled “Graph Variables”These drive the SVG rendering where Tailwind classes cannot be used:
:root { --color-graph-bg: transparent; /* Graph background */ --color-graph-watermark-opacity: 0.08; /* Watermark opacity */ --color-graph-grid-major: rgba(0, 0, 0, 0.15); /* Major grid lines */ --color-graph-grid-minor: rgba(0, 0, 0, 0.06); /* Minor grid lines */ --color-graph-axis-label: rgba(0, 0, 0, 0.6); /* Axis labels (Hz, dB) */ --color-graph-grid-text: rgba(0, 0, 0, 0.5); /* Grid value labels */ --color-graph-baseline: rgba(0, 0, 0, 0.25); /* Baseline indicator */}
.dark { --color-graph-grid-major: rgba(255, 255, 255, 0.15); --color-graph-grid-minor: rgba(255, 255, 255, 0.06); --color-graph-axis-label: rgba(255, 255, 255, 0.6); --color-graph-grid-text: rgba(255, 255, 255, 0.5); --color-graph-baseline: rgba(255, 255, 255, 0.25);}Base UI Variables
Section titled “Base UI Variables”The UI chrome — backgrounds, text, buttons, accents — is driven by a DaisyUI-style base palette. Every variable has a light (:root) and dark (.dark) value:
:root { --color-base-100: oklch(98% 0.003 247.858); /* Background */ --color-base-200: oklch(96% 0.007 247.896); /* Elevated surface */ --color-base-300: oklch(92% 0.013 255.508); /* Highest surface */ --color-base-content: oklch(20% 0.042 265.755); /* Default text */ --color-primary: oklch(59% 0.145 163.225); /* Primary accent */ --color-primary-content: oklch(97% 0.021 166.113); --color-secondary: oklch(60% 0.126 221.723); --color-secondary-content: oklch(98% 0.019 200.873); --color-accent: oklch(44% 0.017 285.786); --color-accent-content: oklch(98% 0 0); --color-neutral: oklch(44% 0.043 257.281); --color-neutral-content: oklch(98% 0.003 247.858); --color-info: oklch(68% 0.169 237.323); --color-info-content: oklch(97% 0.013 236.62); --color-success: oklch(76% 0.233 130.85); --color-success-content: oklch(98% 0.031 120.757); --color-warning: oklch(79% 0.184 86.047); --color-warning-content: oklch(98% 0.026 102.212); --color-error: oklch(64% 0.246 16.439); --color-error-content: oklch(96% 0.015 12.422);}Each --color-* role has a matching --color-*-content variable that sets the foreground (text/icon) color rendered on top of it, so contrast is preserved automatically when you change the base.
Changing Basic Settings (config.js)
Section titled “Changing Basic Settings (config.js)”The config.js file contains various settings related to the operation of modernGraphTool. You can open this file with a text editor and modify the necessary parts.
INITIAL_PHONES
Section titled “INITIAL_PHONES”// Brand : Sennheiser// Model : IE200// Suffix : (Foam Tip)INITIAL_PHONES: ["Sennheiser IE200 (Foam Tip)"],
// You can add multiple phones to the list.INITIAL_PHONES: ["Sennheiser IE200", "Sony IER-Z1R"],Specifies the names of the Phone (measurement data) to be displayed by default when the page loads, in array format.
- You must use the brand + device name defined in
phone_book.json.- The device name to be displayed can include a suffix. If no suffix is specified, the first file will be displayed by default.
- You can choose to display multiple Phones (measurement data).
INITIAL_TARGETS
Section titled “INITIAL_TARGETS”INITIAL_TARGETS: ["Harman IE 2019v2 Target"],
// You can add multiple targets to the list.INITIAL_TARGETS: ["Harman IE 2019v2 Target", "KEMAR DF Target"],Specifies the names of the Target (target curve) to be displayed by default when the page loads, in array format.
- Use the file names (excluding extension) in the
data/targetfolder.
INITIAL_PANEL
Section titled “INITIAL_PANEL”INITIAL_PANEL: "graph",Specifies the panel to be displayed by default when the page loads.
- You can choose from
phone,graph,equalizer, ormisc.
NORMALIZATION
Section titled “NORMALIZATION”NORMALIZATION: { TYPE: "Hz", HZ_VALUE: 500,},Specifies the default settings for graph normalization.
Sets the normalization method.
- You can choose between
Hz (based on a specific frequency)orAvg (based on the average of 300~3000Hz).
HZ_VALUE
Section titled “HZ_VALUE”If TYPE is set to ‘Hz’, the entered number will be used as the default frequency.
VISUALIZATION
Section titled “VISUALIZATION”VISUALIZATION: { ASPECT_RATIO: "16:9", DEFAULT_Y_SCALE: 60, LABEL: { LOCATION: "BOTTOM_LEFT", POSITION: { LEFT: "0", RIGHT: "0", UP: "0", DOWN: "0", }, TEXT_SIZE: "20px", TEXT_WEIGHT: "600", }, BASELINE_LABEL: { LOCATION: "TOP_LEFT", POSITION: { LEFT: "0", RIGHT: "0", UP: "0", DOWN: "0", }, TEXT_SIZE: "15px", TEXT_WEIGHT: "500", }, RIG_DESCRIPTION: "Measured with IEC 60318-4 (711)",},Specifies settings related to graph visualization.
ASPECT_RATIO
Section titled “ASPECT_RATIO”Sets the aspect ratio of the frequency response graph.
"16:9"— Standard widescreen (800×450 viewBox)."CrinGraph"— Matches CrinGraph’s proportions (800×346 viewBox).
DEFAULT_Y_SCALE
Section titled “DEFAULT_Y_SCALE”Sets the default display range for the Y-axis (dB).
- You can choose from 30, 40, 50, 60, or 80.
Sets the position, size, weight, etc., of the Phone/Target name labels displayed on the graph. Optional — the defaults below produce the layout modernGraphTool ships with, so set this only to move the labels.
LOCATION: Name label position — defaultBOTTOM_LEFT- Choose from
BOTTOM_LEFT,BOTTOM_RIGHT,TOP_LEFT,TOP_RIGHT.
- Choose from
POSITION: Fine-tune name label position — defaultsRIGHT: "44",UP: "43",LEFT: "0",DOWN: "0"- Applied as
x + RIGHT - LEFTandy + DOWN - UP, from whichever cornerLOCATIONanchors to. All four always apply — they are not specific to the chosen corner.
- Applied as
TEXT_SIZE: Name label size (in px) — default"14px".TEXT_WEIGHT: Name label weight (choose a multiple of 100 from 100 to 900) — default"600".
BASELINE_LABEL
Section titled “BASELINE_LABEL”Sets the position, size, weight, etc., of the baseline label displayed on the graph when a baseline (compensation) target is active. Also optional.
- Same options as
LABELabove, with defaultsLOCATION: "TOP_LEFT",POSITION: { RIGHT: "44", DOWN: "39", LEFT: "0", UP: "0" },TEXT_SIZE: "14px",TEXT_WEIGHT: "500".
RIG_DESCRIPTION
Section titled “RIG_DESCRIPTION”Enter the description of the measurement equipment to be displayed in the upper right corner of the graph.
INTERFACE
Section titled “INTERFACE”INTERFACE: { PREFERRED_DARK_MODE_THEME: "light", PANEL_POSITION: "left", ALLOW_REMOVING_PHONE_FROM_SELECTOR: true, SWITCH_PHONE_PANEL_ON_BRAND_CLICK: true, TARGET: { ALLOW_MULTIPLE_LINE_PER_TYPE: true, OMIT_TARGET_SUFFIX: true, COLLAPSE_TARGET_LIST_ON_INITIAL: true, }, HIDE_DEV_DONATE_BUTTON: false,},Specifies settings related to the user interface.
PREFERRED_DARK_MODE_THEME
Section titled “PREFERRED_DARK_MODE_THEME”Specifies the dark mode setting.
- Choose from
light,dark,system.
PANEL_POSITION
Section titled “PANEL_POSITION”Sets which side the menu + panel column appears on in the desktop UI. The mobile UI is unaffected.
- Choose
left(default — controls on the left, graph on the right; matches the legacy CrinGraph layout) orright(graph on the left, controls on the right).
ALLOW_REMOVING_PHONE_FROM_SELECTOR
Section titled “ALLOW_REMOVING_PHONE_FROM_SELECTOR”Sets whether to remove an already added item from the graph when reselected in the Phone (measurement data) selector.
- Choose
trueorfalse.
SWITCH_PHONE_PANEL_ON_BRAND_CLICK
Section titled “SWITCH_PHONE_PANEL_ON_BRAND_CLICK”Sets whether to automatically switch to the phone list when a brand button is clicked in the mobile UI.
- Choose
trueorfalse.
TARGET
Section titled “TARGET”Specifies settings related to the Target selector. ##### ALLOW_MULTIPLE_LINE_PER_TYPE
Sets whether to display the Target list in multiple lines per type. - Choose true or false. ##### OMIT_TARGET_SUFFIX
Sets whether to omit the ‘Target’ suffix for each target item. - Choose true or false. ##### COLLAPSE_TARGET_LIST_ON_INITIAL
Sets whether the target list is collapsed on initial page load. - Choose true or false.
HIDE_DEV_DONATE_BUTTON
Section titled “HIDE_DEV_DONATE_BUTTON”Sets whether to hide the ‘Donate’ button.
- Choose
trueorfalse.
URL: { AUTO_UPDATE_URL: true, COMPRESS_URL: true,},AUTO_UPDATE_URL: Sets whether to automatically update the URL according to the selected device and target.- Choose
trueorfalse.
- Choose
COMPRESS_URL: Sets whether to compress the URL.- When activated, the URL is compressed using the base62 algorithm.
- Choose
trueorfalse.
RANKING
Section titled “RANKING”Controls the rank indicator on an expanded row in the device selector. It has two independent halves, and most deploys only ever want the first:
- Link the rank somewhere.
URLalone turns thereviewScorealready in yourphone_book.jsoninto a link — to a spreadsheet, a review site, a squigRanking page, anything. No sheet is fetched and nothing about the score changes. - Read the ranks from a published CSV.
CONFIG_URLorSOURCEmakes a spreadsheet the source of truth for ranks, so editing the sheet updates the tool without touchingphone_book.json. Opt-in, and only this half talks to the network.
// The whole feature is optional — omitting RANKING keeps today's behavior:// the phone_book.json score renders as plain text with no link.
// 1. Link only. Works with any ranking page, spreadsheet or blog:RANKING: { URL: "https://docs.google.com/spreadsheets/.../pubhtml", // no placeholders → used verbatim},
// 2. A squigRanking page on the same deploy, with ranks read from its sheet:RANKING: { URL: "/ranking/?type={type}#{slug}", TYPE: "earphone", CONFIG_URL: "/ranking/ranking-config.js",},
// 3. A plain published CSV, with no squigRanking page involved:RANKING: { URL: "https://reviews.example.com/#{slug}", SOURCE: { CSV_URL: "https://docs.google.com/spreadsheets/d/e/.../pub?output=csv", RANK_COLUMN: "Rank", SCALE: [ { value: "S", color: "#6c63ff" }, { value: "A", color: "#00bfff" }, { value: "B", color: "#8bc34a" }, ], },},| Option | What it does |
|---|---|
URL | Link template for the rank indicator. Empty or unset leaves the rank display-only. |
TYPE | Which squigRanking types key this deploy measures (earphone, headphone, …). Picks the sheet, and fills {type}. Default earphone. |
CONFIG_URL | A squigRanking ranking-config.js. Read for the sheet URL, the rank column and its grade scale. |
SOURCE | A published CSV declared inline instead. Ignored when CONFIG_URL resolves. |
DISPLAY | auto (default), badge, stars or text. See below. |
MATCH | strict (default) or loose. See below. |
CACHE_TTL | Seconds a fetched sheet is reused before it is read again. Default 900 (15 minutes). |
Linking
Section titled “Linking”URL is a template. The following placeholders are substituted per row and URL-encoded (except {slug}, which keeps - readable):
| Placeholder | Expands to |
|---|---|
{brand} | The device’s brand |
{model} | The device’s model |
{slug} | {brand}-{model} lowercased, whitespace → - (matches squigRanking’s deepLink slug format) |
{fullName} | {brand} {model} joined |
{type} | The TYPE value |
If the template contains no placeholders (e.g. a Google Sheet URL), it is used verbatim — no slug or query string is appended.
Reading ranks from a sheet
Section titled “Reading ranks from a sheet”Set either CONFIG_URL or SOURCE:
CONFIG_URLpoints at a squigRanking deploy’sranking-config.js. It is loaded as a plain<script>, exactly as the ranking page loads it, and read for the sheet URL, the rank column, itsscaleand the card anchor format. Your grades stay defined in one place, and recoloring or renaming one on the ranking page updates the device list too. Only the keys listed above are read — anything else in that config is ignored, including aconfigVersionnewer than this tool knows about.SOURCEdescribes a CSV directly, for deploys with no ranking page.CSV_URLis required;RANK_COLUMN,BRAND_COLUMNandMODEL_COLUMNdefault toRank,BrandandModel, andSCALEis an ordered list of{ value, color, textColor, label, score }steps.ROW_FILTER: { FIELD, VALUES }keeps only matching rows, for one sheet shared between an earphone and a headphone deploy.
A few behaviors worth knowing:
- A device with no matching row keeps its
phone_book.jsonscore. Turning this on can only add ranks, never remove ones that already showed. A blank rank cell counts as no row. - A sheet that fails to load changes nothing — the list renders from
phone_book.jsonas if the feature were off, and the reason is logged to the browser console for you (a 404, or a CSV served without CORS headers, are the usual causes). - The sheet is re-read, not snapshotted. After
CACHE_TTLseconds, the next time a visitor opens the device list the sheet is fetched again, so an edited grade appears without a redeploy. Note that Google Sheets caches its own published CSV for a few minutes on top of this. - The link points at the row’s own card. When a row matched,
{slug}is built from the sheet’s spelling of the device rather than the phone book’s, so the deep link lands on the right card even where the two files spell a device differently.
DISPLAY
Section titled “DISPLAY”| Value | Renders |
|---|---|
auto | A colored badge when the scale describes the value, the 0–5 star row for a bare number, plain text otherwise. Default. |
badge | Always a badge. Values outside the scale get the neutral theme colors. |
stars | Always the star row, using the scale’s score for the step. Falls back to text for values with no number behind them. |
text | Always plain text. |
Badge text color is picked automatically for contrast against the scale’s color unless the scale sets textColor explicitly.
Sheet rows are matched to devices by brand and model, since neither file carries an id for the other.
strict(default) accepts an exact match, before and after case, spacing and punctuation are normalized — soTrue-Ear/Projekt.Wenstill matchesTrueEar/Projekt Wen.looseadditionally accepts partial names, which matches more devices and also mismatches more of them:Blessing 2will match aBlessing 2 Duskrow and silently show its grade.
Strict is the default deliberately — a device showing no rank is a visible gap you can fix in the sheet, while a device showing someone else’s rank looks entirely normal.
CDN_MODE
Section titled “CDN_MODE”CDN_MODE: { MAJOR_VERSION: 2, // BASE: "https://cdn.jsdelivr.net/gh/potatosalad775/modernGraphTool@cdn", // BASE_PATH: "/headphones", // VERSIONS_URL: "https://raw.githubusercontent.com/potatosalad775/modernGraphTool/cdn/versions.json",},Configures CDN deployment settings. Only used when deploying with cdn-index.html — leave this section commented out for standard dist/ deployments.
MAJOR_VERSION: Pins the app to a specific major version (e.g.,2means auto-update within v2.x.x).BASE: Custom CDN base URL. Only change this if you’re hosting the CDN assets yourself (advanced use).BASE_PATH: Deployment subpath (e.g."/headphones"), with no trailing slash. Required for any deployment not at the (sub)domain root. For a site atexample.com/headphones/orusername.squig.link/headphones/, setBASE_PATH: "/headphones". Only leave this unset if your site is served at the root of its (sub)domain — e.g.example.com/orusername.squig.link/. Without it, share-link deep routes will 404 even though the home page loads fine. For the full explanation of why this is effectively always required, see the CDN deployment guide.VERSIONS_URL: Full URL toversions.json. By default, the loader derives araw.githubusercontent.comURL fromBASEand fetchesversions.jsondirectly from GitHub — not through jsDelivr. This is intentional: jsDelivr’s edge cache can pin staleversions.jsonresponses for hours, which delays new releases from reaching users.versions.jsonis the one file where that matters, so the loader sidesteps it. Only overrideVERSIONS_URLif you host your own fork of thecdnbranch or serve from a non-GitHub origin.
LANGUAGE
Section titled “LANGUAGE”LANGUAGE: { LANGUAGE_LIST: [ ["en", "English"], ["ko", "한국어"] ], ENABLE_I18N: true, ENABLE_SYSTEM_LANG_DETECTION: true,},LANGUAGE_LIST: Sets the list of available languages.- Add each language in the format
["language_code", "language_name"].
- Add each language in the format
ENABLE_I18N: Sets whether to enable multilingual support.- If disabled, the language selection UI is removed, and only English is displayed.
- Choose
trueorfalse.
ENABLE_SYSTEM_LANG_DETECTION: Sets whether to detect the user’s system language automatically.- Choose
trueorfalse.
- Choose
PATH: { PHONE_MEASUREMENT: "./data/phones", TARGET_MEASUREMENT: "./data/target", PHONE_BOOK: "./data/phone_book.json",},PHONE_MEASUREMENT: Sets the folder path where Phone (measurement data) files are stored.TARGET_MEASUREMENT: Sets the folder path where Target (target curve) files are stored.PHONE_BOOK: Sets the file path forphone_book.json, which records Phone (measurement data) information.
WATERMARK
Section titled “WATERMARK”WATERMARK: [ { TYPE: "TEXT", CONTENT: "© 2025 modernGraphTool", LOCATION: "BOTTOM_RIGHT", SIZE: "15px", FONT_FAMILY: "sans-serif", FONT_WEIGHT: "600", COLOR: "#000000", OPACITY: "0.4", }, // You can even put multiple TEXT or IMAGE in Array. // Randomly picked content will be rendered on every load. { TYPE: "IMAGE", SIZE: "50px", LOCATION: "TOP_LEFT", POSITION: {UP: "20", DOWN: "0", LEFT: "0", RIGHT: "10"}, OPACITY: "0.2", CONTENT: [ "./assets/images/icon_1.png", "./assets/images/icon_2.png", "./assets/images/icon_3.png", ] }],Sets the watermark to be displayed on the graph.
- Multiple watermarks can be displayed simultaneously. Each watermark is distinguished by a
{}object. - modernGraphTool supports two types of watermarks:
TEXTandIMAGE.- Specify the watermark type with the
TYPEfield within the object.
- Specify the watermark type with the
TYPE: Specifies the watermark type. - Set toTEXT. -CONTENT: Sets the text to be displayed in the watermark. - Multiple strings can be entered in array format (enclosed in[]). - If 2 or more strings are specified, a randomly selected string will be displayed on initial load. -LOCATION: Sets the watermark position. - Choose fromTOP_LEFT,TOP_RIGHT,BOTTOM_LEFT,BOTTOM_RIGHT. -SIZE: Sets the watermark size (in px). -FONT_FAMILY: Sets the watermark font. -FONT_WEIGHT: Sets the watermark font weight (a multiple of 100 from 100 to 900). -COLOR: Sets the watermark color (HEX code). -OPACITY: Sets the watermark opacity (0 to 1).
TYPE: Specifies the watermark type. - Set toIMAGE. -CONTENT: Sets the image file path to be displayed in the watermark. - Multiple image file paths can be entered in array format (enclosed in[]). - If 2 or more image paths are specified, a randomly selected image will be displayed on initial load. -LOCATION: Sets the watermark position. - Choose fromTOP_LEFT,TOP_RIGHT,BOTTOM_LEFT,BOTTOM_RIGHT. -SIZE: Sets the watermark size (in px). -POSITION: Fine-tunes the watermark position. - Set the top, bottom, left, and right positions of the watermark with theUP,DOWN,LEFT,RIGHTfields (in px). -OPACITY: Sets the watermark opacity (0 to 1).
TARGET_MANIFEST
Section titled “TARGET_MANIFEST”TARGET_MANIFEST: [ { type:"Harman", files:["Harman IE 2019v2","Harman IE 2017v2"] }, { type:"Neutral", files:["KEMAR DF (KB006x)","ISO 11904-2 DF","IEF Neutral 2023"] }, { type:"Reviewer", files:["Banbeucmas","HBB","Precogvision","Super 22 Adjusted"] }, { type:"Preference", files:["AutoEQ","Rtings","Sonarworks"] }, { type:"Δ", files:["Universal ∆"] }],Defines how targets displayed in the Target selector are grouped and sorted.
- The
typefield defines the name of the target group. - The
filesfield specifies the file names of the targets belonging to that group in array format.
SAMPLES
Section titled “SAMPLES”SAMPLES: { DEFAULT_COUNT: 1, DEFAULT_DISPLAY: ["avg"], FILL_OPACITY: 0.3,},Site-wide defaults for sample sets — variants measured more than once (repeat
runs, seating positions, one measurement per ear pad). See
Sample Sets for the phone_book.json side.
DEFAULT_COUNT: How many runs a variant has when it declares nosamplesof its own. Leave at1unless every device in your database is measured the same number of times — then set it once here instead of on every entry.DEFAULT_DISPLAY: How a sample set is drawn when it declares nodisplay. Any combination of:"avg"— the averaged curve across every run."curves"— each run as its own toggleable curve."fill"— a shaded min/max band across the runs.["avg", "fill"]gives an averaged line with a variance band around it.
FILL_OPACITY: Opacity of the fill band (0 to 1).
TRACE_STYLING
Section titled “TRACE_STYLING”TRACE_STYLING: { PHONE_TRACE_THICKNESS: 2, TARGET_TRACE_THICKNESS: 1, CURVE_COLOR_PALETTE: [ "#0072B2", "#E69F00", "#009E73", "#CC79A7", "#56B4E9", "#D55E00", "#F0E442", "#000000", ], CURVE_COLOR_PALETTE_RANDOMIZE: false, TARGET_TRACE_DASH: [{ name: "KEMAR DF (KB006x)", dash: "10 10" }],},Sets the thickness, dash style, color palette, etc., of graph lines. You can also specify different line styles for specific targets.
PHONE_TRACE_THICKNESS: Sets the thickness of Phone (measurement data) graph lines (in px).TARGET_TRACE_THICKNESS: Sets the thickness of Target (target curve) graph lines (in px).CURVE_COLOR_PALETTE: Curated palette consumed in order when assigning a color to a newly added curve.- Accepts any CSS color string (
#hex,oklch(...),hsl(...),rgb(...)). - Once exhausted (or every preset is too close to a color the user already manually picked), modernGraphTool falls back to OKLCH-based generation that picks the next color farthest in perceptual distance from every color already on the graph.
- Leave empty or omit to use the built-in Okabe-Ito default (8 colorblind-safe colors).
- Accepts any CSS color string (
CURVE_COLOR_PALETTE_RANDOMIZE: Whentrue,CURVE_COLOR_PALETTEis shuffled once per page load so each session starts from a different color.- The shuffled order stays stable within the session, so add / undo / redo remain consistent.
- Has no effect when
CURVE_COLOR_PALETTEis empty or omitted. - Defaults to
false.
TARGET_TRACE_DASH: Sets the line style for a specific target.- The
namefield specifies the target’s name. - The
dashfield sets the target’s line style.- Accepts values according to the ‘stroke-dasharray’ attribute. For a detailed explanation, refer to the MDN documentation.
- Setting to
0 1will not display the line. - Setting to
nullwill display the line as solid.
- The
TOPBAR
Section titled “TOPBAR”TOPBAR: { TITLE: { //TYPE: "TEXT", CONTENT: "modernGraphTool", //TYPE: "IMAGE", CONTENT: "./assets/images/sample.jpg", TYPE: "HTML", CONTENT: "<h2>modernGraphTool</h2>", }, LINK_LIST: [ { TITLE: "Home", URL: "/" }, { TITLE: "Docs", URL: "https://example.com/docs" }, ],},Sets the title and link list for the page’s top bar.
TITLE: Sets the title for the page’s top bar.TYPE: Specifies the title type.- Set to
TEXTto display a text-formatted title. - Set to
IMAGEto display an image-formatted title. - Set to
HTMLto display an HTML-formatted title.
- Set to
CONTENT: Sets the title content.- If
TYPEisTEXT, sets a text-formatted title. - If
TYPEisIMAGE, sets an image file path. - If
TYPEisHTML, sets an HTML-formatted title.
- If
LINK_LIST: Sets the link list for the page’s top bar.- The
TITLEfield specifies the link’s title. - The
URLfield specifies the link’s URL. - You must include
http(s)://for external URLs.
- The
PREFERENCE_BOUND
Section titled “PREFERENCE_BOUND”PREFERENCE_BOUND: { ENABLE_BOUND_ON_INITIAL_LOAD: false, BASE_DF_TARGET_FILE: "KEMAR DF (KB006x) Target", COLOR_FILL: "rgba(180,180,180,0.2)", COLOR_BORDER: "rgba(120,120,120,0.5)",},Configures the preference bound overlay that draws a shaded upper/lower preference range on the graph.
ENABLE_BOUND_ON_INITIAL_LOAD: Shows bounds immediately on page load.- Choose
trueorfalse.
- Choose
BASE_DF_TARGET_FILE: The reference DF target file used for compensation.COLOR_FILL: Fill color of the shaded area (CSS color value).COLOR_BORDER: Border color of the shaded area (CSS color value).
TARGET_CUSTOMIZER
Section titled “TARGET_CUSTOMIZER”TARGET_CUSTOMIZER: { CUSTOMIZABLE_TARGETS: ["KEMAR DF (KB006x) Target", "ISO 11904-2 DF"], FILTERS: [ { id: "tilt", name: "Tilt", type: "TILT", freq: 0, q: 0 }, { id: "bass", name: "Bass", type: "LSQ", freq: 105, q: 0.707 }, { id: "treble", name: "Treble", type: "HSQ", freq: 2500, q: 0.42 }, { id: "ear", name: "Ear", type: "PK", freq: 2750, q: 1 }, { id: "pssr", name: "PSSR", type: "HSQ", freq: 500, q: 0.4 }, ], FILTER_PRESET: [ { name: "Harman 2013", filter: { bass: 6.6, treble: -1.4 } }, { name: "Harman 2015", filter: { bass: 6.6, treble: -3, ear: -1.8 } }, { name: "Harman 2018", filter: { bass: 4.8, treble: -4.4 } }, ], INITIAL_TARGET_FILTERS: [ { name: "KEMAR DF (KB006x)", filter: { tilt: -0.8, bass: 6 } }, { name: "ISO 11904-2 DF", filter: { tilt: -0.8, bass: 6 } }, ],},Configures the target customizer, which allows per-target filter adjustments for specified target curves.
Only CUSTOMIZABLE_TARGETS is required. FILTERS defaults to Tilt / Bass / Treble / Ear, and FILTER_PRESET to the three Harman presets shown above — omit both unless you want something different.
CUSTOMIZABLE_TARGETS: Array of target file names that can be customized.FILTERS: Available filter definitions. Each filter has:id— Unique identifier for the filter.name— Display name.type— Filter type:TILT,LSQ(Low Shelf),HSQ(High Shelf), orPK(Peaking).freq— Center/corner frequency in Hz.q— Q factor (bandwidth).
FILTER_PRESET: Preset filter configurations selectable from a dropdown.name— Preset display name.filter— Object mapping filter IDs to gain values.
INITIAL_TARGET_FILTERS: Automatically applied filters on initial page load.name— Target name to apply filters to.filter— Object mapping filter IDs to gain values.
CROSS_SITE_SEARCH
Section titled “CROSS_SITE_SEARCH”CROSS_SITE_SEARCH: { ENABLED: true, INDEX_URLS: [],},Lets visitors search other measurement databases from your search box. Works on any host — squig.link is not required. See Cross-Site Search.
ENABLED: Enables cross-site device search.INDEX_URLS: Index documents to try, in order. Leave empty to use the official GraphAggregator index and its GitHub Pages mirror. Set your own URLs to self-host an index following the same schema.
SITE_SELECTOR
Section titled “SITE_SELECTOR”SITE_SELECTOR: { ENABLED: 'auto', INDEX_URLS: [],},Adds a top-bar dropdown for switching between measurement databases across sites. Works on any host — squig.link is not required. See Site Selector.
ENABLED:'auto'shows the selector only when this deployment is listed in the shared index (register at graphaggregator.harutohiroki.com) or is hosted on squig.link.truealways shows it;falsenever does and skips the fetch.INDEX_URLS: Directory documents to try, in order. Leave empty to use the official GAA index. Set your own URLs to self-host one following the same schema.
DOWNLOAD
Section titled “DOWNLOAD”DOWNLOAD: { ENABLED: true,},Adds a per-curve download button to the selection list. Exports the curve exactly as displayed — smoothing, normalization, target adjustments and parametric EQ are all baked in — as one tab-separated Frequency / dB .txt file per channel (Name Suffix L.txt, Name Suffix R.txt, …).
ENABLED: Shows the download button. Off by default.
EQUALIZER
Section titled “EQUALIZER”EQUALIZER: { AUTOEQ_DEFAULT_BAND_COUNT: 8, EQCAPS_URL: 'https://potatosalad775.github.io/eqcaps/v1/',},Defaults for the Equalizer panel. See Equalizer.
AUTOEQ_DEFAULT_BAND_COUNT: How many filter bands Run AutoEQ generates when the filter list is empty. Defaults to8. A non-empty list always wins, so users can still pick a count by adding or removing bands before running. Values below1are ignored, and the active EQ constraint’s band cap still applies — a connected 5-band device gets 5.EQCAPS_URL: Where Hardware EQ and the EQ constraint picker read device and app EQ limits from — a copy of the eqcaps/v1/channel. Defaults to the official one on GitHub Pages; set it for a mirror or a self-hosted copy. The URL must serveindex.jsonandprofiles/with CORS. If it can’t be reached, the built-in constraints still work and devices from known makers still connect.
SQUIGLINK
Section titled “SQUIGLINK”SQUIGLINK: { ENABLED: true, ANALYTICS_MEASUREMENT_IDS: [], ANALYTICS_SITE: "", LOG_ANALYTICS: true, ENABLE_ANALYTICS: true, ENABLE_CROSS_SITE_SEARCH: true, ENABLE_SPONSOR: true,},Configures the squig.link integration. These features are only active when hosted on *.squig.link domains.
ENABLED: Master toggle for squig.link integration.ANALYTICS_MEASUREMENT_IDS: Array of GA4 measurement IDs, e.g.,["G-SQUIGLINK_ID", "G-YOUR_ID"].ANALYTICS_SITE: Site name used for analytics attribution.LOG_ANALYTICS: Whether to log analytics events to the browser console.ENABLE_ANALYTICS: Master toggle for analytics tracking.ENABLE_CROSS_SITE_SEARCH: Deprecated — useCROSS_SITE_SEARCH.ENABLED. Still read as a fallback for configs that predate that section.ENABLE_SPONSOR: Enables sponsor banner and shop link features.
DESCRIPTION
Section titled “DESCRIPTION”DESCRIPTION: [ //{ TYPE: "TEXT", CONTENT: "Every measurements are done by using IEC 60318-4 (711) Ear Simulator." }, { TYPE: "HTML", CONTENT: "<p>Every measurements are done by using IEC 60318-4 (711) Ear Simulator.</p>" },],Adds the text / image / HTML element to the ‘description’ area of the Misc panel.
Multiple descriptions can be added simultaneously. Each description is distinguished by a {} object.
TYPE: Specifies the content type.- Set to
TEXTto display plain text. - Set to
IMAGEto display an image. - Set to
HTMLto display HTML-formatted content.
- Set to
CONTENT: Sets the content.- If
TYPEisTEXT, sets a text string. - If
TYPEisIMAGE, sets an image file path. - If
TYPEisHTML, sets HTML-formatted content.
- If
Multilingual Support (config.js)
Section titled “Multilingual Support (config.js)”Some items in config.js can be written in languages other than English.
- To enable multilingual support, you need to modify the
LANGUAGEitem in theconfig.jsfile. - The items that support multilingual configuration are:
TARGET_MANIFESTTOPBAR→LINK_LISTDESCRIPTION
// Example: TOPBAR.LINK_LIST with multilingual supportTOPBAR: { LINK_LIST: { default: [ { TITLE: "Google", URL: "https://www.google.com" }, { TITLE: "Github", URL: "https://www.github.com" }, ], i18n: { ko: [ { TITLE: "구글", URL: "https://www.google.com" }, { TITLE: "깃허브", URL: "https://www.github.com" }, ] } },},For multilingual support items, objects written in the default language (English) should be in the default field, and objects written in other languages should be in the i18n field.
- The
i18nfield must have an object that matches the language code registered in theLANGUAGE_LISTitem within theLANGUAGEitem. - If you don’t need multilingual support, you can use the simpler flat array format (without
defaultandi18nwrappers).