code wiki / (root) / nx_chartlay_lib.nx

nx_chartlay_lib.nx

buildroot/runtime/nx_chartlay_lib.nx

20952 B387 linesdepth 6pulls 7 transitivereach 42 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_chartlay_lib.nx -- THE ONE chart-layout ruler for every SVG chart the compare emitters draw (datavis DV1, 2026-09-15). Domain-fit scales with nice ticks, integer linear scaling, a colour-blind-safe categorical palette (Okabe-Ito, the house accent in slot 0), text-width estimates, greedy collision-free label placement with leader lines, and the READABILITY CRITIC (label-label, label-mark and mark-mark overlaps, off-canvas labels, data spread) so a render GRADES ITSELF before it ships and prints the grade beside the picture. Born of the operator's 2026-09-15 junk verdict on the position map: five marks in one corner of a fixed 0..1000 canvas, labels overlapping and clipped at the right edge, a cube nobody could read. Pure integer arithmetic, struct-free, so the laptop toolchain proves it too. The field's practice this encodes (Datawrapper, Observable Plot, Vega-Lite: 4..7 gridlines, axes fit to the data with a breathing pad, direct labels that never collide, one palette that survives colour-vision deficiency) is the ORACLE; nothing here links, forks or shells any of them -- they stay outside the build path as liar-killers and benchmarks. license_tier: ORIGINAL

dependencies 2 imports · 3 importers

nx_syscalls.nx nx_uiq_color.nx nx_chartlay_lib.nx nx_cdmap_referee_lib.nx nx_chartlay_gate.nx nx_swcompare_lib.nx

imports: nx_syscalls.nxnx_uiq_color.nx

imported by: nx_cdmap_referee_lib.nxnx_chartlay_gate.nxnx_swcompare_lib.nx

structs

none

consts

15const CL_PERMIL: i64 = 1000
16const CL_I64_BYTES: i64 = 8
17const CL_TWO: i64 = 2
18const CL_TICKS_MAX: i64 = 7 // the most ticks an axis wants: pick the smallest nice step that needs no more
19const CL_PAD_PERMIL: i64 = 120 // breathing pad each side of the data span, permil of the span
20const CL_PAD_MIN: i64 = 20 // ...never less than this many permil, so a tight cluster still breathes
21const CL_STEP_N: i64 = 9
22const CL_STEP_10: i64 = 10
23const CL_STEP_20: i64 = 20
24const CL_STEP_25: i64 = 25
25const CL_STEP_50: i64 = 50
26const CL_STEP_100: i64 = 100
27const CL_STEP_200: i64 = 200
28const CL_STEP_250: i64 = 250
29const CL_STEP_500: i64 = 500
30const CL_STEP_1000: i64 = 1000
31const CL_S0: i64 = 0
32const CL_S1: i64 = 1
33const CL_S2: i64 = 2
34const CL_S3: i64 = 3
35const CL_S4: i64 = 4
36const CL_S5: i64 = 5
37const CL_S6: i64 = 6
38const CL_S7: i64 = 7
39const CL_DOM_W: i64 = 3 // a domain record: lo, hi, step
40const CL_D_LO: i64 = 0
41const CL_D_HI: i64 = 1
42const CL_D_STEP: i64 = 2
43const CL_TEXT_W_PERMIL: i64 = 560 // mean glyph advance of a sans face at 1 em (digits and lower case read 0.50..0.61 em)
44const CL_LINE_H_PERMIL: i64 = 1250 // a one-line label box is 1.25 em tall
45const CL_GAP: i64 = 6 // px between a mark's edge and its label box
46const CL_LEAD_MULT: i64 = 3 // a leader-line candidate sits CL_GAP * this from the mark
47const CL_CAND_N: i64 = 8
48const CL_CAND_RIGHT: i64 = 0
49const CL_CAND_LEFT: i64 = 1
50const CL_CAND_ABOVE: i64 = 2
51const CL_CAND_BELOW: i64 = 3
52const CL_CAND_RU: i64 = 4 // right-up with a leader
53const CL_CAND_LU: i64 = 5
54const CL_CAND_RD: i64 = 6
55const CL_CAND_LD: i64 = 7
56const CL_CAND_LEADER_FROM: i64 = 4 // candidates at or past this index need a leader line
57const CL_CRIT_W: i64 = 6
58const CL_C_LL: i64 = 0 // label-label overlapping pairs
59const CL_C_LM: i64 = 1 // label-over-mark overlaps
60const CL_C_OFF: i64 = 2 // labels outside the canvas
61const CL_C_MM: i64 = 3 // mark-mark overlapping pairs (a property of the data, reported never hidden)
62const CL_C_SPREAD: i64 = 4 // permil of the plot the data bounding box spans, mean of the two axes
63const CL_C_DEFECTS: i64 = 5 // LL + LM + OFF: what a reader cannot read
64const CL_PAL_N: i64 = 8
65const CL_PAL_ACCENT: i64 = 0
66const CL_PAL_RIVALS: i64 = 7
261const CL_RESEAT_N: i64 = 5
293const CL_CT_W: i64 = 5
294const CL_CT_SMALL: i64 = 0 // floor x100 for text below the large tier
295const CL_CT_LARGE: i64 = 1 // floor x100 for large text
296const CL_CT_LARGE_PX: i64 = 2 // regular text at or past this px is large
297const CL_CT_LARGE_BOLD_PX: i64 = 3 // bold text at or past this px is large
298const CL_CT_LOADED: i64 = 4 // 0 defaults (no conf) / 1 conf read / 2 conf names an unimplemented algorithm (defaults, announced)
299const CL_CT_DEFAULT_SMALL: i64 = 450
300const CL_CT_DEFAULT_LARGE: i64 = 300
301const CL_CT_DEFAULT_LARGE_PX: i64 = 18
302const CL_CT_DEFAULT_LARGE_BOLD_PX: i64 = 14
303const CL_CT_ALGORITHM: *u8 = "wcag2-ratio"
304const CL_CT_UNKNOWN_ALG: i64 = 2
305const CL_CT_CH_PIPE: i64 = 124
306const CL_CT_CH_NL: i64 = 10
307const CL_CT_CH_0: i64 = 48
308const CL_CT_CH_9: i64 = 57
309const CL_CT_BASE10: i64 = 10

functions

68func chl_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } // chl_, not cl_: nx_catalog_lib owns cl_slen in the emitter's closure
called by 2: g_write_textmain
69func cl_min(a: i64, b: i64) -> i64 { if a < b { return a } return b }
70func cl_max(a: i64, b: i64) -> i64 { if a > b { return a } return b }
71func cl_step_at(i: i64) -> i64
called by 1: cl_nice_step
83func cl_nice_step(span: i64) -> i64
called by 1: cl_domain calls 1: cl_step_at
88func cl_floor_to(v: i64, step: i64) -> i64 { return v - (v % step) }
called by 1: cl_domain
89func cl_ceil_to(v: i64, step: i64) -> i64 { let r: i64 = v % step; if r == 0 { return v } return v + step - r }
called by 1: cl_domain
92func cl_domain(vmin: i64, vmax: i64, dom: *i64) -> i64
113func cl_tick(dom: *i64, i: i64) -> i64 { return dom[CL_D_LO] + i * dom[CL_D_STEP] }
called by 1: main
114func cl_ticks(dom: *i64) -> i64 { return (dom[CL_D_HI] - dom[CL_D_LO]) / dom[CL_D_STEP] + 1 }
called by 1: main
116func cl_scale(v: i64, lo: i64, hi: i64, p0: i64, p1: i64) -> i64 { if hi == lo { return p0 } return p0 + (v - lo) * (p1 - p0) / (hi - lo) }
117func cl_scale_dom(v: i64, dom: *i64, p0: i64, p1: i64) -> i64 { return cl_scale(v, dom[CL_D_LO], dom[CL_D_HI], p0, p1) }
called by 4: maincdp_xcdp_ycdp_iso_fit calls 1: cl_scale
118func cl_text_w(nchars: i64, font_px: i64) -> i64 { return nchars * font_px * CL_TEXT_W_PERMIL / CL_PERMIL }
119func cl_text_h(font_px: i64) -> i64 { return font_px * CL_LINE_H_PERMIL / CL_PERMIL }
120func cl_box_hit(ax: i64, ay: i64, aw: i64, ah: i64, bx: i64, by: i64, bw: i64, bh: i64) -> i64
127func cl_leader(k: i64) -> i64 { if k >= CL_CAND_LEADER_FROM { return 1 } return 0 }
called by 1: main
129func cl_cand(k: i64, mx: i64, my: i64, mr: i64, lw: i64, lh: i64, xy: *i64) -> i64
called by 2: maincl_place_from
144func cl_fits(i: i64, x: i64, y: i64, n: i64, mx: *i64, my: *i64, mr: *i64, lx: *i64, ly: *i64, lw: *i64, lh: *i64, placed: *i64, x0: i64, y0: i64, x1: i64, y1: i64) -> i64
162func cl_place(n: i64, mx: *i64, my: *i64, mr: *i64, lw: *i64, lh: *i64, x0: i64, y0: i64, x1: i64, y1: i64, lx: *i64, ly: *i64, lside: *i64, lres: *i64) -> i64
called by 1: main calls 1: cl_place_from
170func cl_place_from(n: i64, nfixed: i64, mx: *i64, my: *i64, mr: *i64, lw: *i64, lh: *i64, x0: i64, y0: i64, x1: i64, y1: i64, lx: *i64, ly: *i64, lside: *i64, lres: *i64) -> i64
201func cl_critic(n: i64, mx: *i64, my: *i64, mr: *i64, lx: *i64, ly: *i64, lw: *i64, lh: *i64, x0: i64, y0: i64, x1: i64, y1: i64, out: *i64) -> i64
245func cl_palette(i: i64) -> *u8
called by 2: maincdp_mark
262func cl_reseat_in(i: i64, n: i64, mx: *i64, my: *i64, mr: *i64, lx: *i64, ly: *i64, lw: *i64, lh: *i64, rx0: i64, ry0: i64, rx1: i64, ry1: i64) -> i64
called by 1: main calls 3: sys_mmapcl_fitssys_munmap
310func cl_contrast(fr: i64, fg: i64, fb: i64, br: i64, bg: i64, bb: i64) -> i64 { return uiq_ratio100(fr, fg, fb, br, bg, bb) }
called by 1: main calls 1: uiq_ratio100
312func cl_blend(top: i64, under: i64, a_permil: i64) -> i64 { return (top * a_permil + under * (CL_PERMIL - a_permil)) / CL_PERMIL }
called by 1: main
313func cl_contrast_defaults(ct: *i64) -> i64
called by 1: cl_contrast_conf
321func cl_contrast_floor(font_px: i64, bold: i64, ct: *i64) -> i64
called by 1: main
326func cl_contrast_ok(x100: i64, floor: i64) -> i64 { if x100 >= floor { return 1 } return 0 }
called by 1: main
328func cl_ct_field(b: *u8, s: i64, e: i64, f: i64) -> i64
334func cl_ct_field_is(b: *u8, s: i64, e: i64, f: i64, lit: *u8) -> i64
called by 1: cl_contrast_conf calls 1: cl_ct_field
342func cl_ct_field_int(b: *u8, s: i64, e: i64, f: i64) -> i64
called by 1: cl_contrast_conf calls 1: cl_ct_field
351func cl_contrast_conf(path: *u8, ct: *i64) -> i64
377func cl_palette_name(i: i64) -> *u8