43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
/**
|
|
* rData applet definitions — Analytics Card.
|
|
*/
|
|
|
|
import type { AppletDefinition, AppletLiveData } from "../../shared/applet-types";
|
|
|
|
const analyticsCard: AppletDefinition = {
|
|
id: "analytics-card",
|
|
label: "Analytics Card",
|
|
icon: "📊",
|
|
accentColor: "#6366f1",
|
|
ports: [
|
|
{ name: "metric-in", type: "number", direction: "input" },
|
|
{ name: "delta-out", type: "number", direction: "output" },
|
|
],
|
|
renderCompact(data: AppletLiveData): string {
|
|
const { snapshot } = data;
|
|
const label = (snapshot.label as string) || "Metric";
|
|
const value = (snapshot.value as number) || 0;
|
|
const prev = (snapshot.previous as number) || 0;
|
|
const delta = prev > 0 ? Math.round(((value - prev) / prev) * 100) : 0;
|
|
const deltaColor = delta >= 0 ? "#22c55e" : "#ef4444";
|
|
const arrow = delta >= 0 ? "↑" : "↓";
|
|
|
|
return `
|
|
<div>
|
|
<div style="font-size:11px;color:#94a3b8;margin-bottom:6px">${label}</div>
|
|
<div style="font-size:24px;font-weight:700;color:#e2e8f0">${value.toLocaleString()}</div>
|
|
<div style="font-size:12px;font-weight:500;color:${deltaColor};margin-top:4px">
|
|
${arrow} ${Math.abs(delta)}% vs previous
|
|
</div>
|
|
</div>
|
|
`;
|
|
},
|
|
onInputReceived(portName, value, ctx) {
|
|
if (portName === "metric-in" && typeof value === "number") {
|
|
ctx.emitOutput("delta-out", value);
|
|
}
|
|
},
|
|
};
|
|
|
|
export const dataApplets: AppletDefinition[] = [analyticsCard];
|