raidAthmaneBenlala commited on
Commit
7d9495f
·
1 Parent(s): 690d566

✨ Upgrade Odontogram to a realistic Curved Parabolic Dental Arch

Browse files
Files changed (1) hide show
  1. toothmap_frontend/src/App.jsx +29 -15
toothmap_frontend/src/App.jsx CHANGED
@@ -19,6 +19,18 @@ const QUADRANT_COLOURS = ['#3b82f6', '#22c55e', '#f59e0b', '#ef4444'];
19
  const UPPER_TEETH = [18, 17, 16, 15, 14, 13, 12, 11, 21, 22, 23, 24, 25, 26, 27, 28];
20
  const LOWER_TEETH = [48, 47, 46, 45, 44, 43, 42, 41, 31, 32, 33, 34, 35, 36, 37, 38];
21
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  function computeIoU(b1, b2) {
23
  const ix = Math.max(b1[0], b2[0]), iy = Math.max(b1[1], b2[1]);
24
  const iw = Math.min(b1[2], b2[2]) - ix, ih = Math.min(b1[3], b2[3]) - iy;
@@ -280,18 +292,19 @@ export default function App() {
280
 
281
  {/* Dental FDI Chart (Odontogram) moved to Main Section */}
282
  {(uniquePipelineResults && mode.includes('pipeline')) && (
283
- <div className="w-full max-w-4xl bg-zinc-900/60 rounded-2xl p-6 border border-zinc-800/80 shadow-2xl mt-4">
284
- <p className="text-sm font-bold text-slate-300 uppercase tracking-widest mb-6 text-center">Comprehensive Dental Chart</p>
285
- <div className="flex flex-col gap-3">
286
- {/* Upper Row */}
287
- <div className="flex w-full justify-between gap-1.5">
288
  {UPPER_TEETH.map((t, idx) => {
289
  const isLeftQuad = idx < 8;
290
  return (
291
  <div key={t}
292
- className={`flex-1 aspect-[3/4] rounded-md flex items-center justify-center text-sm font-bold transition-all transform hover:scale-105 duration-200 cursor-default ${
 
293
  uniquePipelineResults.some(r => r.fdi === t)
294
- ? 'bg-green-500/20 text-green-400 border border-green-500/50 shadow-[0_0_12px_rgba(34,197,94,0.2)]'
295
  : 'bg-zinc-800/80 text-zinc-500 border border-zinc-700/50 opacity-60'
296
  } ${isLeftQuad && idx === 7 ? 'mr-4' : ''}`}>
297
  {t}
@@ -300,21 +313,22 @@ export default function App() {
300
  </div>
301
 
302
  {/* Middle Divider */}
303
- <div className="flex items-center w-full my-1 opacity-50">
304
- <div className="flex-1 h-px bg-zinc-700" />
305
- <div className="px-4 text-[10px] text-zinc-500 font-mono tracking-widest">MAXILLARY / MANDIBULAR</div>
306
- <div className="flex-1 h-px bg-zinc-700" />
307
  </div>
308
 
309
- {/* Lower Row */}
310
- <div className="flex w-full justify-between gap-1.5">
311
  {LOWER_TEETH.map((t, idx) => {
312
  const isLeftQuad = idx < 8;
313
  return (
314
  <div key={t}
315
- className={`flex-1 aspect-[3/4] rounded-md flex items-center justify-center text-sm font-bold transition-all transform hover:scale-105 duration-200 cursor-default ${
 
316
  uniquePipelineResults.some(r => r.fdi === t)
317
- ? 'bg-green-500/20 text-green-400 border border-green-500/50 shadow-[0_0_12px_rgba(34,197,94,0.2)]'
318
  : 'bg-zinc-800/80 text-zinc-500 border border-zinc-700/50 opacity-60'
319
  } ${isLeftQuad && idx === 7 ? 'mr-4' : ''}`}>
320
  {t}
 
19
  const UPPER_TEETH = [18, 17, 16, 15, 14, 13, 12, 11, 21, 22, 23, 24, 25, 26, 27, 28];
20
  const LOWER_TEETH = [48, 47, 46, 45, 44, 43, 42, 41, 31, 32, 33, 34, 35, 36, 37, 38];
21
 
22
+ // Calculates a quadratic offset to form a realistic dental arch (horseshoe layout)
23
+ function getArchStyle(index, isUpper) {
24
+ const max = 56.25; // 7.5 squared
25
+ const val = max - Math.pow(index - 7.5, 2);
26
+ const offset = val * 0.45; // Scale the depth of the curve (approx 25px max)
27
+ const rotation = (index - 7.5) * (isUpper ? -1.5 : 1.5); // Slight tilt to face the center
28
+
29
+ return {
30
+ transform: `translateY(${isUpper ? offset : -offset}px) rotate(${rotation}deg)`
31
+ };
32
+ }
33
+
34
  function computeIoU(b1, b2) {
35
  const ix = Math.max(b1[0], b2[0]), iy = Math.max(b1[1], b2[1]);
36
  const iw = Math.min(b1[2], b2[2]) - ix, ih = Math.min(b1[3], b2[3]) - iy;
 
292
 
293
  {/* Dental FDI Chart (Odontogram) moved to Main Section */}
294
  {(uniquePipelineResults && mode.includes('pipeline')) && (
295
+ <div className="w-full max-w-4xl bg-zinc-900/60 rounded-2xl p-8 border border-zinc-800/80 shadow-2xl mt-4">
296
+ <p className="text-sm font-bold text-slate-300 uppercase tracking-widest mb-10 text-center">Comprehensive Dental Arch</p>
297
+ <div className="flex flex-col gap-6">
298
+ {/* Upper Row (Maxillary) */}
299
+ <div className="flex w-full justify-between gap-1.5 pb-6 relative">
300
  {UPPER_TEETH.map((t, idx) => {
301
  const isLeftQuad = idx < 8;
302
  return (
303
  <div key={t}
304
+ style={getArchStyle(idx, true)}
305
+ className={`flex-1 aspect-[3/4.5] rounded-t-sm rounded-b-2xl flex items-center justify-center text-sm font-bold transition-all transform hover:scale-110 duration-200 cursor-default ${
306
  uniquePipelineResults.some(r => r.fdi === t)
307
+ ? 'bg-gradient-to-b from-green-500/10 to-green-500/30 text-green-400 border border-green-500/50 shadow-[0_4px_12px_rgba(34,197,94,0.25)]'
308
  : 'bg-zinc-800/80 text-zinc-500 border border-zinc-700/50 opacity-60'
309
  } ${isLeftQuad && idx === 7 ? 'mr-4' : ''}`}>
310
  {t}
 
313
  </div>
314
 
315
  {/* Middle Divider */}
316
+ <div className="flex items-center w-full my-4 opacity-70 z-10">
317
+ <div className="flex-1 h-px bg-zinc-700/50" />
318
+ <div className="px-6 text-[10px] text-zinc-400 font-mono tracking-widest">MAXILLARY / MANDIBULAR</div>
319
+ <div className="flex-1 h-px bg-zinc-700/50" />
320
  </div>
321
 
322
+ {/* Lower Row (Mandibular) */}
323
+ <div className="flex w-full justify-between gap-1.5 pt-6 relative">
324
  {LOWER_TEETH.map((t, idx) => {
325
  const isLeftQuad = idx < 8;
326
  return (
327
  <div key={t}
328
+ style={getArchStyle(idx, false)}
329
+ className={`flex-1 aspect-[3/4.5] rounded-b-sm rounded-t-2xl flex items-center justify-center text-sm font-bold transition-all transform hover:scale-110 duration-200 cursor-default ${
330
  uniquePipelineResults.some(r => r.fdi === t)
331
+ ? 'bg-gradient-to-t from-green-500/10 to-green-500/30 text-green-400 border border-green-500/50 shadow-[0_-4px_12px_rgba(34,197,94,0.25)]'
332
  : 'bg-zinc-800/80 text-zinc-500 border border-zinc-700/50 opacity-60'
333
  } ${isLeftQuad && idx === 7 ? 'mr-4' : ''}`}>
334
  {t}