create-slide-deck 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +119 -0
- package/package.json +36 -0
- package/template-full/README.md +99 -0
- package/template-full/package.json +47 -0
- package/template-full/src/reveal/components/auto-layout.ts +229 -0
- package/template-full/src/reveal/components/charts.tsx +213 -0
- package/template-full/src/reveal/core/blocks.ts +172 -0
- package/template-full/src/reveal/core/deck-init.ts +60 -0
- package/template-full/src/reveal/core/design.ts +46 -0
- package/template-full/src/reveal/core/layout.ts +187 -0
- package/template-full/src/reveal/core/mount-registry.ts +41 -0
- package/template-full/src/reveal/core/presets.ts +189 -0
- package/template-full/src/reveal/core/runtime.ts +141 -0
- package/template-full/src/reveal/core/types.ts +114 -0
- package/template-full/src/reveal/data/algorithms.ts +78 -0
- package/template-full/src/reveal/data/benchmark.ts +79 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-arc-progress.tsx +153 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-before-after.tsx +164 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-bigtext.tsx +70 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-card-flip.tsx +118 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-chat-bubbles.tsx +257 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-code.tsx +136 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-concept-map.tsx +336 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-counter.tsx +194 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-cover.tsx +188 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-dark-dashboard.tsx +166 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-eval-matrix.tsx +191 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-force-graph.tsx +169 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-bars.tsx +109 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-flow.tsx +177 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-heatmap.tsx +135 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-icon-wall.tsx +143 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-math.tsx +103 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-number-morph.tsx +126 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-path.tsx +185 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-radar.tsx +124 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-rough.tsx +169 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-sankey.tsx +144 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-screenshot-annotate.tsx +181 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-stacked-cards.tsx +159 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-tabs.tsx +206 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-timeline.tsx +162 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-treemap.tsx +161 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-zoom-focus.tsx +223 -0
- package/template-full/src/reveal/decks/demo-showcase/components/registry.ts +63 -0
- package/template-full/src/reveal/decks/demo-showcase/demo.css +237 -0
- package/template-full/src/reveal/decks/demo-showcase/index.html +24 -0
- package/template-full/src/reveal/decks/demo-showcase/main.ts +7 -0
- package/template-full/src/reveal/decks/demo-showcase/slides.ts +271 -0
- package/template-full/src/reveal/decks/fse26-rca/components/aws-cascade.tsx +295 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-compare.tsx +64 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-deficiency.tsx +104 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-loop.tsx +402 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-needs.tsx +78 -0
- package/template-full/src/reveal/decks/fse26-rca/components/closing-takeaway.tsx +165 -0
- package/template-full/src/reveal/decks/fse26-rca/components/cloud-incidents.tsx +88 -0
- package/template-full/src/reveal/decks/fse26-rca/components/failure-modes.tsx +59 -0
- package/template-full/src/reveal/decks/fse26-rca/components/fault-heatmap.tsx +85 -0
- package/template-full/src/reveal/decks/fse26-rca/components/hierarchy-tree.tsx +93 -0
- package/template-full/src/reveal/decks/fse26-rca/components/incident-hard.tsx +72 -0
- package/template-full/src/reveal/decks/fse26-rca/components/rca-pipeline.tsx +193 -0
- package/template-full/src/reveal/decks/fse26-rca/components/registry.ts +37 -0
- package/template-full/src/reveal/decks/fse26-rca/components/simple-rca.tsx +216 -0
- package/template-full/src/reveal/decks/fse26-rca/components/sota-collapse.tsx +63 -0
- package/template-full/src/reveal/decks/fse26-rca/components/srca-results.tsx +115 -0
- package/template-full/src/reveal/decks/fse26-rca/images/aws-outage-2025-deployflow.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/aws-post-event-summary.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/bbc-crowdstrike.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/cnn-meta-outage-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/cover.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/nyt-facebook-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/qr-repo.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/verge-crowdstrike-2024.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/wiki-meta-outage-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/index.html +30 -0
- package/template-full/src/reveal/decks/fse26-rca/main.ts +8 -0
- package/template-full/src/reveal/decks/fse26-rca/slides.ts +175 -0
- package/template-full/src/reveal/env.d.ts +38 -0
- package/template-full/src/reveal/theme.css +762 -0
- package/template-full/src/reveal/tools/dev.mjs +120 -0
- package/template-full/src/reveal/tools/export-pdf.mjs +86 -0
- package/template-full/src/reveal/tools/preview.mjs +132 -0
- package/template-full/tsconfig.json +19 -0
- package/template-full/vite.config.ts +95 -0
- package/template-minimal/package.json +42 -0
- package/template-minimal/src/reveal/components/auto-layout.ts +229 -0
- package/template-minimal/src/reveal/components/charts.tsx +213 -0
- package/template-minimal/src/reveal/core/blocks.ts +172 -0
- package/template-minimal/src/reveal/core/deck-init.ts +60 -0
- package/template-minimal/src/reveal/core/design.ts +46 -0
- package/template-minimal/src/reveal/core/layout.ts +187 -0
- package/template-minimal/src/reveal/core/mount-registry.ts +41 -0
- package/template-minimal/src/reveal/core/presets.ts +189 -0
- package/template-minimal/src/reveal/core/runtime.ts +141 -0
- package/template-minimal/src/reveal/core/types.ts +114 -0
- package/template-minimal/src/reveal/data/.gitkeep +0 -0
- package/template-minimal/src/reveal/decks/my-deck/components/example-component.tsx +28 -0
- package/template-minimal/src/reveal/decks/my-deck/components/registry.ts +9 -0
- package/template-minimal/src/reveal/decks/my-deck/index.html +14 -0
- package/template-minimal/src/reveal/decks/my-deck/main.ts +5 -0
- package/template-minimal/src/reveal/decks/my-deck/slides.ts +34 -0
- package/template-minimal/src/reveal/env.d.ts +38 -0
- package/template-minimal/src/reveal/theme.css +762 -0
- package/template-minimal/tsconfig.json +19 -0
- package/template-minimal/vite.config.ts +95 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
3
|
+
import { findEmptySlot, nodeOccupiedRects } from "../../../components/auto-layout.ts";
|
|
4
|
+
import { NODE, DETAIL, EDGE, CANVAS, annotationStyle, illustrationStyle, annotationTitleStyle, vis, visExact, SlideCanvas } from "../../../core/presets.ts";
|
|
5
|
+
|
|
6
|
+
const NODES = [
|
|
7
|
+
{ id: "failure", label: "Failure", sub: "user-visible", color: "#C00000", col: 0, row: 0, step: 0 },
|
|
8
|
+
{ id: "metrics", label: "Metrics", sub: "time-series values", color: "#00A6D6", col: 1, row: 0, step: 1 },
|
|
9
|
+
{ id: "logs", label: "Logs", sub: "event text", color: "#1B556B", col: 1, row: 1, step: 2 },
|
|
10
|
+
{ id: "traces", label: "Traces", sub: "request spans", color: "#76B82A", col: 1, row: 2, step: 3 },
|
|
11
|
+
{ id: "model", label: "RCA Model", sub: "graph / ML / causal",color: "#E8912D", col: 2, row: 1, step: 4 },
|
|
12
|
+
{ id: "rank", label: "Top-K", sub: "ranked causes", color: "#C00000", col: 3, row: 1, step: 5 },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const ICON_PATHS = {
|
|
16
|
+
failure: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4m0 4h.01",
|
|
17
|
+
metrics: "M3 3v18h18M7 16l4-8 4 4 4-6",
|
|
18
|
+
logs: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8zM14 2v6h6M8 13h8M8 17h8M8 9h2",
|
|
19
|
+
traces: "M3 12h4l3-9 4 18 3-9h4",
|
|
20
|
+
model: "M12 2a8 8 0 0 0-8 8c0 6 8 12 8 12s8-6 8-12a8 8 0 0 0-8-8zm0 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6z",
|
|
21
|
+
rank: "M9 11l3 3 8-8M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const DETAILS = [
|
|
25
|
+
null,
|
|
26
|
+
{ vb: "0 0 280 100",
|
|
27
|
+
illustration: (
|
|
28
|
+
<g>
|
|
29
|
+
<line x1="10" y1="70" x2="190" y2="70" stroke="#ddd" strokeWidth="1.5" />
|
|
30
|
+
<line x1="10" y1="70" x2="10" y2="10" stroke="#ddd" strokeWidth="1.5" />
|
|
31
|
+
<polyline points="20,55 50,52 80,48 100,30 110,15 130,35 160,40 180,45" fill="none" stroke="#00A6D6" strokeWidth="2.5" />
|
|
32
|
+
<circle cx="110" cy="15" r="4" fill="#C00000" />
|
|
33
|
+
<text x="110" y="8" textAnchor="middle" fontSize="14" fill="#C00000" fontWeight="800">spike</text>
|
|
34
|
+
<text x="100" y="78" textAnchor="middle" fontSize="14" fill="#999" fontWeight="700">time</text>
|
|
35
|
+
</g>
|
|
36
|
+
),
|
|
37
|
+
lines: ["Numeric values over time: CPU, latency, error rate ..."],
|
|
38
|
+
},
|
|
39
|
+
{ vb: "0 0 300 90",
|
|
40
|
+
illustration: (
|
|
41
|
+
<g>
|
|
42
|
+
<rect x="4" y="4" width="212" height="14" rx="3" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
43
|
+
<text x="8" y="14" fontSize="14" fill="#999" fontWeight="600">10:03:21 INFO request completed 200</text>
|
|
44
|
+
<rect x="4" y="22" width="212" height="14" rx="3" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
45
|
+
<text x="8" y="32" fontSize="14" fill="#999" fontWeight="600">10:03:22 WARN latency exceeded 500ms</text>
|
|
46
|
+
<rect x="4" y="40" width="212" height="14" rx="3" fill="#FFF3F3" stroke="#C00000" strokeWidth="1.5" />
|
|
47
|
+
<text x="8" y="50" fontSize="14" fill="#C00000" fontWeight="800">10:03:23 ERROR connection refused db-svc</text>
|
|
48
|
+
<rect x="4" y="58" width="212" height="14" rx="3" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
49
|
+
<text x="8" y="68" fontSize="14" fill="#999" fontWeight="600">10:03:24 INFO retry attempt 1/3</text>
|
|
50
|
+
</g>
|
|
51
|
+
),
|
|
52
|
+
lines: ["Structured event text: errors, warnings, exceptions ..."],
|
|
53
|
+
},
|
|
54
|
+
{ vb: "0 0 300 90",
|
|
55
|
+
illustration: (
|
|
56
|
+
<g>
|
|
57
|
+
<rect x="4" y="8" width="80" height="12" rx="3" fill="#00A6D6" opacity="0.3" />
|
|
58
|
+
<text x="44" y="17" textAnchor="middle" fontSize="14" fill="#00739A" fontWeight="700">API gateway</text>
|
|
59
|
+
<rect x="30" y="26" width="70" height="12" rx="3" fill="#76B82A" opacity="0.3" />
|
|
60
|
+
<text x="65" y="35" textAnchor="middle" fontSize="14" fill="#4A7A10" fontWeight="700">order-svc</text>
|
|
61
|
+
<rect x="56" y="44" width="90" height="12" rx="3" fill="#C00000" opacity="0.3" />
|
|
62
|
+
<text x="101" y="53" textAnchor="middle" fontSize="14" fill="#C00000" fontWeight="700">db-svc (timeout)</text>
|
|
63
|
+
<line x1="84" y1="14" x2="100" y2="14" stroke="#ddd" strokeWidth="1" strokeDasharray="3 2" />
|
|
64
|
+
<line x1="100" y1="32" x2="146" y2="32" stroke="#ddd" strokeWidth="1" strokeDasharray="3 2" />
|
|
65
|
+
</g>
|
|
66
|
+
),
|
|
67
|
+
lines: ["Request path across services: which span is slow or failing"],
|
|
68
|
+
},
|
|
69
|
+
null,
|
|
70
|
+
null,
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
const COL_W = 180;
|
|
74
|
+
const ROW_H = 110;
|
|
75
|
+
const GAP_X = 120;
|
|
76
|
+
const GAP_Y = 16;
|
|
77
|
+
const PAD_X = 30;
|
|
78
|
+
const PAD_Y = 20;
|
|
79
|
+
const ICON_R = NODE.radius - 8;
|
|
80
|
+
const DETAIL_W = DETAIL.width + 40;
|
|
81
|
+
const DETAIL_H = DETAIL.height + 20;
|
|
82
|
+
|
|
83
|
+
function nx(col: number) { return PAD_X + col * (COL_W + GAP_X) + COL_W / 2; }
|
|
84
|
+
function ny(row: number) { return PAD_Y + row * (ROW_H + GAP_Y) + ICON_R + 8; }
|
|
85
|
+
|
|
86
|
+
const LINKS = [
|
|
87
|
+
{ from: 0, to: 1, step: 1 },
|
|
88
|
+
{ from: 0, to: 2, step: 2 },
|
|
89
|
+
{ from: 0, to: 3, step: 3 },
|
|
90
|
+
{ from: 1, to: 4, step: 4 },
|
|
91
|
+
{ from: 2, to: 4, step: 4 },
|
|
92
|
+
{ from: 3, to: 4, step: 4 },
|
|
93
|
+
{ from: 4, to: 5, step: 5 },
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
// vis, visExact imported from presets
|
|
97
|
+
|
|
98
|
+
function arrowPath(x1: number, y1: number, x2: number, y2: number) {
|
|
99
|
+
const mid = (x1 + x2) / 2;
|
|
100
|
+
return `M${x1},${y1} C${mid},${y1} ${mid},${y2} ${x2},${y2}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function anchorPt(n: (typeof NODES)[number], side: string) {
|
|
104
|
+
const cx = nx(n.col), cy = ny(n.row);
|
|
105
|
+
const r = ICON_R;
|
|
106
|
+
switch (side) {
|
|
107
|
+
case "right": return [cx + r + 6, cy];
|
|
108
|
+
case "left": return [cx - r - 6, cy];
|
|
109
|
+
default: return [cx, cy];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function NodeIcon({ node, step, instant }: { node: (typeof NODES)[number]; step: number; instant: boolean }) {
|
|
114
|
+
const cx = nx(node.col), cy = ny(node.row);
|
|
115
|
+
const r = ICON_R;
|
|
116
|
+
return (
|
|
117
|
+
<g style={vis(step, node.step, instant)}>
|
|
118
|
+
<circle cx={cx} cy={cy} r={r + 5} fill={node.color + "11"} />
|
|
119
|
+
<circle cx={cx} cy={cy} r={r} fill="white" stroke={node.color} strokeWidth={NODE.strokeWidth} />
|
|
120
|
+
<g transform={`translate(${cx - NODE.iconSize/2}, ${cy - NODE.iconSize/2})`}>
|
|
121
|
+
<svg width={NODE.iconSize} height={NODE.iconSize} viewBox="0 0 24 24" fill="none"
|
|
122
|
+
stroke={node.color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
123
|
+
<path d={(ICON_PATHS as any)[node.id]} />
|
|
124
|
+
</svg>
|
|
125
|
+
</g>
|
|
126
|
+
<text x={cx} y={cy + r + 20} textAnchor="middle" fontSize={NODE.labelFont} fontWeight="900"
|
|
127
|
+
fill={NODE.labelColor} fontFamily={CANVAS.fontFamily}>{node.label}</text>
|
|
128
|
+
<text x={cx} y={cy + r + 38} textAnchor="middle" fontSize={NODE.subFont} fontWeight="700"
|
|
129
|
+
fill={node.color} fontFamily={CANVAS.fontFamily}>{node.sub}</text>
|
|
130
|
+
</g>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function DetailAnnotation({ detail, step, currentStep, svgW, svgH, instant }: { detail: (typeof DETAILS)[number]; step: number; currentStep: number; svgW: number; svgH: number; instant: boolean }) {
|
|
135
|
+
if (!detail) return null;
|
|
136
|
+
const node = NODES[step];
|
|
137
|
+
const occupied = nodeOccupiedRects(NODES, step, { nx, ny, iconR: ICON_R, labelH: 44 });
|
|
138
|
+
const pos = findEmptySlot({
|
|
139
|
+
canvasW: svgW, canvasH: svgH,
|
|
140
|
+
occupied, slotW: DETAIL_W, slotH: DETAIL_H,
|
|
141
|
+
margin: DETAIL.margin,
|
|
142
|
+
near: { x: nx(node.col), y: ny(node.row) },
|
|
143
|
+
step: DETAIL.scanStep,
|
|
144
|
+
});
|
|
145
|
+
return (
|
|
146
|
+
<g style={visExact(currentStep, step, instant)}>
|
|
147
|
+
<rect x={pos.x} y={pos.y} width={DETAIL_W} height={DETAIL_H} rx="12"
|
|
148
|
+
fill="white" fillOpacity={DETAIL.bgOpacity} stroke="none" />
|
|
149
|
+
<foreignObject x={pos.x} y={pos.y} width={DETAIL_W} height={DETAIL_H}>
|
|
150
|
+
<div style={annotationStyle()}>
|
|
151
|
+
<svg style={illustrationStyle()} viewBox={detail.vb}>
|
|
152
|
+
{detail.illustration}
|
|
153
|
+
</svg>
|
|
154
|
+
<div style={{ flex: "1 1 auto", display: "flex", flexDirection: "column", justifyContent: "center" }}>
|
|
155
|
+
<div style={annotationTitleStyle()}>
|
|
156
|
+
{detail.lines[0]}
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</foreignObject>
|
|
161
|
+
</g>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const SVG_W = 4 * COL_W + 3 * GAP_X + 2 * PAD_X;
|
|
166
|
+
const SVG_H = 3 * ROW_H + 2 * GAP_Y + 2 * PAD_Y + 60;
|
|
167
|
+
|
|
168
|
+
// getStep imported from presets
|
|
169
|
+
|
|
170
|
+
export default function RcaPipeline({ Reveal }: SlideComponentProps) {
|
|
171
|
+
return (
|
|
172
|
+
<SlideCanvas Reveal={Reveal} W={SVG_W} H={SVG_H}>{(step, instant) => <>
|
|
173
|
+
<defs>
|
|
174
|
+
<marker id="pipe-arr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
175
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#BFBFBF" />
|
|
176
|
+
</marker>
|
|
177
|
+
</defs>
|
|
178
|
+
|
|
179
|
+
{LINKS.map((link, i) => {
|
|
180
|
+
const from = NODES[link.from], to = NODES[link.to];
|
|
181
|
+
const p1 = anchorPt(from, "right");
|
|
182
|
+
const p2 = anchorPt(to, "left");
|
|
183
|
+
return <path key={i} d={arrowPath(p1[0], p1[1], p2[0], p2[1])}
|
|
184
|
+
fill="none" stroke="#BFBFBF" strokeWidth="2.5" strokeLinecap="round"
|
|
185
|
+
markerEnd="url(#pipe-arr)" style={vis(step, link.step, instant)} />;
|
|
186
|
+
})}
|
|
187
|
+
|
|
188
|
+
{NODES.map((n) => <NodeIcon key={n.id} node={n} step={step} instant={instant} />)}
|
|
189
|
+
|
|
190
|
+
{DETAILS.map((d, i) => d && <DetailAnnotation key={i} detail={d} step={i} currentStep={step} svgW={SVG_W} svgH={SVG_H} instant={instant} />)}
|
|
191
|
+
</>}</SlideCanvas>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
3
|
+
import AwsCascade from "./aws-cascade.tsx";
|
|
4
|
+
import RcaPipeline from "./rca-pipeline.tsx";
|
|
5
|
+
import SimpleRca from "./simple-rca.tsx";
|
|
6
|
+
import SrcaResults from "./srca-results.tsx";
|
|
7
|
+
import BenchDeficiency from "./bench-deficiency.tsx";
|
|
8
|
+
import BenchLoop from "./bench-loop.tsx";
|
|
9
|
+
import HierarchyTree from "./hierarchy-tree.tsx";
|
|
10
|
+
import BenchCompare from "./bench-compare.tsx";
|
|
11
|
+
import SotaCollapse from "./sota-collapse.tsx";
|
|
12
|
+
import FaultHeatmap from "./fault-heatmap.tsx";
|
|
13
|
+
import FailureModes from "./failure-modes.tsx";
|
|
14
|
+
import ClosingTakeaway from "./closing-takeaway.tsx";
|
|
15
|
+
import IncidentHard from "./incident-hard.tsx";
|
|
16
|
+
import BenchNeeds from "./bench-needs.tsx";
|
|
17
|
+
import CloudIncidents from "./cloud-incidents.tsx";
|
|
18
|
+
|
|
19
|
+
export const components = {
|
|
20
|
+
AwsCascade,
|
|
21
|
+
RcaPipeline,
|
|
22
|
+
SimpleRca,
|
|
23
|
+
SrcaResults,
|
|
24
|
+
BenchDeficiency,
|
|
25
|
+
BenchLoop,
|
|
26
|
+
HierarchyTree,
|
|
27
|
+
BenchCompare,
|
|
28
|
+
SotaCollapse,
|
|
29
|
+
FaultHeatmap,
|
|
30
|
+
FailureModes,
|
|
31
|
+
ClosingTakeaway,
|
|
32
|
+
IncidentHard,
|
|
33
|
+
BenchNeeds,
|
|
34
|
+
CloudIncidents,
|
|
35
|
+
} satisfies Record<string, ComponentType<SlideComponentProps>>;
|
|
36
|
+
|
|
37
|
+
export type ComponentName = keyof typeof components;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
3
|
+
import { findEmptySlot, nodeOccupiedRects } from "../../../components/auto-layout.ts";
|
|
4
|
+
import { NODE, DETAIL, EDGE, CANVAS, annotationStyle, illustrationStyle, annotationTitleStyle, vis, visExact, SlideCanvas } from "../../../core/presets.ts";
|
|
5
|
+
|
|
6
|
+
const NODES = [
|
|
7
|
+
{ id: "metrics", label: "Metrics", sub: "threshold check", color: "#00A6D6", col: 0, row: 0, step: 0 },
|
|
8
|
+
{ id: "traces", label: "Traces", sub: "latency check", color: "#76B82A", col: 0, row: 1, step: 1 },
|
|
9
|
+
{ id: "logs", label: "Logs", sub: "keyword match", color: "#1B556B", col: 0, row: 2, step: 2 },
|
|
10
|
+
{ id: "count", label: "Count alerts", sub: "per service", color: "#E8912D", col: 1, row: 1, step: 3 },
|
|
11
|
+
{ id: "rank", label: "Rank services", sub: "most alerts first", color: "#C00000", col: 2, row: 1, step: 4 },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const ICON_PATHS = {
|
|
15
|
+
metrics: "M3 3v18h18M7 16l4-8 4 4 4-6",
|
|
16
|
+
traces: "M3 12h4l3-9 4 18 3-9h4",
|
|
17
|
+
logs: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8zM14 2v6h6M8 13h8M8 17h8M8 9h2",
|
|
18
|
+
count: "M3 3h18v18H3zM3 9h18M3 15h18M9 3v18",
|
|
19
|
+
rank: "M4 6h16M4 12h10M4 18h5",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const DETAILS = [
|
|
23
|
+
{
|
|
24
|
+
vb: "0 0 300 100",
|
|
25
|
+
illustration: (
|
|
26
|
+
<g>
|
|
27
|
+
<line x1="10" y1="70" x2="210" y2="70" stroke="#ddd" strokeWidth="1.5" />
|
|
28
|
+
<line x1="10" y1="70" x2="10" y2="10" stroke="#ddd" strokeWidth="1.5" />
|
|
29
|
+
<line x1="10" y1="28" x2="210" y2="28" stroke="#C00000" strokeWidth="1.5" strokeDasharray="4 3" />
|
|
30
|
+
<text x="210" y="22" textAnchor="end" fontSize="14" fill="#C00000" fontWeight="700">threshold</text>
|
|
31
|
+
<polyline points="20,55 50,52 80,48 100,24 120,16 140,42 160,50 180,48" fill="none" stroke="#00A6D6" strokeWidth="2.5" />
|
|
32
|
+
<circle cx="100" cy="24" r="4" fill="#C00000" />
|
|
33
|
+
<circle cx="120" cy="16" r="4" fill="#C00000" />
|
|
34
|
+
<text x="110" y="8" textAnchor="middle" fontSize="14" fill="#C00000" fontWeight="800">alert</text>
|
|
35
|
+
</g>
|
|
36
|
+
),
|
|
37
|
+
lines: ["Metric values above threshold counted as alerts"],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
vb: "0 0 300 90",
|
|
41
|
+
illustration: (
|
|
42
|
+
<g>
|
|
43
|
+
<rect x="4" y="6" width="100" height="13" rx="3" fill="#00A6D6" opacity="0.25" />
|
|
44
|
+
<text x="54" y="16" textAnchor="middle" fontSize="14" fill="#00739A" fontWeight="700">gateway 12ms</text>
|
|
45
|
+
<rect x="30" y="25" width="80" height="13" rx="3" fill="#76B82A" opacity="0.25" />
|
|
46
|
+
<text x="70" y="35" textAnchor="middle" fontSize="14" fill="#4A7A10" fontWeight="700">order-svc 8ms</text>
|
|
47
|
+
<rect x="56" y="44" width="155" height="13" rx="3" fill="#C00000" opacity="0.25" />
|
|
48
|
+
<text x="133" y="54" textAnchor="middle" fontSize="14" fill="#C00000" fontWeight="800">db-svc 580ms</text>
|
|
49
|
+
<text x="218" y="54" fontSize="14" fill="#C00000" fontWeight="900">!</text>
|
|
50
|
+
</g>
|
|
51
|
+
),
|
|
52
|
+
lines: ["Span latency above threshold counted as alerts"],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
vb: "0 0 300 96",
|
|
56
|
+
illustration: (
|
|
57
|
+
<g>
|
|
58
|
+
<rect x="4" y="4" width="212" height="14" rx="3" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
59
|
+
<text x="8" y="14" fontSize="14" fill="#999" fontWeight="600">10:03:21 INFO request ok</text>
|
|
60
|
+
<rect x="4" y="22" width="212" height="14" rx="3" fill="#FFF3F3" stroke="#C00000" strokeWidth="1.5" />
|
|
61
|
+
<text x="8" y="32" fontSize="14" fill="#C00000" fontWeight="800">10:03:22 ERROR conn refused</text>
|
|
62
|
+
<rect x="4" y="40" width="212" height="14" rx="3" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
63
|
+
<text x="8" y="50" fontSize="14" fill="#999" fontWeight="600">10:03:23 INFO retry 1/3</text>
|
|
64
|
+
<rect x="4" y="58" width="212" height="14" rx="3" fill="#FFF3F3" stroke="#C00000" strokeWidth="1.5" />
|
|
65
|
+
<text x="8" y="68" fontSize="14" fill="#C00000" fontWeight="800">10:03:24 ERROR timeout</text>
|
|
66
|
+
</g>
|
|
67
|
+
),
|
|
68
|
+
lines: ["Lines matching error keywords counted as alerts"],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
vb: "0 0 280 100",
|
|
72
|
+
illustration: (
|
|
73
|
+
<g>
|
|
74
|
+
<text x="16" y="14" fontSize="14" fill="#313131" fontWeight="800">Service</text>
|
|
75
|
+
<text x="140" y="14" fontSize="14" fill="#313131" fontWeight="800">Alerts</text>
|
|
76
|
+
<line x1="10" y1="20" x2="190" y2="20" stroke="#ddd" strokeWidth="1" />
|
|
77
|
+
<text x="16" y="36" fontSize="14" fill="#767676" fontWeight="700">ts-order</text>
|
|
78
|
+
<text x="155" y="36" fontSize="14" fill="#E8912D" fontWeight="900">12</text>
|
|
79
|
+
<text x="16" y="52" fontSize="14" fill="#767676" fontWeight="700">ts-travel</text>
|
|
80
|
+
<text x="155" y="52" fontSize="14" fill="#E8912D" fontWeight="900">5</text>
|
|
81
|
+
<text x="16" y="68" fontSize="14" fill="#767676" fontWeight="700">ts-auth</text>
|
|
82
|
+
<text x="155" y="68" fontSize="14" fill="#E8912D" fontWeight="900">2</text>
|
|
83
|
+
</g>
|
|
84
|
+
),
|
|
85
|
+
lines: ["Sum metric + trace + log alerts per service"],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
vb: "0 0 280 100",
|
|
89
|
+
illustration: (
|
|
90
|
+
<g>
|
|
91
|
+
<rect x="8" y="4" width="194" height="20" rx="4" fill="#C00000" fillOpacity="0.1" stroke="#C00000" strokeWidth="1.5" />
|
|
92
|
+
<text x="16" y="18" fontSize="14" fill="#C00000" fontWeight="900">#1 ts-order — 12 alerts</text>
|
|
93
|
+
<rect x="8" y="30" width="194" height="20" rx="4" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
94
|
+
<text x="16" y="44" fontSize="14" fill="#767676" fontWeight="700">#2 ts-travel — 5 alerts</text>
|
|
95
|
+
<rect x="8" y="56" width="194" height="20" rx="4" fill="#F5F5F5" stroke="#ddd" strokeWidth="1" />
|
|
96
|
+
<text x="16" y="70" fontSize="14" fill="#767676" fontWeight="700">#3 ts-auth — 2 alerts</text>
|
|
97
|
+
</g>
|
|
98
|
+
),
|
|
99
|
+
lines: ["Most-alerted service = predicted root cause"],
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
const COL_W = 180;
|
|
104
|
+
const ROW_H = 110;
|
|
105
|
+
const GAP_X = 200;
|
|
106
|
+
const GAP_Y = 16;
|
|
107
|
+
const PAD_X = 40;
|
|
108
|
+
const PAD_Y = 20;
|
|
109
|
+
const ICON_R = NODE.radius - 8;
|
|
110
|
+
const DETAIL_W = DETAIL.width;
|
|
111
|
+
const DETAIL_H = DETAIL.height;
|
|
112
|
+
|
|
113
|
+
function nx(col: number) { return PAD_X + col * (COL_W + GAP_X) + COL_W / 2; }
|
|
114
|
+
function ny(row: number) { return PAD_Y + row * (ROW_H + GAP_Y) + ICON_R + 8; }
|
|
115
|
+
|
|
116
|
+
const LINKS = [
|
|
117
|
+
{ from: 0, to: 3, step: 3 },
|
|
118
|
+
{ from: 1, to: 3, step: 3 },
|
|
119
|
+
{ from: 2, to: 3, step: 3 },
|
|
120
|
+
{ from: 3, to: 4, step: 4 },
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
function arrowPath(x1: number, y1: number, x2: number, y2: number) {
|
|
124
|
+
const mid = (x1 + x2) / 2;
|
|
125
|
+
return "M" + x1 + "," + y1 + " C" + mid + "," + y1 + " " + mid + "," + y2 + " " + x2 + "," + y2;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function anchorPt(n: any, side: string) {
|
|
129
|
+
const cx = nx(n.col), cy = ny(n.row);
|
|
130
|
+
const r = ICON_R;
|
|
131
|
+
if (side === "right") return [cx + r + 6, cy];
|
|
132
|
+
if (side === "left") return [cx - r - 6, cy];
|
|
133
|
+
return [cx, cy];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function NodeIcon({ node, step, instant }: { node: any; step: number; instant: boolean }) {
|
|
137
|
+
const cx = nx(node.col), cy = ny(node.row);
|
|
138
|
+
const r = ICON_R;
|
|
139
|
+
return (
|
|
140
|
+
<g style={vis(step, node.step, instant)}>
|
|
141
|
+
<circle cx={cx} cy={cy} r={r + 5} fill={node.color + "11"} />
|
|
142
|
+
<circle cx={cx} cy={cy} r={r} fill="white" stroke={node.color} strokeWidth={NODE.strokeWidth} />
|
|
143
|
+
<g transform={"translate(" + (cx - NODE.iconSize / 2) + ", " + (cy - NODE.iconSize / 2) + ")"}>
|
|
144
|
+
<svg width={NODE.iconSize} height={NODE.iconSize} viewBox="0 0 24 24" fill="none"
|
|
145
|
+
stroke={node.color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
146
|
+
<path d={ICON_PATHS[node.id as keyof typeof ICON_PATHS]} />
|
|
147
|
+
</svg>
|
|
148
|
+
</g>
|
|
149
|
+
<text x={cx} y={cy + r + 20} textAnchor="middle" fontSize={NODE.labelFont} fontWeight="900"
|
|
150
|
+
fill={NODE.labelColor} fontFamily={CANVAS.fontFamily}>{node.label}</text>
|
|
151
|
+
<text x={cx} y={cy + r + 38} textAnchor="middle" fontSize={NODE.subFont} fontWeight="700"
|
|
152
|
+
fill={node.color} fontFamily={CANVAS.fontFamily}>{node.sub}</text>
|
|
153
|
+
</g>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function DetailAnnotation({ detail, step, currentStep, svgW, svgH, instant }: { detail: any; step: number; currentStep: number; svgW: number; svgH: number; instant: boolean }) {
|
|
158
|
+
if (!detail) return null;
|
|
159
|
+
const node = NODES[step];
|
|
160
|
+
const occupied = nodeOccupiedRects(NODES, step, { nx: nx, ny: ny, iconR: ICON_R, labelH: 44 });
|
|
161
|
+
const pos = findEmptySlot({
|
|
162
|
+
canvasW: svgW, canvasH: svgH,
|
|
163
|
+
occupied: occupied, slotW: DETAIL_W, slotH: DETAIL_H,
|
|
164
|
+
margin: DETAIL.margin,
|
|
165
|
+
near: { x: nx(node.col), y: ny(node.row) },
|
|
166
|
+
step: DETAIL.scanStep,
|
|
167
|
+
});
|
|
168
|
+
return (
|
|
169
|
+
<g style={visExact(currentStep, step, instant)}>
|
|
170
|
+
<rect x={pos.x} y={pos.y} width={DETAIL_W} height={DETAIL_H} rx="12"
|
|
171
|
+
fill="white" fillOpacity={DETAIL.bgOpacity} stroke="none" />
|
|
172
|
+
<foreignObject x={pos.x} y={pos.y} width={DETAIL_W} height={DETAIL_H}>
|
|
173
|
+
<div style={annotationStyle()}>
|
|
174
|
+
<svg style={illustrationStyle()} viewBox={detail.vb}>
|
|
175
|
+
{detail.illustration}
|
|
176
|
+
</svg>
|
|
177
|
+
<div style={{ flex: "1 1 auto", display: "flex", flexDirection: "column", justifyContent: "center" }}>
|
|
178
|
+
<div style={annotationTitleStyle()}>
|
|
179
|
+
{detail.lines[0]}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</foreignObject>
|
|
184
|
+
</g>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const SVG_W = 3 * COL_W + 2 * GAP_X + 2 * PAD_X;
|
|
189
|
+
const SVG_H = 3 * ROW_H + 2 * GAP_Y + 2 * PAD_Y + 200;
|
|
190
|
+
|
|
191
|
+
export default function SimpleRca({ Reveal }: SlideComponentProps) {
|
|
192
|
+
return (
|
|
193
|
+
<SlideCanvas Reveal={Reveal} W={SVG_W} H={SVG_H}>{(step, instant) => <>
|
|
194
|
+
<defs>
|
|
195
|
+
<marker id="srca-arr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
196
|
+
<path d="M 0 0 L 10 5 L 0 10 z" fill="#BFBFBF" />
|
|
197
|
+
</marker>
|
|
198
|
+
</defs>
|
|
199
|
+
|
|
200
|
+
{LINKS.map(function (link, i) {
|
|
201
|
+
const from = NODES[link.from], to = NODES[link.to];
|
|
202
|
+
const p1 = anchorPt(from, "right");
|
|
203
|
+
const p2 = anchorPt(to, "left");
|
|
204
|
+
return <path key={i} d={arrowPath(p1[0], p1[1], p2[0], p2[1])}
|
|
205
|
+
fill="none" stroke="#BFBFBF" strokeWidth="2.5" strokeLinecap="round"
|
|
206
|
+
markerEnd="url(#srca-arr)" style={vis(step, link.step, instant)} />;
|
|
207
|
+
})}
|
|
208
|
+
|
|
209
|
+
{NODES.map(function (n) { return <NodeIcon key={n.id} node={n} step={step} instant={instant} />; })}
|
|
210
|
+
|
|
211
|
+
{DETAILS.map(function (d, i) {
|
|
212
|
+
return <DetailAnnotation key={i} detail={d} step={i} currentStep={step} svgW={SVG_W} svgH={SVG_H} instant={instant} />;
|
|
213
|
+
})}
|
|
214
|
+
</>}</SlideCanvas>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
3
|
+
import { CANVAS, SlideCanvas, vis } from "../../../core/presets.ts";
|
|
4
|
+
import { ALGOS } from "../../../data/algorithms.ts";
|
|
5
|
+
|
|
6
|
+
const W = 1060, H = 440;
|
|
7
|
+
const BAR_X = 140;
|
|
8
|
+
const BAR_MAX = 360;
|
|
9
|
+
const TABLE_X = 560;
|
|
10
|
+
const ROW_H = 32;
|
|
11
|
+
const TOP_Y = 20;
|
|
12
|
+
|
|
13
|
+
export default function SotaCollapse({ Reveal }: SlideComponentProps) {
|
|
14
|
+
return (
|
|
15
|
+
<SlideCanvas Reveal={Reveal} W={W} H={H}>{(step, instant) => <>
|
|
16
|
+
|
|
17
|
+
<g style={vis(step, -1, instant)}>
|
|
18
|
+
<text x={BAR_X + BAR_MAX / 2} y={TOP_Y} textAnchor="middle" fontSize="14" fontWeight="800" fill="#999" fontFamily={CANVAS.fontFamily}>Top@1</text>
|
|
19
|
+
|
|
20
|
+
<text x={TABLE_X + 40} y={TOP_Y} textAnchor="middle" fontSize="14" fontWeight="800" fill="#999" fontFamily={CANVAS.fontFamily}>@1</text>
|
|
21
|
+
<text x={TABLE_X + 100} y={TOP_Y} textAnchor="middle" fontSize="14" fontWeight="800" fill="#999" fontFamily={CANVAS.fontFamily}>@3</text>
|
|
22
|
+
<text x={TABLE_X + 160} y={TOP_Y} textAnchor="middle" fontSize="14" fontWeight="800" fill="#999" fontFamily={CANVAS.fontFamily}>@5</text>
|
|
23
|
+
<text x={TABLE_X + 230} y={TOP_Y} textAnchor="middle" fontSize="14" fontWeight="800" fill="#999" fontFamily={CANVAS.fontFamily}>Time(s)</text>
|
|
24
|
+
</g>
|
|
25
|
+
|
|
26
|
+
{ALGOS.map(function (a, i) {
|
|
27
|
+
const y = TOP_Y + 10 + i * ROW_H;
|
|
28
|
+
const barW = (a.t1 / 0.40) * BAR_MAX;
|
|
29
|
+
const isSimple = a.name === "SimpleRCA";
|
|
30
|
+
const isBest = a.name === "MicroRCA";
|
|
31
|
+
const barColor = isSimple ? "#C00000" : isBest ? "#76B82A" : a.color;
|
|
32
|
+
const revealStep = i < 4 ? 0 : i < 8 ? 1 : 2;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<g key={i} style={vis(step, revealStep, instant)}>
|
|
36
|
+
<text x={BAR_X - 8} y={y + ROW_H / 2 + 1} textAnchor="end" dominantBaseline="middle"
|
|
37
|
+
fontSize="14" fontWeight={isSimple || isBest ? 900 : 700} fill={isSimple ? "#C00000" : "#313131"} fontFamily={CANVAS.fontFamily}>{a.name}</text>
|
|
38
|
+
|
|
39
|
+
<rect x={BAR_X} y={y + 5} width={barW} height={ROW_H - 12} rx="3"
|
|
40
|
+
fill={barColor} fillOpacity="0.18" stroke={barColor} strokeWidth={isSimple || isBest ? 2 : 1} />
|
|
41
|
+
<text x={BAR_X + barW + 6} y={y + ROW_H / 2 + 1} dominantBaseline="middle"
|
|
42
|
+
fontSize="14" fontWeight="900" fill={barColor} fontFamily={CANVAS.fontFamily}>{a.t1.toFixed(2)}</text>
|
|
43
|
+
|
|
44
|
+
<text x={TABLE_X + 40} y={y + ROW_H / 2 + 1} textAnchor="middle" dominantBaseline="middle"
|
|
45
|
+
fontSize="14" fontWeight="700" fill="#767676" fontFamily={CANVAS.fontFamily}>{a.t1.toFixed(2)}</text>
|
|
46
|
+
<text x={TABLE_X + 100} y={y + ROW_H / 2 + 1} textAnchor="middle" dominantBaseline="middle"
|
|
47
|
+
fontSize="14" fontWeight="700" fill="#767676" fontFamily={CANVAS.fontFamily}>{a.t3.toFixed(2)}</text>
|
|
48
|
+
<text x={TABLE_X + 160} y={y + ROW_H / 2 + 1} textAnchor="middle" dominantBaseline="middle"
|
|
49
|
+
fontSize="14" fontWeight="700" fill="#767676" fontFamily={CANVAS.fontFamily}>{a.t5.toFixed(2)}</text>
|
|
50
|
+
<text x={TABLE_X + 230} y={y + ROW_H / 2 + 1} textAnchor="middle" dominantBaseline="middle"
|
|
51
|
+
fontSize="14" fontWeight="700" fill={parseFloat(a.time) > 100 ? "#C00000" : "#999"} fontFamily={CANVAS.fontFamily}>{a.time}</text>
|
|
52
|
+
</g>
|
|
53
|
+
);
|
|
54
|
+
})}
|
|
55
|
+
|
|
56
|
+
<g style={vis(step, 3, instant)}>
|
|
57
|
+
<text x={W / 2} y={H - 10} textAnchor="middle" fontSize="16" fontWeight="800" fill="#313131" fontFamily={CANVAS.fontFamily}>
|
|
58
|
+
Best Top@1 = 0.37 · SimpleRCA = 0.28 · The shortcut no longer dominates
|
|
59
|
+
</text>
|
|
60
|
+
</g>
|
|
61
|
+
</>}</SlideCanvas>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SlideComponentProps } from "../../../core/types.ts";
|
|
3
|
+
import { useRevealStep, CANVAS } from "../../../core/presets.ts";
|
|
4
|
+
|
|
5
|
+
const DATA = [
|
|
6
|
+
{ ds: "RE2-OB", s: [0.47, 0.93, 1.00], m: "BARO", o: [0.14, 0.93, 0.98], win: true },
|
|
7
|
+
{ ds: "RE2-TT", s: [0.80, 0.87, 0.93], m: "BARO", o: [0.67, 0.84, 0.89], win: true },
|
|
8
|
+
{ ds: "RE2-SS", s: [0.24, 0.88, 0.97], m: "BARO", o: [0.14, 0.82, 0.94], win: true },
|
|
9
|
+
{ ds: "RE3-OB", s: [0.30, 0.90, 0.90], m: "BARO", o: [0.00, 0.90, 0.90], win: true },
|
|
10
|
+
{ ds: "RE3-TT", s: [0.83, 1.00, 1.00], m: "BARO", o: [0.50, 0.93, 1.00], win: true },
|
|
11
|
+
{ ds: "RE3-SS", s: [0.83, 0.90, 0.90], m: "BARO", o: [0.00, 0.83, 0.93], win: true },
|
|
12
|
+
{ ds: "Nezha-TT", s: [0.93, 0.98, 0.98], m: "Nezha", o: [0.87, 0.98, 0.98], win: true },
|
|
13
|
+
{ ds: "Nezha-OB", s: [0.91, 0.91, 0.91], m: "Nezha", o: [0.93, 0.96, 0.96], win: false },
|
|
14
|
+
{ ds: "Eadro-TT", s: [0.81, 0.83, 0.83], m: "Eadro", o: [0.99, 0.99, 0.99], win: false, note: true },
|
|
15
|
+
{ ds: "Eadro-SN", s: [0.83, 0.83, 0.83], m: "Eadro", o: [0.97, 0.99, 0.99], win: false, note: true },
|
|
16
|
+
{ ds: "AIOps-21", s: [0.63, 0.82, 0.91], m: "ART", o: [0.72, 0.89, null], win: false },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const TH: React.CSSProperties = { padding: "8px 8px 2px", fontSize: 14, fontWeight: 900, color: "#313131", borderBottom: "none" };
|
|
20
|
+
const SUB: React.CSSProperties = { padding: "0 8px 8px", fontSize: 14, fontWeight: 800, color: "#999", textAlign: "right", borderBottom: "2px solid #313131" };
|
|
21
|
+
const DS_S: React.CSSProperties = { padding: "7px 10px", fontSize: 18, fontWeight: 800, color: "#313131", textAlign: "left", borderBottom: "1px solid #e8e8e8" };
|
|
22
|
+
const NUM_S: React.CSSProperties = { padding: "7px 10px", fontSize: 18, fontWeight: 700, textAlign: "right", borderBottom: "1px solid #e8e8e8" };
|
|
23
|
+
const M_S: React.CSSProperties = { padding: "7px 10px 7px 18px", fontSize: 14, fontWeight: 700, color: "#999", textAlign: "left", borderBottom: "1px solid #e8e8e8" };
|
|
24
|
+
|
|
25
|
+
function fmt(v: number | null) { return v !== null ? v.toFixed(2) : "—"; }
|
|
26
|
+
function wc(a: number | null, b: number | null) { return (b === null || (a as number) >= b) ? "#C00000" : "#999"; }
|
|
27
|
+
function ww(a: number | null, b: number | null) { return (b === null || (a as number) >= b) ? 900 : 700; }
|
|
28
|
+
|
|
29
|
+
export default function SrcaResults({ Reveal }: SlideComponentProps) {
|
|
30
|
+
const ref = useRevealStep(Reveal);
|
|
31
|
+
const step = ref[0], ready = ref[1], instant = ref[2];
|
|
32
|
+
const tr = instant ? "none" : "opacity 0.4s ease, background 0.4s ease";
|
|
33
|
+
|
|
34
|
+
function rowOp(win: boolean) {
|
|
35
|
+
if (step < 0 || step >= 2) return 1;
|
|
36
|
+
return (step === 0) === win ? 1 : 0.15;
|
|
37
|
+
}
|
|
38
|
+
function rowBg(win: boolean) {
|
|
39
|
+
if (step === 0 && win) return "rgba(192,0,0,0.04)";
|
|
40
|
+
if (step === 1 && !win) return "rgba(27,85,107,0.04)";
|
|
41
|
+
return "transparent";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div style={{ opacity: ready ? 1 : 0, transition: instant ? "none" : "opacity 0.2s ease", width: "100%", height: "100%", fontFamily: CANVAS.fontFamily, position: "relative" }}>
|
|
46
|
+
<table style={{ borderCollapse: "collapse", width: "100%" }}>
|
|
47
|
+
<thead>
|
|
48
|
+
<tr>
|
|
49
|
+
<th style={{ ...TH, textAlign: "left" }}></th>
|
|
50
|
+
<th colSpan={3} style={{ ...TH, textAlign: "center", borderBottom: "2px solid #C00000" }}>SimpleRCA</th>
|
|
51
|
+
<th style={TH}></th>
|
|
52
|
+
<th colSpan={3} style={{ ...TH, textAlign: "center" }}>Best SOTA</th>
|
|
53
|
+
</tr>
|
|
54
|
+
<tr>
|
|
55
|
+
<th style={{ ...SUB, textAlign: "left" }}>Dataset</th>
|
|
56
|
+
<th style={SUB}>@1</th><th style={SUB}>@3</th><th style={SUB}>@5</th>
|
|
57
|
+
<th style={{ ...SUB, textAlign: "left", paddingLeft: 18 }}>Method</th>
|
|
58
|
+
<th style={SUB}>@1</th><th style={SUB}>@3</th><th style={SUB}>@5</th>
|
|
59
|
+
</tr>
|
|
60
|
+
</thead>
|
|
61
|
+
<tbody>
|
|
62
|
+
{DATA.map(function (r) {
|
|
63
|
+
return (
|
|
64
|
+
<tr key={r.ds} style={{ opacity: rowOp(r.win), background: rowBg(r.win), transition: tr }}>
|
|
65
|
+
<td style={DS_S}>{r.ds}</td>
|
|
66
|
+
<td style={{ ...NUM_S, color: wc(r.s[0], r.o[0]), fontWeight: ww(r.s[0], r.o[0]) }}>{fmt(r.s[0])}</td>
|
|
67
|
+
<td style={{ ...NUM_S, color: wc(r.s[1], r.o[1]), fontWeight: ww(r.s[1], r.o[1]) }}>{fmt(r.s[1])}</td>
|
|
68
|
+
<td style={{ ...NUM_S, color: wc(r.s[2], r.o[2]), fontWeight: ww(r.s[2], r.o[2]) }}>{fmt(r.s[2])}</td>
|
|
69
|
+
<td style={M_S}>{r.m}{r.note ? " *" : ""}</td>
|
|
70
|
+
<td style={{ ...NUM_S, color: wc(r.o[0], r.s[0]), fontWeight: ww(r.o[0], r.s[0]) }}>{fmt(r.o[0])}</td>
|
|
71
|
+
<td style={{ ...NUM_S, color: wc(r.o[1], r.s[1]), fontWeight: ww(r.o[1], r.s[1]) }}>{fmt(r.o[1])}</td>
|
|
72
|
+
<td style={{ ...NUM_S, color: wc(r.o[2], r.s[2]), fontWeight: ww(r.o[2], r.s[2]) }}>{fmt(r.o[2])}</td>
|
|
73
|
+
</tr>
|
|
74
|
+
);
|
|
75
|
+
})}
|
|
76
|
+
</tbody>
|
|
77
|
+
</table>
|
|
78
|
+
<div style={{ marginTop: 6, fontSize: 14, color: "#999", fontWeight: 600 }}>* Eadro: training / test set overlap</div>
|
|
79
|
+
|
|
80
|
+
<div style={{
|
|
81
|
+
position: "absolute", bottom: 30, left: "50%", transform: "translateX(-50%)",
|
|
82
|
+
padding: "14px 36px", borderRadius: 10,
|
|
83
|
+
background: "#fff", boxShadow: "0 8px 28px rgba(49,49,49,0.15)",
|
|
84
|
+
opacity: step === 0 ? 1 : 0, transition: tr,
|
|
85
|
+
whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: 20,
|
|
86
|
+
}}>
|
|
87
|
+
<strong style={{ color: "#C00000", fontSize: 28, fontWeight: 900 }}>SimpleRCA wins</strong>
|
|
88
|
+
<span style={{ fontSize: 16, fontWeight: 700, color: "#767676" }}>matches or beats published SOTA on 7 datasets</span>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div style={{
|
|
92
|
+
position: "absolute", bottom: 30, left: "50%", transform: "translateX(-50%)",
|
|
93
|
+
padding: "14px 36px", borderRadius: 10,
|
|
94
|
+
background: "#fff", boxShadow: "0 8px 28px rgba(49,49,49,0.15)",
|
|
95
|
+
opacity: step === 1 ? 1 : 0, transition: tr,
|
|
96
|
+
whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: 20,
|
|
97
|
+
}}>
|
|
98
|
+
<strong style={{ color: "#1B556B", fontSize: 28, fontWeight: 900 }}>Even when losing</strong>
|
|
99
|
+
<span style={{ fontSize: 16, fontWeight: 700, color: "#767676" }}>gap ≤ 0.18 · Eadro* has data leakage</span>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div style={{
|
|
103
|
+
position: "absolute", bottom: 30, left: "50%", transform: "translateX(-50%)",
|
|
104
|
+
padding: "14px 36px", borderRadius: 10,
|
|
105
|
+
background: "#fff", boxShadow: "0 8px 28px rgba(49,49,49,0.15)",
|
|
106
|
+
opacity: step >= 2 ? 1 : 0, transition: tr,
|
|
107
|
+
whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: 24,
|
|
108
|
+
}}>
|
|
109
|
+
<strong style={{ color: "#C00000", fontSize: 36, fontWeight: 900 }}>7 / 11</strong>
|
|
110
|
+
<span style={{ fontSize: 18, fontWeight: 800, color: "#313131" }}>A trivial probe should not match published models</span>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|