| name | generate-diagram |
| description | v3 SVG diagram generation workflow for MechCodex calculators — layered SVG structure, interactive labels, color palette, React component pattern, diagram types. |
| metadata | {"priority":5,"promptSignals":{"phrases":["generate diagram","SVG diagram","engineering diagram","create diagram","interactive diagram","v3 diagram"],"minScore":4}} |
MechCodex v3 SVG Diagram Generation — Complete Skill
v3 Architecture Pattern
Three-layer structure in every calculator:
- SVG base layer: geometric shapes (lines, paths, circles, polygons)
- HTML overlay: labels, dimensions, interactive buttons
- React state: drives both layers (dimensions, parameters, highlighted states)
React Component Structure
const DiagramPanel = ({ params, highlight, onSelect }) => {
const L = params.L ?? 200;
const scale = 300 / L;
return (
<div className="relative" style={{ width: 360, height: 280 }}>
{/* SVG Base Layer */}
<svg
viewBox="0 0 360 280"
className="absolute inset-0 w-full h-full"
xmlns="http://www.w3.org/2000/svg"
>
{/* Background */}
<rect width="360" height="280" fill="#0f172a" rx="8"/>
{/* Engineering shapes here */}
<path d="..." fill={highlight === 'flange' ? '#f59e0b' : '#334155'} />
{/* Dimension lines */}
<line x1="..." y1="..." x2="..." y2="..." stroke="#64748b" strokeDasharray="4,3"/>
<text x="..." y="..." fill="#94a3b8" fontSize="11" textAnchor="middle">L</text>
</svg>
{/* HTML Overlay Labels */}
<div className="absolute inset-0 pointer-events-none">
<div className="absolute" style={{ left: '45%', top: '12px' }}>
<span className="text-xs text-cyan-400 font-mono">σ_max</span>
</div>
</div>
{/* Interactive Buttons */}
<div className="absolute bottom-2 left-2 flex gap-1">
{['Web', 'Flange', 'NA'].map(zone => (
<button
key={zone}
onClick={() => onSelect(zone)}
className={`text-xs px-2 py-1 rounded ${
highlight === zone ? 'bg-cyan-500 text-slate-900' : 'bg-slate-700 text-slate-300'
}`}
>
{zone}
</button>
))}
</div>
</div>
);
};
Color Palette (Dark Theme — MechCodex Standard)
Background: #0f172a (slate-900)
Panel: #1e293b (slate-800)
Border: #334155 (slate-700)
Steel/neutral: #64748b (slate-500)
Highlight A: #06b6d4 (cyan-500)
Highlight B: #f59e0b (amber-500)
Highlight C: #a78bfa (violet-400)
Danger/fail: #ef4444 (red-500)
Pass/ok: #22c55e (green-500)
Dim lines: #475569 (slate-600)
Text light: #f8fafc (slate-50)
Text mid: #94a3b8 (slate-400)
Text dim: #64748b (slate-500)
Common Shape Patterns
I-Beam Section
<rect x="120" y="60" width="120" height="12" fill="#334155" stroke="#06b6d4" strokeWidth="1"/>
<rect x="172" y="72" width="16" height="96" fill="#334155" stroke="#475569" strokeWidth="1"/>
<rect x="120" y="168" width="120" height="12" fill="#334155" stroke="#06b6d4" strokeWidth="1"/>
Round Shaft
<circle cx="180" cy="140" r="40" fill="none" stroke="#06b6d4" strokeWidth="2"/>
<line x1="180" y1="100" x2="180" y2="180" stroke="#475569" strokeWidth="1" strokeDasharray="4,4"/>
<line x1="140" y1="140" x2="220" y2="140" stroke="#475569" strokeWidth="1" strokeDasharray="4,4"/>
<line x1="180" y1="140" x2="220" y2="140" stroke="#f59e0b" strokeWidth="1.5" =/>
Stress Distribution
<polygon points="160,60 200,60 180,140" fill="#ef4444" fillOpacity="0.3" stroke="#ef4444"/>
<polygon points="160,220 200,220 180,140" fill="#06b6d4" fillOpacity="0.3" stroke="#06b6d4"/>
<line x1="140" y1="140" x2="220" y2="140" stroke="#f59e0b" strokeWidth="1.5" strokeDasharray="6,3"/>
Load Arrows
<defs>
<marker id="arrowDown" markerWidth="6" markerHeight="6" refX="3" refY="6" orient="auto">
<polygon points="0,0 6,0 3,6" fill="#ef4444"/>
</marker>
</defs>
<line x1="180" y1="30" x2="180" y2="70" stroke="#ef4444" strokeWidth="2" markerEnd="url(#arrowDown)"/>
Fixed Support (Hatching)
<line x1="60" y1="100" x2="60" y2="180" stroke="#64748b" strokeWidth="2"/>
<line x1="40" y1="100" x2="60" y2="100" stroke="#64748b" strokeWidth="1.5"/>
{Array.from({length: 7}, (_, i) => (
<line key={i} x1="40" y1={100 + i*13} x2="60" y2={110 + i*13} stroke="#64748b" strokeWidth="1"/>
))}
Dimension Lines
<defs>
<marker id="dimArrow" markerWidth="5" markerHeight="5" refX="0" refY="2.5" orient="auto">
<polygon points="0,0 0,5 5,2.5" fill="#64748b"/>
</marker>
</defs>
<line x1="120" y1="240" x2="240" y2="240" stroke="#64748b" strokeWidth="1"
markerStart="url(#dimArrow)" markerEnd="url(#dimArrow)"/>
<line x1="120" y1="180" x2="120" y2="245" stroke="#64748b" strokeWidth="0.75" strokeDasharray=/>
L = 500 mm
Diagram Types for Each Calculator
| Calculator | Required Diagrams |
|---|
| Shaft | Cross-section, side view with loads, Mohr's circle |
| Beam | Loading diagram, SFD, BMD (3 SVGs) |
| Gear | Gear mesh cross-section, tooth geometry, force diagram |
| Pressure vessel | Shell cross-section, head types comparison |
| Column | Buckled shape (Euler modes 1-4), effective length animation |
| Weld | Joint types (fillet/groove), throat dimension, force direction |
| Spring | Free body, coil geometry, Wahl factor chart |
| Heat exchanger | Shell-and-tube cross-section, LMTD diagram |
| Fin | Temperature distribution, fin geometry |
Minimum Diagram Requirements (Audit)
Every calculator MUST have:
- ≥ 2 SVG diagrams (theory tab counts separately from interactive)
- Interactive highlighting (click to highlight region)
- Dimension labels that update with input values
- Correct engineering notation (forces with arrows, stress distributions filled)
- Color coding: loads=red, reactions=cyan, stress=amber, neutral axis=yellow dashed
Output
Provide: complete React component code with SVG + HTML overlay, interactive button states, responsive scaling, correct engineering notation.