Skip to Content

Examples

KPS Monitor (Keys Per Second)

A panel that displays real-time keys per second.

// @id kps-monitor dmn.plugin.defineElement({ name: "KPS Monitor", maxInstances: 1, settings: { windowSize: { type: "number", default: 1, min: 0.5, max: 5, step: 0.5, label: "Window Size (seconds)", }, showPeak: { type: "boolean", default: true, label: "Show Peak" }, }, messages: { ko: { "menu.create": "KPS 패널 생성", "menu.delete": "KPS 패널 삭제", current: "현재", peak: "최고", }, en: { "menu.create": "Create KPS Panel", "menu.delete": "Delete KPS Panel", current: "Current", peak: "Peak", }, }, contextMenu: { create: "menu.create", delete: "menu.delete", }, template: (state, settings, { html, t }) => html` <div style=" background: rgba(0,0,0,0.7); padding: 8px 16px; border-radius: 8px; font-family: monospace; color: #fff; " > <div> ${t("current")}: <strong>${(state.kps ?? 0).toFixed(1)}</strong> </div> ${settings.showPeak ? html` <div style="opacity: 0.7"> ${t("peak")}: ${(state.peak ?? 0).toFixed(1)} </div> ` : ""} </div> `, onMount: ({ setState, getSettings, onHook }) => { const timestamps = []; let peak = 0; onHook("key", ({ state }) => { if (state !== "DOWN") return; const now = Date.now(); const settings = getSettings(); const windowMs = settings.windowSize * 1000; timestamps.push(now); // Keep only timestamps within window while (timestamps.length && timestamps[0] < now - windowMs) { timestamps.shift(); } const kps = timestamps.length / settings.windowSize; peak = Math.max(peak, kps); setState({ kps, peak }); }); }, });

Key Heatmap

Visualizes key usage frequency with colors.

// @id key-heatmap // Color interpolation helper function interpolateColor(c1, c2, ratio) { const hex = (s) => parseInt(s.slice(1), 16); const r1 = (hex(c1) >> 16) & 255, g1 = (hex(c1) >> 8) & 255, b1 = hex(c1) & 255; const r2 = (hex(c2) >> 16) & 255, g2 = (hex(c2) >> 8) & 255, b2 = hex(c2) & 255; const r = Math.round(r1 + (r2 - r1) * ratio); const g = Math.round(g1 + (g2 - g1) * ratio); const b = Math.round(b1 + (b2 - b1) * ratio); return `rgb(${r},${g},${b})`; } dmn.plugin.defineElement({ name: "Key Heatmap", maxInstances: 1, settings: { colorCold: { type: "color", default: "#3b82f6", label: "Low Frequency Color", }, colorHot: { type: "color", default: "#ef4444", label: "High Frequency Color", }, }, messages: { ko: { "menu.create": "히트맵 생성", "menu.delete": "히트맵 삭제" }, en: { "menu.create": "Create Heatmap", "menu.delete": "Delete Heatmap" }, }, contextMenu: { create: "menu.create", delete: "menu.delete", }, template: (state, settings, { html }) => { const counters = state.counters ?? {}; const maxCount = state.maxCount ?? 1; return html` <div style="display: flex; gap: 4px; flex-wrap: wrap;"> ${Object.entries(counters).map(([key, count]) => { const ratio = maxCount > 0 ? count / maxCount : 0; const color = interpolateColor( settings.colorCold, settings.colorHot, ratio, ); return html` <div style=" width: 40px; height: 40px; background: ${color}; border-radius: 4px; display: flex; align-items: center; justify-content: center; font-size: 10px; color: #fff; " > ${key.replace("Key", "")} </div> `; })} </div> `; }, onMount: ({ setState }) => { const counters = {}; const unsub = dmn.keys.onCounterChanged(({ key, count }) => { counters[key] = count; const maxCount = Math.max(...Object.values(counters)); setState({ counters: { ...counters }, maxCount }); }); return () => unsub(); }, });