|
| 1 | +--- |
| 2 | +// AUTO-GENERATED property-graph hero for python. Encodes the real Neo4j schema |
| 3 | +// (node labels, typed relationships, key properties). Theme-aware via Starlight |
| 4 | +// CSS custom properties; renders as static SVG (no client JS). |
| 5 | +--- |
| 6 | +<figure class="pgraph-figure"> |
| 7 | +<svg class="pgraph" viewBox="0 0 1080 600" role="img" aria-label="codeanalyzer-python · Neo4j property graph" xmlns="http://www.w3.org/2000/svg"> |
| 8 | + <defs> |
| 9 | + <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"> |
| 10 | + <path d="M 0 0 L 10 5 L 0 10 z" fill="var(--pg-edge)"/> |
| 11 | + </marker> |
| 12 | + <marker id="arrow-accent" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"> |
| 13 | + <path d="M 0 0 L 10 5 L 0 10 z" fill="#DA7194"/> |
| 14 | + </marker> |
| 15 | + <radialGradient id="gloss" cx="35%" cy="30%" r="75%"> |
| 16 | + <stop offset="0%" stop-color="#ffffff" stop-opacity="0.35"/> |
| 17 | + <stop offset="55%" stop-color="#ffffff" stop-opacity="0.0"/> |
| 18 | + </radialGradient> |
| 19 | + <filter id="nshadow" x="-30%" y="-30%" width="160%" height="160%"> |
| 20 | + <feDropShadow dx="0" dy="3" stdDeviation="4" flood-color="#0b1020" flood-opacity="0.28"/> |
| 21 | + </filter> |
| 22 | + </defs> |
| 23 | +<path d="M 155.8 271.1 L 292.7 160.2" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 24 | +<g transform="translate(224.2,215.6)"><rect x="-49.5" y="-11" width="99.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_HAS_MODULE</text></g> |
| 25 | +<path d="M 330.0 176.0 L 330.0 422.0" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 26 | +<g transform="translate(330.0,333.4)"><rect x="-42.5" y="-11" width="85.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_DECLARES</text></g> |
| 27 | +<path d="M 284.0 470.0 L 168.0 470.0" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 28 | +<g transform="translate(226.0,470.0)"><rect x="-60.0" y="-11" width="120.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_HAS_ATTRIBUTE</text></g> |
| 29 | +<path d="M 367.0 442.7 L 521.4 328.5" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 30 | +<g transform="translate(444.2,385.6)"><rect x="-49.5" y="-11" width="99.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_HAS_METHOD</text></g> |
| 31 | +<path d="M 560.0 346.0 L 560.0 422.0" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 32 | +<g transform="translate(560.0,394.6)"><rect x="-56.5" y="-11" width="113.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_DECORATED_BY</text></g> |
| 33 | +<path d="M 597.0 272.7 L 751.4 158.5" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 34 | +<g transform="translate(674.2,215.6)"><rect x="-56.5" y="-11" width="113.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_HAS_CALLSITE</text></g> |
| 35 | +<path d="M 823.9 161.1 L 939.7 267.5" class="rel" fill="none" marker-end="url(#arrow)"/> |
| 36 | +<g transform="translate(881.8,214.3)"><rect x="-53.0" y="-11" width="106.0" height="22" rx="11" class="pill"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_RESOLVES_TO</text></g> |
| 37 | +<path d="M 606.0 300.0 Q 734.4 170.0 927.0 300.0" class="rel-accent" fill="none" marker-end="url(#arrow-accent)"/> |
| 38 | +<g transform="translate(725.2,236.7)"><rect x="-32.0" y="-11" width="64.0" height="22" rx="11" class="pill-accent"/><text x="0" y="4" class="rtype" text-anchor="middle">PY_CALLS</text></g> |
| 39 | +<circle cx="120" cy="300" r="46" fill="#C990C0" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 40 | +<circle cx="120" cy="300" r="46" fill="url(#gloss)"/> |
| 41 | +<text x="120" y="304" class="nlabel" text-anchor="middle">:PyApplication</text> |
| 42 | +<text x="120" y="362" class="prop" text-anchor="middle">name</text> |
| 43 | +<text x="120" y="378" class="prop" text-anchor="middle">schema_version</text> |
| 44 | +<circle cx="330" cy="130" r="46" fill="#4C8EDA" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 45 | +<circle cx="330" cy="130" r="46" fill="url(#gloss)"/> |
| 46 | +<text x="330" y="134" class="nlabel" text-anchor="middle">:PyModule</text> |
| 47 | +<text x="330" y="192" class="prop" text-anchor="middle">module_name</text> |
| 48 | +<text x="330" y="208" class="prop" text-anchor="middle">content_hash</text> |
| 49 | +<circle cx="330" cy="470" r="46" fill="#F79767" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 50 | +<circle cx="330" cy="470" r="46" fill="url(#gloss)"/> |
| 51 | +<text x="330" y="466" class="nlabel" text-anchor="middle">:PyClass</text> |
| 52 | +<text x="330" y="483" class="nsub" text-anchor="middle">:PySymbol</text> |
| 53 | +<text x="330" y="532" class="prop" text-anchor="middle">name</text> |
| 54 | +<text x="330" y="548" class="prop" text-anchor="middle">base_classes</text> |
| 55 | +<circle cx="120" cy="470" r="46" fill="#57C7E3" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 56 | +<circle cx="120" cy="470" r="46" fill="url(#gloss)"/> |
| 57 | +<text x="120" y="474" class="nlabel" text-anchor="middle">:PyAttribute</text> |
| 58 | +<text x="120" y="532" class="prop" text-anchor="middle">name</text> |
| 59 | +<text x="120" y="548" class="prop" text-anchor="middle">type</text> |
| 60 | +<circle cx="560" cy="300" r="46" fill="#8DCC93" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 61 | +<circle cx="560" cy="300" r="46" fill="url(#gloss)"/> |
| 62 | +<text x="560" y="296" class="nlabel" text-anchor="middle">:PyCallable</text> |
| 63 | +<text x="560" y="313" class="nsub" text-anchor="middle">:PySymbol</text> |
| 64 | +<text x="560" y="362" class="prop" text-anchor="middle">signature</text> |
| 65 | +<text x="560" y="378" class="prop" text-anchor="middle">cyclomatic_complexity</text> |
| 66 | +<circle cx="560" cy="470" r="46" fill="#ECB5C9" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 67 | +<circle cx="560" cy="470" r="46" fill="url(#gloss)"/> |
| 68 | +<text x="560" y="474" class="nlabel" text-anchor="middle">:PyDecorator</text> |
| 69 | +<text x="560" y="532" class="prop" text-anchor="middle">name</text> |
| 70 | +<circle cx="790" cy="130" r="46" fill="#FFC454" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 71 | +<circle cx="790" cy="130" r="46" fill="url(#gloss)"/> |
| 72 | +<text x="790" y="134" class="nlabel" text-anchor="middle">:PyCallSite</text> |
| 73 | +<text x="790" y="192" class="prop" text-anchor="middle">method_name</text> |
| 74 | +<text x="790" y="208" class="prop" text-anchor="middle">receiver_type</text> |
| 75 | +<circle cx="975" cy="300" r="46" fill="#569480" stroke="#ffffff" stroke-width="2.5" filter="url(#nshadow)"/> |
| 76 | +<circle cx="975" cy="300" r="46" fill="url(#gloss)"/> |
| 77 | +<text x="975" y="304" class="nlabel" text-anchor="middle">:PyExternal</text> |
| 78 | +<text x="975" y="362" class="prop" text-anchor="middle">name</text> |
| 79 | +<text x="975" y="378" class="prop" text-anchor="middle">module</text> |
| 80 | +</svg> |
| 81 | + <figcaption> |
| 82 | + The analysis is a <strong>Neo4j property graph</strong>: every node carries a |
| 83 | + <em>label</em> (its color) and <em>properties</em>; every relationship carries a |
| 84 | + <em>type</em>. The dashed ring marks an <code>entrypoint</code>; |
| 85 | + the <span class="calls">PY_CALLS</span> edge is the resolved call graph. |
| 86 | + </figcaption> |
| 87 | +</figure> |
| 88 | + |
| 89 | +<style> |
| 90 | + .pgraph-figure { |
| 91 | + margin: 1.5rem 0 2rem; |
| 92 | + padding: 0.5rem 0.25rem 0.25rem; |
| 93 | + border: 1px solid var(--sl-color-gray-5); |
| 94 | + border-radius: 14px; |
| 95 | + background: |
| 96 | + radial-gradient(120% 80% at 15% 0%, color-mix(in srgb, var(--sl-color-accent-low) 55%, transparent), transparent 60%), |
| 97 | + var(--sl-color-black); |
| 98 | + overflow: hidden; |
| 99 | + } |
| 100 | + .pgraph { width: 100%; height: auto; display: block; } |
| 101 | + /* edges + labels adapt to theme */ |
| 102 | + .pgraph { --pg-edge: var(--sl-color-gray-3); } |
| 103 | + .pgraph .rel { stroke: var(--pg-edge); stroke-width: 2.2; } |
| 104 | + .pgraph .rel-accent { stroke: #DA7194; stroke-width: 3.2; } |
| 105 | + .pgraph .nlabel { fill: #fff; font: 700 14px/1.1 ui-sans-serif, system-ui, sans-serif; letter-spacing: .2px; } |
| 106 | + .pgraph .nsub { fill: rgba(255,255,255,.92); font: 600 12px ui-sans-serif, system-ui, sans-serif; } |
| 107 | + .pgraph .prop { fill: var(--sl-color-gray-2); font: 500 12px ui-monospace, "SFMono-Regular", monospace; } |
| 108 | + .pgraph .rtype { fill: #fff; font: 700 11px ui-monospace, monospace; letter-spacing: .3px; } |
| 109 | + .pgraph .pill { fill: #3a4252; stroke: rgba(255,255,255,.18); } |
| 110 | + .pgraph .pill-accent { fill: #DA7194; } |
| 111 | + .pgraph .badge { fill: #ffd98a; font: 700 11px ui-monospace, monospace; } |
| 112 | + .pgraph-figure figcaption { |
| 113 | + color: var(--sl-color-gray-2); |
| 114 | + font-size: 0.85rem; line-height: 1.5; |
| 115 | + padding: 0.4rem 1rem 0.75rem; text-align: center; |
| 116 | + } |
| 117 | + .pgraph-figure .calls { color: #DA7194; font-weight: 700; font-family: ui-monospace, monospace; } |
| 118 | +</style> |
0 commit comments