fix: Record correct diagram type, send playground toggle event immediately.

This commit is contained in:
Sidharth Vinod
2025-03-13 09:11:46 -07:00
parent 73dd347bab
commit 91331bda7e
3 changed files with 42 additions and 80 deletions

View File

@@ -67,6 +67,7 @@
return;
}
error = false;
let diagramType: string | undefined;
try {
if (container && state && (state.updateDiagram || state.autoSync)) {
if (!state.autoSync) {
@@ -95,12 +96,16 @@
rough = state.rough;
const scroll = view?.parentElement?.scrollTop;
delete container.dataset.processed;
const { svg, bindFunctions } = await renderDiagram(
const {
svg,
bindFunctions,
diagramType: detectedDiagramType
} = await renderDiagram(
Object.assign({}, JSON.parse(state.mermaid)) as MermaidConfig,
code,
'graph-div'
);
diagramType = detectedDiagramType;
if (svg.length > 0) {
handlePanZoom(state);
container.innerHTML = svg;
@@ -145,7 +150,7 @@
error = true;
}
const renderTime = Date.now() - startTime;
saveStatistics({ code, renderTime, isRough: state.rough });
saveStatistics({ code, renderTime, isRough: state.rough, diagramType });
recordRenderTime(renderTime, () => {
$inputStateStore.updateDiagram = true;
});

View File

@@ -1,19 +0,0 @@
import { describe, it, expect } from 'vitest';
import { detectType } from './stats';
describe('diagram detection', () => {
it('should detect diagrams correctly', () => {
expect(
detectType(`%%{{
graph`)
).toBe('graph');
expect(detectType(`gitGraph`)).toBe('gitGraph');
expect(
detectType(`%%{{
flowChart
graph`)
).toBe('flowChart');
expect(detectType(`loki -> thor`)).toBe(undefined);
});
});

View File

@@ -1,6 +1,7 @@
import { browser } from '$app/environment';
import type PlausibleInstance from 'plausible-tracker';
import { env } from './env';
export let plausible: ReturnType<typeof PlausibleInstance> | undefined;
export const initAnalytics = async (): Promise<void> => {
@@ -20,29 +21,6 @@ export const initAnalytics = async (): Promise<void> => {
}
};
export const detectType = (text: string): string | undefined => {
const possibleDiagramTypes = [
'classDiagram',
'erDiagram',
'flowChart',
'gantt',
'gitGraph',
'graph',
'journey',
'pie',
'stateDiagram',
'quadrantChart',
'mindmap'
];
const firstLine = text
.replaceAll(/^\s*%%.*\n/g, '\n')
.trimStart()
.split(' ')[0]
.toLowerCase();
const detectedDiagram = possibleDiagramTypes.find((d) => firstLine.includes(d.toLowerCase()));
return detectedDiagram;
};
export const countLines = (code: string): number => {
return (code.match(/\n/g)?.length ?? 0) + 1;
};
@@ -50,50 +28,47 @@ export const countLines = (code: string): number => {
export const saveStatistics = ({
code,
renderTime,
isRough
isRough,
diagramType
}: {
code: string;
renderTime: number;
isRough: boolean;
diagramType?: string;
}): void => {
const graphType = detectType(code);
if (!graphType) {
if (!diagramType) {
return;
}
const length = countLines(code);
const lengthBucket = getBucket(length);
const renderTimeMsBucket = getBucket(renderTime);
logEvent('render', { graphType, length, lengthBucket, renderTimeMsBucket, isRough });
logEvent('render', { diagramType, lengthBucket, renderTimeMsBucket, isRough });
};
const getBucket = (length: number): string => {
return length < 10
? '0-10'
: length < 25
? '10-25'
: length < 50
? '25-50'
: length < 100
? '50-100'
: length < 200
? '100-200'
: length < 500
? '200-500'
: length < 700
? '500-700'
: length < 1000
? '700-1000'
: length < 1500
? '1000-1500'
: length < 2500
? '1500-2500'
: length < 4500
? '2500-4500'
: length < 7000
? '4500-7000'
: length < 10_000
? '7000-10000'
: '10000+';
const buckets = [
[10, '0-10'],
[25, '10-25'],
[50, '25-50'],
[100, '50-100'],
[200, '100-200'],
[500, '200-500'],
[700, '500-700'],
[1000, '700-1000'],
[1500, '1000-1500'],
[2500, '1500-2500'],
[4500, '2500-4500'],
[7000, '4500-7000'],
[10_000, '7000-10000']
] as const;
for (const [threshold, label] of buckets) {
if (length < threshold) {
return label;
}
}
return '10000+';
};
const minutesToMilliSeconds = (minutes: number): number => {
@@ -104,7 +79,7 @@ const defaultDelay = minutesToMilliSeconds(1);
const delaysPerEvent = {
render: minutesToMilliSeconds(5),
panZoom: minutesToMilliSeconds(10),
playgroundToggle: defaultDelay,
playgroundToggle: 0,
copyClipboard: defaultDelay,
download: defaultDelay,
copyMarkdown: defaultDelay,
@@ -116,7 +91,7 @@ const delaysPerEvent = {
themeChange: defaultDelay,
bannerClick: defaultDelay,
version: defaultDelay
};
} as const;
export type AnalyticsEvent = keyof typeof delaysPerEvent;
const timeouts: Map<string, number> = new Map<string, number>();
// manual debounce to reduce the number of events sent to analytics
@@ -128,7 +103,8 @@ export const logEvent = (
return;
}
const key = data ? JSON.stringify({ name, data }) : name;
if (timeouts.has(key)) {
const delay = delaysPerEvent[name];
if (timeouts.has(key) && delay > 0) {
clearTimeout(timeouts.get(key));
} else {
plausible.trackEvent(
@@ -139,6 +115,6 @@ export const logEvent = (
}
timeouts.set(
key,
window.setTimeout(() => timeouts.delete(key), delaysPerEvent[name])
window.setTimeout(() => timeouts.delete(key), delay)
);
};