44 < meta charset ="UTF-8 " />
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
66 < title > tsb — melt</ title >
7- < script src ="playground-runtime.js "> </ script >
87 < style >
9- body { font-family : system-ui, sans-serif; max-width : 860px ; margin : 2rem auto; padding : 0 1rem ; color : # 1a1a1a ; }
10- h1 { font-size : 2rem ; margin-bottom : .25rem ; }
11- .subtitle { color : # 555 ; margin-bottom : 2rem ; }
12- section { margin-bottom : 2.5rem ; }
13- h2 { font-size : 1.25rem ; border-bottom : 2px solid # e0e0e0 ; padding-bottom : .35rem ; margin-bottom : 1rem ; }
14- pre { background : # f5f5f5 ; border-radius : 6px ; padding : 1rem ; overflow-x : auto; font-size : .875rem ; }
15- code { font-family : "JetBrains Mono" , "Fira Code" , monospace; }
16- .output { background : # eaf7ea ; border-left : 4px solid # 4caf50 ; padding : .75rem 1rem ; border-radius : 0 6px 6px 0 ; margin-top : .5rem ; font-size : .875rem ; white-space : pre; font-family : monospace; }
17- .note { background : # fff8e1 ; border-left : 4px solid # ffc107 ; padding : .6rem 1rem ; border-radius : 0 6px 6px 0 ; font-size : .9rem ; margin : .75rem 0 ; }
18- nav { margin-bottom : 1.5rem ; font-size : .9rem ; color : # 555 ; }
19- nav a { color : # 0366d6 ; text-decoration : none; }
20- nav a : hover { text-decoration : underline; }
8+ : root {
9+ --bg : # 0d1117 ;
10+ --surface : # 161b22 ;
11+ --border : # 30363d ;
12+ --text : # e6edf3 ;
13+ --accent : # 58a6ff ;
14+ --green : # 3fb950 ;
15+ --orange : # d29922 ;
16+ --red : # f85149 ;
17+ --font-mono : "Cascadia Code" , "Fira Code" , "JetBrains Mono" , monospace;
18+ }
19+ * { box-sizing : border-box; margin : 0 ; padding : 0 ; }
20+ body {
21+ background : var (--bg );
22+ color : var (--text );
23+ font-family : system-ui, -apple-system, sans-serif;
24+ line-height : 1.6 ;
25+ padding : 2rem ;
26+ max-width : 900px ;
27+ margin : 0 auto;
28+ }
29+ a { color : var (--accent ); }
30+ h1 { color : var (--accent ); margin-bottom : 0.5rem ; }
31+ h2 { margin-top : 0 ; margin-bottom : 0.5rem ; font-size : 1.25rem ; }
32+ p { color : # 8b949e ; margin-bottom : 1rem ; }
33+ code {
34+ font-family : var (--font-mono );
35+ font-size : 0.875em ;
36+ background : var (--surface );
37+ border : 1px solid var (--border );
38+ border-radius : 0.3rem ;
39+ padding : 0.1rem 0.4rem ;
40+ }
41+ .back { margin-bottom : 2rem ; display : inline-block; }
42+ # playground-loading {
43+ position : fixed;
44+ inset : 0 ;
45+ background : rgba (13 , 17 , 23 , 0.92 );
46+ display : flex;
47+ flex-direction : column;
48+ align-items : center;
49+ justify-content : center;
50+ z-index : 1000 ;
51+ gap : 1rem ;
52+ }
53+ .spinner {
54+ width : 40px ; height : 40px ;
55+ border : 3px solid var (--border );
56+ border-top-color : var (--accent );
57+ border-radius : 50% ;
58+ animation : spin 0.8s linear infinite;
59+ }
60+ @keyframes spin { to { transform : rotate (360deg ); } }
61+ # playground-status { color : # 8b949e ; font-size : 0.95rem ; }
62+ .section {
63+ background : var (--surface );
64+ border : 1px solid var (--border );
65+ border-radius : 0.75rem ;
66+ padding : 1.5rem ;
67+ margin-bottom : 1.5rem ;
68+ }
69+ .section p { margin-bottom : 0.75rem ; }
70+ .playground-block { margin-top : 0.75rem ; }
71+ .playground-header {
72+ display : flex;
73+ align-items : center;
74+ justify-content : space-between;
75+ background : # 1c2128 ;
76+ border : 1px solid var (--border );
77+ border-bottom : none;
78+ border-radius : 0.5rem 0.5rem 0 0 ;
79+ padding : 0.4rem 0.75rem ;
80+ }
81+ .playground-label {
82+ font-size : 0.75rem ;
83+ color : # 8b949e ;
84+ text-transform : uppercase;
85+ letter-spacing : 0.05em ;
86+ }
87+ .playground-actions { display : flex; gap : 0.5rem ; }
88+ .playground-actions button {
89+ background : transparent;
90+ color : var (--accent );
91+ border : 1px solid var (--border );
92+ border-radius : 0.35rem ;
93+ padding : 0.25rem 0.7rem ;
94+ font-size : 0.8rem ;
95+ cursor : pointer;
96+ font-family : system-ui, sans-serif;
97+ transition : background 0.15s , border-color 0.15s ;
98+ }
99+ .playground-actions button : hover : not (: disabled ) {
100+ background : rgba (88 , 166 , 255 , 0.1 );
101+ border-color : var (--accent );
102+ }
103+ .playground-actions button : disabled { opacity : 0.4 ; cursor : not-allowed; }
104+ .playground-run { font-weight : 600 ; }
105+ .playground-editor {
106+ display : block;
107+ width : 100% ;
108+ min-height : 80px ;
109+ background : # 0d1117 ;
110+ color : var (--text );
111+ border : 1px solid var (--border );
112+ border-top : none;
113+ border-bottom : none;
114+ padding : 1rem ;
115+ font-family : var (--font-mono );
116+ font-size : 0.875rem ;
117+ line-height : 1.55 ;
118+ resize : vertical;
119+ outline : none;
120+ tab-size : 2 ;
121+ white-space : pre;
122+ overflow-x : auto;
123+ }
124+ .playground-editor : focus {
125+ border-color : var (--accent );
126+ box-shadow : inset 0 0 0 1px var (--accent );
127+ }
128+ .playground-output {
129+ background : # 1c2333 ;
130+ border : 1px solid var (--border );
131+ border-radius : 0 0 0.5rem 0.5rem ;
132+ padding : 0.75rem 1rem ;
133+ font-family : var (--font-mono );
134+ font-size : 0.85rem ;
135+ color : # 8b949e ;
136+ white-space : pre-wrap;
137+ min-height : 2rem ;
138+ word-break : break-word;
139+ }
140+ .playground-output .active { color : var (--green ); border-color : var (--green ); }
141+ .playground-output .error { color : var (--red ); border-color : var (--red ); }
142+ .playground-hint {
143+ font-size : 0.75rem ;
144+ color : # 484f58 ;
145+ margin-top : 0.35rem ;
146+ text-align : right;
147+ }
148+ .api-reference-code {
149+ background : var (--bg );
150+ border : 1px solid var (--border );
151+ border-radius : 0.5rem ;
152+ padding : 1rem ;
153+ font-family : var (--font-mono );
154+ font-size : 0.85rem ;
155+ color : # 8b949e ;
156+ overflow-x : auto;
157+ margin-top : 0.5rem ;
158+ }
159+ .api-reference-code code {
160+ background : none;
161+ border : none;
162+ padding : 0 ;
163+ }
164+ footer {
165+ text-align : center;
166+ padding : 2rem 0 ;
167+ color : # 8b949e ;
168+ font-size : 0.85rem ;
169+ border-top : 1px solid var (--border );
170+ margin-top : 2rem ;
171+ }
21172 </ style >
22173</ head >
23174< body >
24- < nav > < a href ="index.html "> ← tsb playground</ a > </ nav >
25- < h1 > melt — Wide to Long</ h1 >
26- < p class ="subtitle "> Unpivot a DataFrame from wide format to long format — mirrors < code > pandas.melt()</ code > / < code > DataFrame.melt()</ code > .</ p >
175+ < div id ="playground-loading ">
176+ < div class ="spinner "> </ div >
177+ < div id ="playground-status "> Initializing playground…</ div >
178+ </ div >
179+ < a class ="back " href ="index.html "> ← Back to roadmap</ a >
180+ < h1 > 🔄 melt — Interactive Playground</ h1 >
181+ < p > Unpivot a DataFrame from wide format to long format — mirrors
182+ < code > pandas.melt()</ code > / < code > DataFrame.melt()</ code > .< br >
183+ < strong style ="color: var(--text); "> Edit any code block below and press ▶ Run
184+ (or Ctrl+Enter) to execute it live in your browser.</ strong >
185+ </ p >
27186
28- < section >
29- < h2 > 1 — Basic melt</ h2 >
30- < p > Melt all value columns into a single < code > variable</ code > / < code > value</ code > pair.</ p >
31- < pre > < code id ="ex1-code "> import { DataFrame, melt } from "tsb";
187+ <!-- 1 · Basic melt -->
188+ < div class ="section ">
189+ < h2 > 1 · Basic melt</ h2 >
190+ < p > Melt all value columns into a single < code > variable</ code > / < code > value</ code >
191+ pair.</ p >
192+ < div class ="playground-block ">
193+ < div class ="playground-header ">
194+ < span class ="playground-label "> TypeScript</ span >
195+ < div class ="playground-actions ">
196+ < button class ="playground-run " disabled > ▶ Run</ button >
197+ < button class ="playground-reset "> ↺ Reset</ button >
198+ </ div >
199+ </ div >
200+ < textarea class ="playground-editor " spellcheck ="false "> import { DataFrame, melt } from "tsb";
32201
33202const df = DataFrame.fromColumns({
34203 A: [1, 2, 3],
@@ -37,16 +206,26 @@ <h2>1 — Basic melt</h2>
37206});
38207
39208const long = melt(df);
40- console.log(long.toRecords());
41- // [{ variable: "A", value: 1 }, { variable: "A", value: 2 }, ...]
42- </ code > </ pre >
43- < div class =" output " id =" ex1-out " > ▶ run </ div >
44- </ section >
209+ console.log(long.toRecords());</ textarea >
210+ < div class =" playground-output " > Click ▶ Run to execute </ div >
211+ < div class =" playground-hint " > Ctrl+Enter to run · Tab to indent </ div >
212+ </ div >
213+ </ div >
45214
46- < section >
47- < h2 > 2 — Preserve identifier columns</ h2 >
48- < p > Use < code > id_vars</ code > to keep columns as identifiers that are repeated for each melted row.</ p >
49- < pre > < code id ="ex2-code "> import { DataFrame, melt } from "tsb";
215+ <!-- 2 · Preserve identifier columns -->
216+ < div class ="section ">
217+ < h2 > 2 · Preserve identifier columns</ h2 >
218+ < p > Use < code > id_vars</ code > to keep columns as identifiers that are repeated for
219+ each melted row.</ p >
220+ < div class ="playground-block ">
221+ < div class ="playground-header ">
222+ < span class ="playground-label "> TypeScript</ span >
223+ < div class ="playground-actions ">
224+ < button class ="playground-run " disabled > ▶ Run</ button >
225+ < button class ="playground-reset "> ↺ Reset</ button >
226+ </ div >
227+ </ div >
228+ < textarea class ="playground-editor " spellcheck ="false "> import { DataFrame, melt } from "tsb";
50229
51230const df = DataFrame.fromColumns({
52231 id: ["alice", "bob", "carol"],
@@ -55,16 +234,30 @@ <h2>2 — Preserve identifier columns</h2>
55234 mar: [120, 210, 140],
56235});
57236
58- const long = melt(df, { id_vars: "id", var_name: "month", value_name: "sales" });
59- console.log(long.toRecords());
60- </ code > </ pre >
61- < div class ="output " id ="ex2-out "> ▶ run</ div >
62- </ section >
237+ const long = melt(df, {
238+ id_vars: "id",
239+ var_name: "month",
240+ value_name: "sales",
241+ });
242+ console.log(long.toRecords());</ textarea >
243+ < div class ="playground-output "> Click ▶ Run to execute</ div >
244+ < div class ="playground-hint "> Ctrl+Enter to run · Tab to indent</ div >
245+ </ div >
246+ </ div >
63247
64- < section >
65- < h2 > 3 — Selective value columns</ h2 >
66- < p > Use < code > value_vars</ code > to specify which columns to unpivot.</ p >
67- < pre > < code id ="ex3-code "> import { DataFrame, melt } from "tsb";
248+ <!-- 3 · Selective value columns -->
249+ < div class ="section ">
250+ < h2 > 3 · Selective value columns</ h2 >
251+ < p > Use < code > value_vars</ code > to specify which columns to unpivot.</ p >
252+ < div class ="playground-block ">
253+ < div class ="playground-header ">
254+ < span class ="playground-label "> TypeScript</ span >
255+ < div class ="playground-actions ">
256+ < button class ="playground-run " disabled > ▶ Run</ button >
257+ < button class ="playground-reset "> ↺ Reset</ button >
258+ </ div >
259+ </ div >
260+ < textarea class ="playground-editor " spellcheck ="false "> import { DataFrame, melt } from "tsb";
68261
69262const df = DataFrame.fromColumns({
70263 name: ["Alice", "Bob"],
@@ -73,22 +266,31 @@ <h2>3 — Selective value columns</h2>
73266 grade: ["B", "A"],
74267});
75268
76- // Only melt score columns, keep name
77269const long = melt(df, {
78270 id_vars: "name",
79271 value_vars: ["score1", "score2"],
80272 var_name: "test",
81273 value_name: "score",
82274});
83- console.log(long.toRecords());
84- </ code > </ pre >
85- < div class ="output " id ="ex3-out "> ▶ run</ div >
86- </ section >
275+ console.log(long.toRecords());</ textarea >
276+ < div class ="playground-output "> Click ▶ Run to execute</ div >
277+ < div class ="playground-hint "> Ctrl+Enter to run · Tab to indent</ div >
278+ </ div >
279+ </ div >
87280
88- < section >
89- < h2 > 4 — Multiple id columns</ h2 >
90- < p > Pass an array to < code > id_vars</ code > to use multiple identifier columns.</ p >
91- < pre > < code id ="ex4-code "> import { DataFrame, melt } from "tsb";
281+ <!-- 4 · Multiple id columns -->
282+ < div class ="section ">
283+ < h2 > 4 · Multiple id columns</ h2 >
284+ < p > Pass an array to < code > id_vars</ code > to use multiple identifier columns.</ p >
285+ < div class ="playground-block ">
286+ < div class ="playground-header ">
287+ < span class ="playground-label "> TypeScript</ span >
288+ < div class ="playground-actions ">
289+ < button class ="playground-run " disabled > ▶ Run</ button >
290+ < button class ="playground-reset "> ↺ Reset</ button >
291+ </ div >
292+ </ div >
293+ < textarea class ="playground-editor " spellcheck ="false "> import { DataFrame, melt } from "tsb";
92294
93295const df = DataFrame.fromColumns({
94296 year: [2022, 2023],
@@ -102,28 +304,32 @@ <h2>4 — Multiple id columns</h2>
102304 var_name: "quarter",
103305 value_name: "revenue",
104306});
105- console.log(long.toRecords());
106- </ code > </ pre >
107- < div class ="output " id ="ex4-out "> ▶ run</ div >
108- </ section >
307+ console.log(long.toRecords());</ textarea >
308+ < div class ="playground-output "> Click ▶ Run to execute</ div >
309+ < div class ="playground-hint "> Ctrl+Enter to run · Tab to indent</ div >
310+ </ div >
311+ </ div >
109312
110- < script >
111- window . addEventListener ( "load" , ( ) => {
112- document . querySelectorAll ( ".output" ) . forEach ( ( el ) => {
113- const id = el . id . replace ( "-out" , "-code" ) ;
114- const code = document . getElementById ( id ) ?. textContent ?? "" ;
115- el . textContent = "▶ click to run" ;
116- el . style . cursor = "pointer" ;
117- el . addEventListener ( "click" , ( ) => {
118- el . textContent = "Running…" ;
119- try {
120- window . runTsb ?. ( code , ( result ) => { el . textContent = result ; } ) ;
121- } catch ( e ) {
122- el . textContent = String ( e ) ;
123- }
124- } ) ;
125- } ) ;
126- } ) ;
127- </ script >
313+ <!-- API Reference -->
314+ < div class ="section ">
315+ < h2 > API Reference</ h2 >
316+ < p > Unpivot a DataFrame from wide to long format. Columns not specified as
317+ < code > id_vars</ code > or < code > value_vars</ code > are melted into
318+ < code > variable</ code > / < code > value</ code > pairs.</ p >
319+ < pre class ="api-reference-code "> < code > melt(df: DataFrame, options?: {
320+ id_vars?: string | string[], // columns to keep as identifiers
321+ value_vars?: string | string[], // columns to unpivot (default: all non-id)
322+ var_name?: string, // name for the variable column (default: "variable")
323+ value_name?: string, // name for the value column (default: "value")
324+ }): DataFrame</ code > </ pre >
325+ </ div >
326+
327+ < footer >
328+ < p >
329+ < a href ="index.html "> tsb playground</ a > ·
330+ Built by < a href ="https://github.com/githubnext/autoloop "> Autoloop</ a >
331+ </ p >
332+ </ footer >
333+ < script type ="module " src ="playground-runtime.js "> </ script >
128334</ body >
129335</ html >
0 commit comments