Skip to content

Commit 9934cea

Browse files
authored
Update and rename index.html to index.html
1 parent cea914c commit 9934cea

2 files changed

Lines changed: 294 additions & 351 deletions

File tree

json-schema/index.html

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>JSON Studio</title>
6+
7+
<script src="https://cdn.tailwindcss.com"></script>
8+
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
9+
<script src="https://cdnjs.cloudflare.com/ajax/libs/diff/5.1.0/diff.min.js"></script>
10+
11+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"/>
12+
13+
<style>
14+
15+
body{
16+
background:#0B1120;
17+
color:#E2E8F0;
18+
font-family: ui-monospace;
19+
}
20+
21+
.panel{
22+
background:#111827;
23+
border:1px solid #1F2937;
24+
border-radius:12px;
25+
}
26+
27+
textarea{
28+
background:#020617;
29+
color:#e2e8f0;
30+
}
31+
32+
.node rect{
33+
fill:#1E293B;
34+
stroke:#FFC300;
35+
stroke-width:1.5px;
36+
}
37+
38+
.node text{
39+
fill:#E5E7EB;
40+
font-size:12px;
41+
}
42+
43+
.link{
44+
fill:none;
45+
stroke:#475569;
46+
stroke-width:1.5px;
47+
}
48+
49+
</style>
50+
</head>
51+
52+
<body class="p-6">
53+
54+
<div class="max-w-7xl mx-auto space-y-6">
55+
56+
<h1 class="text-3xl font-bold">
57+
JSON <span class="text-yellow-400">Studio</span>
58+
</h1>
59+
60+
<div class="grid md:grid-cols-2 gap-6">
61+
62+
<div class="panel p-4">
63+
64+
<div class="flex justify-between mb-3">
65+
<h2 class="font-semibold">JSON Input</h2>
66+
67+
<button onclick="visualize()"
68+
class="bg-yellow-500 text-black px-3 py-1 rounded text-sm">
69+
Visualize
70+
</button>
71+
</div>
72+
73+
<textarea id="jsonInput" class="w-full h-64 p-3 rounded text-sm"></textarea>
74+
75+
</div>
76+
77+
<div class="panel p-4">
78+
79+
<h2 class="font-semibold mb-3">Schema Explorer</h2>
80+
81+
<div id="schemaTable" class="text-sm"></div>
82+
83+
</div>
84+
85+
</div>
86+
87+
<div class="panel p-4">
88+
89+
<h2 class="font-semibold mb-3">Structure Graph</h2>
90+
91+
<svg id="graph" width="100%" height="500"></svg>
92+
93+
</div>
94+
95+
<div class="grid md:grid-cols-2 gap-6">
96+
97+
<div class="panel p-4">
98+
99+
<h2 class="font-semibold mb-3">JSON Diff</h2>
100+
101+
<textarea id="jsonInput2" class="w-full h-40 p-3 rounded text-sm"></textarea>
102+
103+
<button onclick="runDiff()" class="mt-2 bg-yellow-500 text-black px-3 py-1 rounded text-sm">
104+
Compare
105+
</button>
106+
107+
<pre id="diffResult" class="text-xs mt-3"></pre>
108+
109+
</div>
110+
111+
<div class="panel p-4">
112+
113+
<h2 class="font-semibold mb-3">Schema Intelligence</h2>
114+
115+
<div id="aiExplain" class="text-sm text-gray-300"></div>
116+
117+
</div>
118+
119+
</div>
120+
121+
</div>
122+
123+
<script>
124+
125+
function visualize(){
126+
127+
let json = JSON.parse(document.getElementById("jsonInput").value);
128+
129+
renderSchema(json);
130+
131+
renderGraph(json);
132+
133+
detectOpenAPI(json);
134+
135+
}
136+
137+
function renderSchema(obj){
138+
139+
let rows=[];
140+
141+
function walk(o,path="root"){
142+
143+
for(let k in o){
144+
145+
let val=o[k];
146+
let type=Array.isArray(val)?"array":typeof val;
147+
148+
rows.push(`<tr>
149+
<td class="px-2">${path}.${k}</td>
150+
<td>${type}</td>
151+
</tr>`);
152+
153+
if(typeof val==="object" && val!=null){
154+
155+
walk(val,path+"."+k)
156+
157+
}
158+
159+
}
160+
161+
}
162+
163+
walk(obj);
164+
165+
document.getElementById("schemaTable").innerHTML=
166+
167+
`<table class="w-full text-xs">
168+
<tr class="text-yellow-400">
169+
<th class="text-left px-2">Field</th>
170+
<th>Type</th>
171+
</tr>
172+
${rows.join("")}
173+
</table>`
174+
175+
}
176+
177+
function renderGraph(data){
178+
179+
const svg=d3.select("#graph");
180+
svg.selectAll("*").remove();
181+
182+
const width=800;
183+
const height=500;
184+
185+
const root=d3.hierarchy(convert(data));
186+
187+
const tree=d3.tree().size([height,width-200]);
188+
189+
tree(root);
190+
191+
const g=svg.append("g").attr("transform","translate(80,0)");
192+
193+
g.selectAll(".link")
194+
.data(root.links())
195+
.enter()
196+
.append("path")
197+
.attr("class","link")
198+
.attr("d",d3.linkHorizontal()
199+
.x(d=>d.y)
200+
.y(d=>d.x)
201+
);
202+
203+
const node=g.selectAll(".node")
204+
.data(root.descendants())
205+
.enter()
206+
.append("g")
207+
.attr("transform",d=>`translate(${d.y},${d.x})`);
208+
209+
node.append("rect")
210+
.attr("width",120)
211+
.attr("height",20)
212+
.attr("rx",4);
213+
214+
node.append("text")
215+
.attr("dx",5)
216+
.attr("dy",14)
217+
.text(d=>d.data.name);
218+
219+
}
220+
221+
function convert(obj){
222+
223+
if(typeof obj!=="object"||obj==null){
224+
225+
return {name:String(obj)}
226+
227+
}
228+
229+
return{
230+
231+
name:"object",
232+
children:Object.keys(obj).map(k=>({
233+
234+
name:k,
235+
children:[convert(obj[k])]
236+
237+
}))
238+
239+
}
240+
241+
}
242+
243+
function runDiff(){
244+
245+
let a=document.getElementById("jsonInput").value
246+
let b=document.getElementById("jsonInput2").value
247+
248+
let diff=Diff.diffLines(a,b)
249+
250+
let html=""
251+
252+
diff.forEach(part=>{
253+
254+
let color=part.added?"#22c55e":
255+
part.removed?"#ef4444":"#94a3b8"
256+
257+
html+=`<span style="color:${color}">${part.value}</span>`
258+
259+
})
260+
261+
document.getElementById("diffResult").innerHTML=html
262+
263+
}
264+
265+
function detectOpenAPI(json){
266+
267+
let text=""
268+
269+
if(json.openapi){
270+
271+
text+=`<p class="text-green-400">OpenAPI schema detected</p>`
272+
273+
if(json.paths){
274+
275+
text+=`<p>Endpoints detected: ${Object.keys(json.paths).length}</p>`
276+
277+
}
278+
279+
}
280+
281+
else{
282+
283+
text+="Standard JSON structure"
284+
285+
}
286+
287+
document.getElementById("aiExplain").innerHTML=text
288+
289+
}
290+
291+
</script>
292+
293+
</body>
294+
</html>

0 commit comments

Comments
 (0)