code wiki / _hdl_build / nx_viz_shape.nx
nx_viz_shape.nx source
↩ module page · 101 lines · 6031 B
1// nx_viz_shape.nx -- the SHAPES layer of the sovereign Nishi viz library (the d3-shape + d3-path equivalent,
2// bits-up). Generates SVG path strings from data points: line + area (the basis of line/area charts). Composes
3// with nx_viz_scale (scale data -> pixel coords, then shape -> path). No d3.js. Arc/pie await the trig layer.
4// Closes shape-line-area + path-serialize in viz_capability_target.tsv. Arc/pie via nx_viz_trig. license_tier: ORIGINAL
5import "nx_syscalls.nx"
6import "nx_viz_trig.nx"
7const K_MAGIC_10000: i64 = 10000
8
9// append integer to out at off; returns new off.
10func vsh_n(out: *u8, off: i64, val: i64) -> i64 {
11 var o: i64 = off
12 var v: i64 = val
13 if v < 0 { out[o] = 45 as u8; o = o + 1; v = 0 - v }
14 let t: *u8 = sys_mmap(28); var k: i64 = 0
15 if v == 0 { t[0] = 48 as u8; k = 1 }
16 while v > 0 { t[k] = (48 + (v % 10)) as u8; v = v / 10; k = k + 1 }
17 var i: i64 = 0; while i < k { out[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
18 return o
19}
20func vsh_lit(out: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { out[o] = s[i]; o = o + 1; i = i + 1 } return o }
21
22// LINE path: "M x0 y0 L x1 y1 ..." -> out (null-terminated). returns length. (d3.line)
23func vs_line(xs: *i64, ys: *i64, n: i64, out: *u8) -> i64 {
24 if n <= 0 { out[0] = 0 as u8; return 0 }
25 var o: i64 = vsh_lit(out, 0, "M " as *u8)
26 o = vsh_n(out, o, xs[0]); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, ys[0])
27 var i: i64 = 1
28 while i < n {
29 o = vsh_lit(out, o, " L " as *u8)
30 o = vsh_n(out, o, xs[i]); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, ys[i])
31 i = i + 1
32 }
33 out[o] = 0 as u8
34 return o
35}
36// AREA path: line across the top, down to baseline, back, closed. (d3.area)
37func vs_area(xs: *i64, ys: *i64, n: i64, baseline: i64, out: *u8) -> i64 {
38 if n <= 0 { out[0] = 0 as u8; return 0 }
39 var o: i64 = vs_line(xs, ys, n, out)
40 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, xs[n - 1]); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, baseline)
41 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, xs[0]); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, baseline)
42 o = vsh_lit(out, o, " Z" as *u8)
43 out[o] = 0 as u8
44 return o
45}
46// ARC/PIE slice: from center -> arc-start -> arc to arc-end -> close. SVG y is down (angles run clockwise).
47// x = cx + r*cos(a)/10000, y = cy + r*sin(a)/10000 (via nx_viz_trig). (d3.arc / d3.pie)
48func vs_arc(cx: i64, cy: i64, r: i64, a0_deg: i64, a1_deg: i64, out: *u8) -> i64 {
49 let x0: i64 = cx + (r * vs_cos(a0_deg)) / K_MAGIC_10000
50 let y0: i64 = cy + (r * vs_sin(a0_deg)) / K_MAGIC_10000
51 let x1: i64 = cx + (r * vs_cos(a1_deg)) / K_MAGIC_10000
52 let y1: i64 = cy + (r * vs_sin(a1_deg)) / K_MAGIC_10000
53 var large: i64 = 0
54 if (a1_deg - a0_deg) > 180 { large = 1 }
55 var o: i64 = vsh_lit(out, 0, "M " as *u8)
56 o = vsh_n(out, o, cx); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy)
57 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, x0); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, y0)
58 o = vsh_lit(out, o, " A " as *u8); o = vsh_n(out, o, r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, r)
59 o = vsh_lit(out, o, " 0 " as *u8); o = vsh_n(out, o, large); o = vsh_lit(out, o, " 1 " as *u8)
60 o = vsh_n(out, o, x1); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, y1)
61 o = vsh_lit(out, o, " Z" as *u8)
62 out[o] = 0 as u8
63 return o
64}
65// SYMBOL marker path centred at (cx,cy), radius r. typ: 0=square 1=diamond 2=triangle. (d3.symbol)
66func vs_symbol(typ: i64, cx: i64, cy: i64, r: i64, out: *u8) -> i64 {
67 var o: i64 = 0
68 if typ == 0 {
69 o = vsh_lit(out, 0, "M " as *u8); o = vsh_n(out, o, cx - r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy - r)
70 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx + r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy - r)
71 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx + r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy + r)
72 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx - r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy + r)
73 o = vsh_lit(out, o, " Z" as *u8)
74 }
75 if typ == 1 {
76 o = vsh_lit(out, 0, "M " as *u8); o = vsh_n(out, o, cx); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy - r)
77 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx + r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy)
78 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy + r)
79 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx - r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy)
80 o = vsh_lit(out, o, " Z" as *u8)
81 }
82 if typ == 2 {
83 o = vsh_lit(out, 0, "M " as *u8); o = vsh_n(out, o, cx); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy - r)
84 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx + r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy + r)
85 o = vsh_lit(out, o, " L " as *u8); o = vsh_n(out, o, cx - r); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, cy + r)
86 o = vsh_lit(out, o, " Z" as *u8)
87 }
88 out[o] = 0 as u8
89 return o
90}
91// LINK path: smooth horizontal cubic-Bezier S-curve from (x0,y0) to (x1,y1). (d3.linkHorizontal)
92func vs_link(x0: i64, y0: i64, x1: i64, y1: i64, out: *u8) -> i64 {
93 let mx: i64 = (x0 + x1) / 2
94 var o: i64 = vsh_lit(out, 0, "M " as *u8); o = vsh_n(out, o, x0); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, y0)
95 o = vsh_lit(out, o, " C " as *u8); o = vsh_n(out, o, mx); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, y0)
96 o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, mx); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, y1)
97 o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, x1); o = vsh_lit(out, o, " " as *u8); o = vsh_n(out, o, y1)
98 out[o] = 0 as u8
99 return o
100}
101func main() -> i64 { return 0 }