@grafana/scenes 6.40.0--canary.1265.18325783397.0 → 6.40.0--canary.1277.18545717336.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/CHANGELOG.md +72 -0
- package/dist/esm/behaviors/LongFrameDetector.js +11 -11
- package/dist/esm/behaviors/LongFrameDetector.js.map +1 -1
- package/dist/esm/behaviors/SceneRenderProfiler.js +131 -93
- package/dist/esm/behaviors/SceneRenderProfiler.js.map +1 -1
- package/dist/esm/behaviors/index.js +0 -3
- package/dist/esm/behaviors/index.js.map +1 -1
- package/dist/esm/components/SceneRefreshPicker.js +1 -1
- package/dist/esm/components/SceneRefreshPicker.js.map +1 -1
- package/dist/esm/components/SceneTimeRangeCompare.js +17 -14
- package/dist/esm/components/SceneTimeRangeCompare.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanel.js +1 -36
- package/dist/esm/components/VizPanel/VizPanel.js.map +1 -1
- package/dist/esm/components/VizPanel/VizPanelRenderer.js +2 -20
- package/dist/esm/components/VizPanel/VizPanelRenderer.js.map +1 -1
- package/dist/esm/core/SceneTimeRange.js +1 -1
- package/dist/esm/core/SceneTimeRange.js.map +1 -1
- package/dist/esm/index.js +3 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/querying/SceneDataTransformer.js +22 -79
- package/dist/esm/querying/SceneDataTransformer.js.map +1 -1
- package/dist/esm/querying/SceneQueryRunner.js +6 -11
- package/dist/esm/querying/SceneQueryRunner.js.map +1 -1
- package/dist/esm/querying/layers/SceneDataLayerControls.js +13 -1
- package/dist/esm/querying/layers/SceneDataLayerControls.js.map +1 -1
- package/dist/esm/querying/registerQueryWithController.js +2 -39
- package/dist/esm/querying/registerQueryWithController.js.map +1 -1
- package/dist/esm/utils/writeSceneLog.js +10 -1
- package/dist/esm/utils/writeSceneLog.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterBuilder.js +13 -2
- package/dist/esm/variables/adhoc/AdHocFilterBuilder.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js +6 -0
- package/dist/esm/variables/adhoc/AdHocFilterRenderer.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersCombobox/AdHocFiltersCombobox.js.map +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js +1 -1
- package/dist/esm/variables/adhoc/AdHocFiltersVariable.js.map +1 -1
- package/dist/esm/variables/components/VariableValueSelect.js +1 -1
- package/dist/esm/variables/components/VariableValueSelect.js.map +1 -1
- package/dist/esm/variables/groupby/GroupByVariable.js +1 -1
- package/dist/esm/variables/groupby/GroupByVariable.js.map +1 -1
- package/dist/esm/variables/variants/CustomVariable.js +9 -4
- package/dist/esm/variables/variants/CustomVariable.js.map +1 -1
- package/dist/esm/variables/variants/MultiValueVariable.js +1 -1
- package/dist/esm/variables/variants/MultiValueVariable.js.map +1 -1
- package/dist/esm/variables/variants/ScopesVariable.js +1 -1
- package/dist/esm/variables/variants/ScopesVariable.js.map +1 -1
- package/dist/esm/variables/variants/SwitchVariable.js +108 -0
- package/dist/esm/variables/variants/SwitchVariable.js.map +1 -0
- package/dist/esm/variables/variants/guards.js +4 -1
- package/dist/esm/variables/variants/guards.js.map +1 -1
- package/dist/index.d.ts +115 -370
- package/dist/index.js +7066 -7543
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/esm/behaviors/PanelProfilingManager.js +0 -65
- package/dist/esm/behaviors/PanelProfilingManager.js.map +0 -1
- package/dist/esm/behaviors/ScenePerformanceTracker.js +0 -78
- package/dist/esm/behaviors/ScenePerformanceTracker.js.map +0 -1
- package/dist/esm/behaviors/VizPanelRenderProfiler.js +0 -328
- package/dist/esm/behaviors/VizPanelRenderProfiler.js.map +0 -1
- package/dist/esm/behaviors/interactionConstants.js +0 -14
- package/dist/esm/behaviors/interactionConstants.js.map +0 -1
- package/dist/esm/utils/findPanelProfiler.js +0 -18
- package/dist/esm/utils/findPanelProfiler.js.map +0 -1
- package/dist/esm/utils/writePerformanceLog.js +0 -12
- package/dist/esm/utils/writePerformanceLog.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writePerformanceLog } from '../utils/writePerformanceLog';\nimport { SceneQueryControllerLike, LongFrameEvent, SceneComponentInteractionEvent } from './types';\nimport {\n getScenePerformanceTracker,\n generateOperationId,\n DashboardInteractionCompleteData,\n} from './ScenePerformanceTracker';\nimport { PanelProfilingManager, PanelProfilingConfig } from './PanelProfilingManager';\nimport { SceneObject } from '../core/types';\nimport { VizPanel } from '../components/VizPanel/VizPanel';\nimport { LongFrameDetector } from './LongFrameDetector';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst DEFAULT_LONG_FRAME_THRESHOLD = 30; // Threshold for tail recording slow frames\nconst TAB_INACTIVE_THRESHOLD = 1000; // Tab inactive threshold in ms\n\n/**\n * SceneRenderProfiler tracks dashboard interaction performance including:\n * - Total interaction duration\n * - Network time\n * - Long frame detection (50ms threshold) during interaction using LoAF API (default) or manual tracking (fallback)\n * - Slow frame detection (30ms threshold) for tail recording after interaction\n *\n * Long frame detection during interaction:\n * - 50ms threshold aligned with LoAF API default\n * - LoAF API preferred (Chrome 123+) with manual fallback\n * - Provides script attribution when using LoAF API\n *\n * Slow frame detection for tail recording:\n * - 30ms threshold for post-interaction monitoring\n * - Manual frame timing measurement\n * - Captures rendering delays after user interaction completes\n */\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n origin: string; // Profile trigger (e.g., 'time_range_change')\n crumbs: string[];\n } | null = null;\n\n #interactionInProgress: {\n interaction: string;\n startTs: number;\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Generic metadata for observer notifications\n private metadata: Record<string, unknown> = {};\n\n // Operation ID for correlating dashboard interaction events\n #currentOperationId?: string;\n\n // Trailing frame measurements\n #recordedTrailingSpans: number[] = [];\n\n // Long frame tracking\n #longFrameDetector: LongFrameDetector;\n #longFramesCount = 0;\n #longFramesTotalTime = 0;\n\n #visibilityChangeHandler: (() => void) | null = null;\n #onInteractionComplete: ((event: SceneComponentInteractionEvent) => void) | null = null;\n\n // Panel profiling composition\n private _panelProfilingManager?: PanelProfilingManager;\n\n // Query controller for monitoring query completion\n private queryController?: SceneQueryControllerLike;\n\n public constructor(panelProfilingConfig?: PanelProfilingConfig) {\n this.#longFrameDetector = new LongFrameDetector();\n this.setupVisibilityChangeHandler();\n this.#interactionInProgress = null;\n\n // Compose with panel profiling manager if provided\n if (panelProfilingConfig) {\n this._panelProfilingManager = new PanelProfilingManager(panelProfilingConfig);\n }\n }\n\n /** Set generic metadata for observer notifications */\n public setMetadata(metadata: Record<string, unknown>) {\n this.metadata = { ...metadata };\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n /** Attach panel profiling to a scene object */\n public attachPanelProfiling(sceneObject: SceneObject) {\n this._panelProfilingManager?.attachToScene(sceneObject);\n }\n\n /** Attach profiler to a specific panel */\n public attachProfilerToPanel(panel: VizPanel): void {\n writePerformanceLog('SRP', 'Attaching profiler to panel', panel.state.key);\n this._panelProfilingManager?.attachProfilerToPanel(panel);\n }\n\n public setInteractionCompleteHandler(handler?: (event: SceneComponentInteractionEvent) => void) {\n this.#onInteractionComplete = handler ?? null;\n }\n\n private setupVisibilityChangeHandler() {\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Cancel profiling when tab becomes inactive\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writePerformanceLog('SRP', 'Tab became inactive, cancelling profile');\n this.cancelProfile();\n }\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', this.#visibilityChangeHandler);\n }\n }\n\n public cleanup() {\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cleanup long frame tracking\n this.#longFrameDetector.stop();\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n\n // Cleanup composed panel profiling manager\n this._panelProfilingManager?.cleanup();\n }\n\n public startProfile(name: string) {\n // Skip profiling if tab is inactive\n if (document.hidden) {\n writePerformanceLog('SRP', 'Tab is inactive, skipping profile', name);\n return;\n }\n\n if (this.#profileInProgress) {\n if (this.#trailAnimationFrameId) {\n this.cancelProfile();\n this._startNewProfile(name, true);\n } else {\n this.addCrumb(name);\n }\n } else {\n this._startNewProfile(name);\n }\n }\n\n public startInteraction(interaction: string) {\n // Cancel any existing interaction recording\n if (this.#interactionInProgress) {\n writePerformanceLog('SRP', 'Cancelled interaction:', this.#interactionInProgress);\n this.#interactionInProgress = null;\n }\n\n this.#interactionInProgress = {\n interaction,\n startTs: performance.now(),\n };\n\n writePerformanceLog('SRP', 'Started interaction:', interaction);\n }\n\n public stopInteraction() {\n if (!this.#interactionInProgress) {\n return;\n }\n\n const endTs = performance.now();\n const interactionDuration = endTs - this.#interactionInProgress.startTs;\n\n // Capture network requests that occurred during the interaction\n const networkDuration = captureNetwork(this.#interactionInProgress.startTs, endTs);\n\n writePerformanceLog(\n 'SRP',\n `[INTERACTION] Complete: ${interactionDuration.toFixed(1)}ms total | ${networkDuration.toFixed(1)}ms network`\n );\n\n if (this.#onInteractionComplete && this.#profileInProgress) {\n this.#onInteractionComplete({\n origin: this.#interactionInProgress.interaction,\n duration: interactionDuration,\n networkDuration,\n startTs: this.#interactionInProgress.startTs,\n endTs,\n });\n }\n\n // Create performance marks for browser dev tools\n performance.mark(`${this.#interactionInProgress.interaction}_start`, {\n startTime: this.#interactionInProgress.startTs,\n });\n performance.mark(`${this.#interactionInProgress.interaction}_end`, {\n startTime: endTs,\n });\n performance.measure(\n `Interaction_${this.#interactionInProgress.interaction}`,\n `${this.#interactionInProgress.interaction}_start`,\n `${this.#interactionInProgress.interaction}_end`\n );\n\n this.#interactionInProgress = null;\n }\n\n public getCurrentInteraction(): string | null {\n return this.#interactionInProgress?.interaction ?? null;\n }\n\n /**\n * Start new performance profile\n * @param name - Profile trigger (e.g., 'time_range_change')\n * @param force - True if canceling existing profile, false if starting clean\n */\n private _startNewProfile(name: string, force = false) {\n const profileType = force ? 'forced' : 'clean';\n writePerformanceLog('SRP', `[PROFILER] ${name} started (${profileType})`);\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n\n this.#currentOperationId = generateOperationId('dashboard');\n getScenePerformanceTracker().notifyDashboardInteractionStart({\n operationId: this.#currentOperationId,\n interactionType: name,\n timestamp: this.#profileStartTs,\n metadata: this.metadata,\n });\n\n // Start long frame detection with callback\n this.#longFrameDetector.start((event: LongFrameEvent) => {\n // Only record long frames during active profiling\n if (!this.#profileInProgress || !this.#profileStartTs) {\n return;\n }\n\n // Only record frames that occur after profile started\n if (event.timestamp < this.#profileStartTs) {\n return;\n }\n\n this.#longFramesCount++;\n this.#longFramesTotalTime += event.duration;\n });\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n\n // Detect tab inactivity as backup to Page Visibility API\n if (frameLength > TAB_INACTIVE_THRESHOLD) {\n writePerformanceLog('SRP', 'Tab was inactive, cancelling profile measurement');\n this.cancelProfile();\n return;\n }\n\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n writePerformanceLog(\n 'SRP',\n 'Profile tail recorded, slow frames duration:',\n slowFramesTime,\n slowFrames,\n this.#profileInProgress\n );\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n const slowFrameSummary =\n slowFrames.length > 0\n ? `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length}) ⚠️`\n : `${slowFramesTime.toFixed(1)}ms slow frames[tail recording] (${slowFrames.length})`;\n\n const longFrameSummary =\n this.#longFramesCount > 0\n ? `${this.#longFramesTotalTime.toFixed(1)}ms long frames[LoAF] (${this.#longFramesCount}) ⚠️`\n : `${this.#longFramesTotalTime.toFixed(1)}ms long frames[LoAF] (${this.#longFramesCount})`;\n\n writePerformanceLog(\n 'SRP',\n `[PROFILER] Complete: ${(profileDuration + slowFramesTime).toFixed(\n 1\n )}ms total | ${slowFrameSummary} | ${longFrameSummary}`\n );\n this.#longFrameDetector.stop();\n\n this.#trailAnimationFrameId = null;\n\n // Profile completion - interaction context now handled by observer pattern\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n // Guard against race condition where profile might be cancelled during execution\n if (!this.#profileInProgress) {\n return;\n }\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.#profileInProgress) {\n // Notify performance observers of dashboard interaction completion\n const dashboardData: DashboardInteractionCompleteData = {\n operationId: this.#currentOperationId || generateOperationId('dashboard-fallback'),\n interactionType: this.#profileInProgress.origin,\n timestamp: profileEndTs,\n duration: profileDuration + slowFramesTime,\n networkDuration: networkDuration,\n longFramesCount: this.#longFramesCount,\n longFramesTotalTime: this.#longFramesTotalTime,\n metadata: this.metadata,\n };\n\n const tracker = getScenePerformanceTracker();\n tracker.notifyDashboardInteractionComplete(dashboardData);\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n }\n };\n\n public tryCompletingProfile() {\n writePerformanceLog('SRP', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writePerformanceLog('SRP', 'All queries completed, stopping profile');\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writePerformanceLog('SRP', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writePerformanceLog('SRP', 'Cancelling profile', this.#profileInProgress);\n\n // Profile cancelled - cleanup handled by observer pattern\n\n this.#profileInProgress = null;\n // Cancel any pending animation frame to prevent accessing null profileInProgress\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n }\n // Stop long frame tracking\n this.#longFrameDetector.stop();\n writePerformanceLog('SRP', 'Stopped long frame detection - profile cancelled');\n // Reset recorded spans to ensure complete cleanup\n this.#recordedTrailingSpans = [];\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n // writeSceneLog('SRP', 'Adding crumb:', crumb);\n // Notify performance observers of milestone\n getScenePerformanceTracker().notifyDashboardInteractionMilestone({\n operationId: generateOperationId('dashboard-milestone'),\n interactionType: this.#profileInProgress.origin,\n timestamp: performance.now(),\n milestone: crumb,\n metadata: this.metadata,\n });\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than default threshold\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nexport function captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n // Only include network entries that both started AND ended within the time window\n const networkEntries = entries.filter(\n (entry) =>\n entry.startTime >= startTs &&\n entry.startTime <= endTs &&\n entry.responseEnd >= startTs &&\n entry.responseEnd <= endTs\n );\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n\n// Constants moved to ./interactionConstants.ts to avoid circular dependencies\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SceneRenderProfiler.js","sources":["../../../src/behaviors/SceneRenderProfiler.ts"],"sourcesContent":["import { writeSceneLog, writeSceneLogStyled } from '../utils/writeSceneLog';\nimport { SceneQueryControllerLike, LongFrameEvent, SceneComponentInteractionEvent } from './types';\nimport { LongFrameDetector } from './LongFrameDetector';\n\nconst POST_STORM_WINDOW = 2000; // Time after last query to observe slow frames\nconst DEFAULT_LONG_FRAME_THRESHOLD = 30; // Threshold for tail recording slow frames\n\n/**\n * SceneRenderProfiler tracks dashboard interaction performance including:\n * - Total interaction duration\n * - Network time\n * - Long frame detection (50ms threshold) during interaction using LoAF API (default) or manual tracking (fallback)\n * - Slow frame detection (30ms threshold) for tail recording after interaction\n *\n * Long frame detection during interaction:\n * - 50ms threshold aligned with LoAF API default\n * - LoAF API preferred (Chrome 123+) with manual fallback\n * - Provides script attribution when using LoAF API\n *\n * Slow frame detection for tail recording:\n * - 30ms threshold for post-interaction monitoring\n * - Manual frame timing measurement\n * - Captures rendering delays after user interaction completes\n */\n\nexport class SceneRenderProfiler {\n #profileInProgress: {\n // Profile origin, i.e. scene refresh picker\n origin: string;\n crumbs: string[];\n } | null = null;\n\n #interactionInProgress: {\n interaction: string;\n startTs: number;\n } | null = null;\n\n #profileStartTs: number | null = null;\n #trailAnimationFrameId: number | null = null;\n\n // Will keep measured lengths trailing frames\n #recordedTrailingSpans: number[] = [];\n\n // Long frame tracking\n #longFrameDetector: LongFrameDetector;\n #longFramesCount = 0;\n #longFramesTotalTime = 0;\n\n #visibilityChangeHandler: (() => void) | null = null;\n #onInteractionComplete: ((event: SceneComponentInteractionEvent) => void) | null = null;\n\n public constructor(private queryController?: SceneQueryControllerLike) {\n this.#longFrameDetector = new LongFrameDetector();\n this.setupVisibilityChangeHandler();\n this.#interactionInProgress = null;\n }\n\n public setQueryController(queryController: SceneQueryControllerLike) {\n this.queryController = queryController;\n }\n\n public setInteractionCompleteHandler(handler?: (event: SceneComponentInteractionEvent) => void) {\n this.#onInteractionComplete = handler ?? null;\n }\n\n private setupVisibilityChangeHandler() {\n // Ensure event listener is only added once\n if (this.#visibilityChangeHandler) {\n return;\n }\n\n // Handle tab switching with Page Visibility API\n this.#visibilityChangeHandler = () => {\n if (document.hidden && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Tab became inactive, cancelling profile');\n this.cancelProfile();\n }\n };\n\n if (typeof document !== 'undefined') {\n document.addEventListener('visibilitychange', this.#visibilityChangeHandler);\n }\n }\n\n public cleanup() {\n // Remove event listener to prevent memory leaks\n if (this.#visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.#visibilityChangeHandler);\n this.#visibilityChangeHandler = null;\n }\n\n // Cleanup long frame tracking\n this.#longFrameDetector.stop();\n\n // Cancel any ongoing profiling\n this.cancelProfile();\n }\n\n public startProfile(name: string) {\n // Only start profile if tab is active. This makes sure we don't start a profile when i.e. someone opens a dashboard in a new tab\n // and doesn't interact with it.\n if (document.hidden) {\n writeSceneLog('SceneRenderProfiler', 'Tab is inactive, skipping profile', name);\n return;\n }\n\n if (this.#profileInProgress) {\n if (this.#trailAnimationFrameId) {\n this.cancelProfile();\n this._startNewProfile(name, true);\n } else {\n this.addCrumb(name);\n }\n } else {\n this._startNewProfile(name);\n }\n }\n\n public startInteraction(interaction: string) {\n // Cancel any existing interaction recording\n if (this.#interactionInProgress) {\n writeSceneLog('profile', 'Cancelled interaction:', this.#interactionInProgress);\n this.#interactionInProgress = null;\n }\n\n this.#interactionInProgress = {\n interaction,\n startTs: performance.now(),\n };\n\n writeSceneLog('SceneRenderProfiler', 'Started interaction:', interaction);\n }\n\n public stopInteraction() {\n if (!this.#interactionInProgress) {\n return;\n }\n\n const endTs = performance.now();\n const interactionDuration = endTs - this.#interactionInProgress.startTs;\n\n // Capture network requests that occurred during the interaction\n const networkDuration = captureNetwork(this.#interactionInProgress.startTs, endTs);\n\n writeSceneLog('SceneRenderProfiler', 'Completed interaction:');\n writeSceneLog('', ` ├─ Total time: ${interactionDuration.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Network duration: ${networkDuration.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ StartTs: ${this.#interactionInProgress.startTs.toFixed(1)}ms`);\n writeSceneLog('', ` └─ EndTs: ${endTs.toFixed(1)}ms`);\n\n if (this.#onInteractionComplete && this.#profileInProgress) {\n this.#onInteractionComplete({\n origin: this.#interactionInProgress.interaction,\n duration: interactionDuration,\n networkDuration,\n startTs: this.#interactionInProgress.startTs,\n endTs,\n });\n }\n\n // Create performance marks for browser dev tools\n performance.mark(`${this.#interactionInProgress.interaction}_start`, {\n startTime: this.#interactionInProgress.startTs,\n });\n performance.mark(`${this.#interactionInProgress.interaction}_end`, {\n startTime: endTs,\n });\n performance.measure(\n `Interaction_${this.#interactionInProgress.interaction}`,\n `${this.#interactionInProgress.interaction}_start`,\n `${this.#interactionInProgress.interaction}_end`\n );\n\n this.#interactionInProgress = null;\n }\n\n public getCurrentInteraction(): string | null {\n return this.#interactionInProgress?.interaction ?? null;\n }\n\n /**\n * Starts a new profile for performance measurement.\n *\n * @param name - The origin/trigger of the profile (e.g., 'time_range_change', 'variable_value_changed')\n * @param force - Whether this is a \"forced\" profile (true) or \"clean\" profile (false)\n * - \"forced\": Started by canceling an existing profile that was recording trailing frames\n * This happens when a new user interaction occurs before the previous one\n * finished measuring its performance impact\n * - \"clean\": Started when no profile is currently active\n */\n private _startNewProfile(name: string, force = false) {\n this.#profileInProgress = { origin: name, crumbs: [] };\n this.#profileStartTs = performance.now();\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n\n // Add performance mark for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const markName = `Dashboard Profile Start: ${name}`;\n performance.mark(markName);\n }\n\n // Log profile start in structured format\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Profile started[${force ? 'forced' : 'clean'}]`,\n 'color: #FFCC00; font-weight: bold;'\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Timestamp: ${this.#profileStartTs.toFixed(1)}ms`);\n\n // Start long frame detection with callback\n this.#longFrameDetector.start((event: LongFrameEvent) => {\n // Only record long frames during active profiling\n if (!this.#profileInProgress || !this.#profileStartTs) {\n return;\n }\n\n // Only record frames that occur after profile started\n if (event.timestamp < this.#profileStartTs) {\n return;\n }\n\n this.#longFramesCount++;\n this.#longFramesTotalTime += event.duration;\n });\n }\n\n private recordProfileTail(measurementStartTime: number, profileStartTs: number) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTime, measurementStartTime, profileStartTs)\n );\n }\n\n private measureTrailingFrames = (measurementStartTs: number, lastFrameTime: number, profileStartTs: number) => {\n const currentFrameTime = performance.now();\n const frameLength = currentFrameTime - lastFrameTime;\n\n this.#recordedTrailingSpans.push(frameLength);\n\n if (currentFrameTime - measurementStartTs! < POST_STORM_WINDOW) {\n if (this.#profileInProgress) {\n this.#trailAnimationFrameId = requestAnimationFrame(() =>\n this.measureTrailingFrames(measurementStartTs, currentFrameTime, profileStartTs)\n );\n }\n } else {\n const slowFrames = processRecordedSpans(this.#recordedTrailingSpans);\n const slowFramesTime = slowFrames.reduce((acc, val) => acc + val, 0);\n\n // Log tail recording in structured format\n writeSceneLog(\n 'SceneRenderProfiler',\n `Profile tail recorded - Slow frames: ${slowFramesTime.toFixed(1)}ms (${slowFrames.length} frames)`\n );\n writeSceneLog('', ` ├─ Origin: ${this.#profileInProgress?.origin || 'unknown'}`);\n writeSceneLog('', ` └─ Crumbs:`, this.#profileInProgress?.crumbs || []);\n\n this.#recordedTrailingSpans = [];\n\n const profileDuration = measurementStartTs - profileStartTs;\n\n // Add performance marks for debugging in dev tools\n if (typeof performance !== 'undefined' && performance.mark) {\n const profileName = this.#profileInProgress?.origin || 'unknown';\n const totalTime = profileDuration + slowFramesTime;\n\n // Mark profile completion\n performance.mark(`Dashboard Profile End: ${profileName}`);\n\n // Add measure from start to end if possible\n const startMarkName = `Dashboard Profile Start: ${profileName}`;\n try {\n performance.measure(\n `Dashboard Profile: ${profileName} (${totalTime.toFixed(1)}ms)`,\n startMarkName,\n `Dashboard Profile End: ${profileName}`\n );\n } catch {\n // Start mark might not exist, create a simple end mark\n performance.mark(`Dashboard Profile Complete: ${profileName} (${totalTime.toFixed(1)}ms)`);\n }\n\n // Add measurements for slow frame details if significant\n if (slowFrames.length > 0) {\n const slowFramesMarkName = `Slow Frames Summary: ${slowFrames.length} frames (${slowFramesTime.toFixed(\n 1\n )}ms)`;\n performance.mark(slowFramesMarkName);\n\n // Create individual measurements for each slow frame during tail\n slowFrames.forEach((frameTime, index) => {\n if (frameTime > 16) {\n // Only measure frames slower than 16ms (60fps)\n try {\n const frameStartTime =\n this.#profileStartTs! +\n profileDuration +\n (index > 0 ? slowFrames.slice(0, index).reduce((sum, t) => sum + t, 0) : 0);\n const frameId = `slow-frame-${index}`;\n const frameStartMark = `${frameId}-start`;\n const frameEndMark = `${frameId}-end`;\n\n performance.mark(frameStartMark, { startTime: frameStartTime });\n performance.mark(frameEndMark, { startTime: frameStartTime + frameTime });\n performance.measure(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`, frameStartMark, frameEndMark);\n } catch {\n // Fallback if startTime not supported\n performance.mark(`Slow Frame ${index + 1}: ${frameTime.toFixed(1)}ms`);\n }\n }\n });\n }\n }\n\n // Log performance summary in a structured format\n const completionTimestamp = performance.now();\n writeSceneLog('SceneRenderProfiler', 'Profile completed');\n writeSceneLog('', ` ├─ Timestamp: ${completionTimestamp.toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Total time: ${(profileDuration + slowFramesTime).toFixed(1)}ms`);\n writeSceneLog('', ` ├─ Slow frames: ${slowFramesTime}ms (${slowFrames.length} frames)`);\n writeSceneLog('', ` └─ Long frames: ${this.#longFramesTotalTime}ms (${this.#longFramesCount} frames)`);\n\n // Stop long frame detection now that the profile is complete\n this.#longFrameDetector.stop();\n writeSceneLogStyled(\n 'SceneRenderProfiler',\n `Stopped long frame detection - profile complete at ${completionTimestamp.toFixed(1)}ms`,\n 'color: #00CC00; font-weight: bold;'\n );\n\n this.#trailAnimationFrameId = null;\n\n const profileEndTs = profileStartTs + profileDuration + slowFramesTime;\n\n // Guard against race condition where profile might be cancelled during execution\n if (!this.#profileInProgress) {\n return;\n }\n\n performance.measure(`DashboardInteraction ${this.#profileInProgress.origin}`, {\n start: profileStartTs,\n end: profileEndTs,\n });\n\n const networkDuration = captureNetwork(profileStartTs, profileEndTs);\n\n if (this.queryController?.state.onProfileComplete && this.#profileInProgress) {\n this.queryController.state.onProfileComplete({\n origin: this.#profileInProgress.origin,\n crumbs: this.#profileInProgress.crumbs,\n duration: profileDuration + slowFramesTime,\n networkDuration,\n startTs: profileStartTs,\n endTs: profileEndTs,\n longFramesCount: this.#longFramesCount,\n longFramesTotalTime: this.#longFramesTotalTime,\n // @ts-ignore\n jsHeapSizeLimit: performance.memory ? performance.memory.jsHeapSizeLimit : 0,\n // @ts-ignore\n usedJSHeapSize: performance.memory ? performance.memory.usedJSHeapSize : 0,\n // @ts-ignore\n totalJSHeapSize: performance.memory ? performance.memory.totalJSHeapSize : 0,\n });\n\n this.#profileInProgress = null;\n this.#trailAnimationFrameId = null;\n }\n // @ts-ignore\n if (window.__runs) {\n // @ts-ignore\n window.__runs += `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n } else {\n // @ts-ignore\n window.__runs = `${Date.now()}, ${profileDuration + slowFramesTime}\\n`;\n }\n }\n };\n\n public tryCompletingProfile() {\n if (!this.#profileInProgress) {\n return;\n }\n\n writeSceneLog('SceneRenderProfiler', 'Trying to complete profile', this.#profileInProgress);\n if (this.queryController?.runningQueriesCount() === 0 && this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'All queries completed, starting tail measurement');\n // Note: Long frame detector continues running during tail measurement\n // It will be stopped when the profile completely finishes\n this.recordProfileTail(performance.now(), this.#profileStartTs!);\n }\n }\n\n public isTailRecording() {\n return Boolean(this.#trailAnimationFrameId);\n }\n\n public cancelTailRecording() {\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n writeSceneLog('SceneRenderProfiler', 'Cancelled recording frames, new profile started');\n }\n }\n\n // cancel profile\n public cancelProfile() {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Cancelling profile', this.#profileInProgress);\n this.#profileInProgress = null;\n // Cancel any pending animation frame to prevent accessing null profileInProgress\n if (this.#trailAnimationFrameId) {\n cancelAnimationFrame(this.#trailAnimationFrameId);\n this.#trailAnimationFrameId = null;\n }\n // Stop long frame tracking\n this.#longFrameDetector.stop();\n writeSceneLog('SceneRenderProfiler', 'Stopped long frame detection - profile cancelled');\n // Reset recorded spans to ensure complete cleanup\n this.#recordedTrailingSpans = [];\n this.#longFramesCount = 0;\n this.#longFramesTotalTime = 0;\n }\n }\n\n public addCrumb(crumb: string) {\n if (this.#profileInProgress) {\n writeSceneLog('SceneRenderProfiler', 'Adding crumb:', crumb);\n this.#profileInProgress.crumbs.push(crumb);\n }\n }\n}\n\nexport function processRecordedSpans(spans: number[]) {\n // identify last span in spans that's bigger than default threshold\n for (let i = spans.length - 1; i >= 0; i--) {\n if (spans[i] > DEFAULT_LONG_FRAME_THRESHOLD) {\n return spans.slice(0, i + 1);\n }\n }\n return [spans[0]];\n}\n\nexport function captureNetwork(startTs: number, endTs: number) {\n const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[];\n performance.clearResourceTimings();\n // Only include network entries that both started AND ended within the time window\n const networkEntries = entries.filter(\n (entry) =>\n entry.startTime >= startTs &&\n entry.startTime <= endTs &&\n entry.responseEnd >= startTs &&\n entry.responseEnd <= endTs\n );\n for (const entry of networkEntries) {\n performance.measure('Network entry ' + entry.name, {\n start: entry.startTime,\n end: entry.responseEnd,\n });\n }\n\n return calculateNetworkTime(networkEntries);\n}\n\n// Will calculate total time spent on Network\nexport function calculateNetworkTime(requests: PerformanceResourceTiming[]): number {\n if (requests.length === 0) {\n return 0;\n }\n\n // Step 1: Sort the requests by startTs\n requests.sort((a, b) => a.startTime - b.startTime);\n\n // Step 2: Initialize variables\n let totalNetworkTime = 0;\n let currentStart = requests[0].startTime;\n let currentEnd = requests[0].responseEnd;\n\n // Step 3: Iterate through the sorted list and merge overlapping intervals\n for (let i = 1; i < requests.length; i++) {\n if (requests[i].startTime <= currentEnd) {\n // Overlapping intervals, merge them\n currentEnd = Math.max(currentEnd, requests[i].responseEnd);\n } else {\n // Non-overlapping interval, add the duration to total time\n totalNetworkTime += currentEnd - currentStart;\n\n // Update current interval\n currentStart = requests[i].startTime;\n currentEnd = requests[i].responseEnd;\n }\n }\n\n // Step 4: Add the last interval\n totalNetworkTime += currentEnd - currentStart;\n\n return totalNetworkTime;\n}\n\nexport const REFRESH_INTERACTION = 'refresh';\nexport const TIME_RANGE_CHANGE_INTERACTION = 'time_range_change';\nexport const FILTER_ADDED_INTERACTION = 'filter_added';\nexport const FILTER_REMOVED_INTERACTION = 'filter_removed';\nexport const FILTER_CHANGED_INTERACTION = 'filter_changed';\nexport const FILTER_RESTORED_INTERACTION = 'filter_restored';\nexport const VARIABLE_VALUE_CHANGED_INTERACTION = 'variable_value_changed';\nexport const SCOPES_CHANGED_INTERACTION = 'scopes_changed';\nexport const ADHOC_KEYS_DROPDOWN_INTERACTION = 'adhoc_keys_dropdown';\nexport const ADHOC_VALUES_DROPDOWN_INTERACTION = 'adhoc_values_dropdown';\nexport const GROUPBY_DIMENSIONS_INTERACTION = 'groupby_dimensions';\n"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,4 @@ export { CursorSync } from './CursorSync.js';
|
|
|
3
3
|
export { SceneQueryController } from './SceneQueryController.js';
|
|
4
4
|
export { SceneInteractionTracker } from './SceneInteractionTracker.js';
|
|
5
5
|
export { LiveNowTimer } from './LiveNowTimer.js';
|
|
6
|
-
export { VizPanelRenderProfiler } from './VizPanelRenderProfiler.js';
|
|
7
|
-
export { ScenePerformanceTracker, getScenePerformanceTracker } from './ScenePerformanceTracker.js';
|
|
8
|
-
export { ADHOC_KEYS_DROPDOWN_INTERACTION, ADHOC_VALUES_DROPDOWN_INTERACTION, FILTER_ADDED_INTERACTION, FILTER_CHANGED_INTERACTION, FILTER_REMOVED_INTERACTION, FILTER_RESTORED_INTERACTION, GROUPBY_DIMENSIONS_INTERACTION, REFRESH_INTERACTION, SCOPES_CHANGED_INTERACTION, TIME_RANGE_CHANGE_INTERACTION, VARIABLE_VALUE_CHANGED_INTERACTION } from './interactionConstants.js';
|
|
9
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -5,7 +5,7 @@ import { RefreshPicker } from '@grafana/ui';
|
|
|
5
5
|
import { SceneObjectBase } from '../core/SceneObjectBase.js';
|
|
6
6
|
import { sceneGraph } from '../core/sceneGraph/index.js';
|
|
7
7
|
import { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig.js';
|
|
8
|
-
import { REFRESH_INTERACTION } from '../behaviors/
|
|
8
|
+
import { REFRESH_INTERACTION } from '../behaviors/SceneRenderProfiler.js';
|
|
9
9
|
|
|
10
10
|
const DEFAULT_INTERVALS = ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"];
|
|
11
11
|
class SceneRefreshPicker extends SceneObjectBase {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneRefreshPicker.js","sources":["../../../src/components/SceneRefreshPicker.tsx"],"sourcesContent":["import React from 'react';\nimport { Unsubscribable } from 'rxjs';\nimport { rangeUtil } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { RefreshPicker } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { REFRESH_INTERACTION } from '../behaviors/interactionConstants';\n\nexport const DEFAULT_INTERVALS = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'];\n\nexport interface SceneRefreshPickerState extends SceneObjectState {\n /**\n * Refresh interval, e.g. 5s, 1m, 2h\n */\n refresh: string;\n autoEnabled?: boolean;\n autoMinInterval?: string;\n autoValue?: string;\n /**\n * List of allowed refresh intervals, e.g. ['5s', '1m']\n */\n intervals?: string[];\n isOnCanvas?: boolean;\n primary?: boolean;\n withText?: boolean;\n /**\n * Overrides the default minRefreshInterval from the grafana config. Can be set to \"0s\" to remove the minimum refresh interval.\n */\n minRefreshInterval?: string;\n}\n\nexport class SceneRefreshPicker extends SceneObjectBase<SceneRefreshPickerState> {\n public static Component = SceneRefreshPickerRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['refresh'] });\n private _intervalTimer: ReturnType<typeof setInterval> | undefined;\n private _autoTimeRangeListener: Unsubscribable | undefined;\n private _autoRefreshBlocked = false;\n\n public constructor(state: Partial<SceneRefreshPickerState>) {\n const filterDissalowedIntervals = (i: string) => {\n const minInterval = state.minRefreshInterval ?? config.minRefreshInterval;\n try {\n return minInterval ? rangeUtil.intervalToMs(i) >= rangeUtil.intervalToMs(minInterval) : true;\n } catch (e) {\n // Unable to parse interval\n return false;\n }\n };\n\n super({\n refresh: '',\n ...state,\n autoValue: undefined,\n autoEnabled: state.autoEnabled ?? true,\n autoMinInterval: state.autoMinInterval ?? config.minRefreshInterval,\n intervals: (state.intervals ?? DEFAULT_INTERVALS).filter(filterDissalowedIntervals),\n });\n\n this.addActivationHandler(() => {\n this.setupIntervalTimer();\n\n const onVisibilityChange = () => {\n if (this._autoRefreshBlocked && document.visibilityState === 'visible') {\n this._autoRefreshBlocked = false;\n this.onRefresh();\n }\n };\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n return () => {\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n document.removeEventListener('visibilitychange', onVisibilityChange);\n this._autoTimeRangeListener?.unsubscribe();\n };\n });\n }\n\n public onRefresh = () => {\n const queryController = sceneGraph.getQueryController(this);\n\n if (queryController?.state.isRunning) {\n queryController.cancelAll();\n queryController.cancelProfile();\n return;\n }\n\n queryController?.startProfile(REFRESH_INTERACTION);\n\n const timeRange = sceneGraph.getTimeRange(this);\n\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n timeRange.onRefresh();\n this.setupIntervalTimer();\n };\n\n public onIntervalChanged = (interval: string) => {\n this.setState({ refresh: interval });\n this.setupIntervalTimer();\n };\n\n public getUrlState() {\n let refresh: string | undefined = this.state.refresh;\n\n if (typeof refresh !== 'string' || refresh.length === 0) {\n refresh = undefined;\n }\n\n return { refresh };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n const { intervals } = this.state;\n let refresh = values.refresh;\n\n if (typeof refresh === 'string' && isIntervalString(refresh)) {\n if (intervals?.includes(refresh)) {\n this.setState({ refresh });\n } else {\n this.setState({\n // Default to the first refresh interval if the interval from the URL is not allowed, just like in the old architecture.\n refresh: intervals ? intervals[0] : undefined,\n });\n }\n }\n }\n\n private setupAutoTimeRangeListener = () => {\n // If the time range has changed, we need to recalculate the auto interval but prevent unnecessary processing\n return sceneGraph.getTimeRange(this).subscribeToState((newState, prevState) => {\n if (newState.from !== prevState.from || newState.to !== prevState.to) {\n this.setupIntervalTimer();\n }\n });\n };\n\n private calculateAutoRefreshInterval = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const resolution = window?.innerWidth ?? 2000;\n return rangeUtil.calculateInterval(timeRange.state.value, resolution, this.state.autoMinInterval);\n };\n\n private isTabVisible() {\n return document.visibilityState === undefined || document.visibilityState === 'visible';\n }\n\n private setupIntervalTimer = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const { refresh, intervals } = this.state;\n\n if (this._intervalTimer || refresh === '') {\n clearInterval(this._intervalTimer);\n }\n\n if (refresh === '') {\n return;\n }\n\n // If the provided interval is not allowed\n if (refresh !== RefreshPicker.autoOption.value && intervals && !intervals.includes(refresh)) {\n return;\n }\n\n let intervalMs: number;\n\n // Unsubscribe from previous listener no matter what\n this._autoTimeRangeListener?.unsubscribe();\n\n if (refresh === RefreshPicker.autoOption.value) {\n const autoRefreshInterval = this.calculateAutoRefreshInterval();\n\n intervalMs = autoRefreshInterval.intervalMs;\n\n this._autoTimeRangeListener = this.setupAutoTimeRangeListener();\n\n if (autoRefreshInterval.interval !== this.state.autoValue) {\n this.setState({ autoValue: autoRefreshInterval.interval });\n }\n } else {\n intervalMs = rangeUtil.intervalToMs(refresh);\n }\n\n this._intervalTimer = setInterval(() => {\n if (this.isTabVisible()) {\n const queryController = sceneGraph.getQueryController(this);\n\n if (queryController?.state.isRunning) {\n queryController.cancelProfile();\n }\n\n queryController?.startProfile(REFRESH_INTERACTION);\n timeRange.onRefresh();\n } else {\n this._autoRefreshBlocked = true;\n }\n }, intervalMs);\n };\n}\n\nexport function SceneRefreshPickerRenderer({ model }: SceneComponentProps<SceneRefreshPicker>) {\n const { refresh, intervals, autoEnabled, autoValue, isOnCanvas, primary, withText } = model.useState();\n const isRunning = useQueryControllerState(model);\n\n let text = refresh === RefreshPicker.autoOption?.value ? autoValue : withText ? 'Refresh' : undefined;\n let tooltip: string | undefined;\n let width: string | undefined;\n\n if (isRunning) {\n tooltip = 'Cancel all queries';\n\n if (withText) {\n text = 'Cancel';\n }\n }\n\n if (withText) {\n width = '96px';\n }\n\n return (\n <RefreshPicker\n showAutoInterval={autoEnabled}\n value={refresh}\n intervals={intervals}\n tooltip={tooltip}\n width={width}\n text={text}\n onRefresh={() => {\n model.onRefresh();\n }}\n primary={primary}\n onIntervalChanged={model.onIntervalChanged}\n isLoading={isRunning}\n isOnCanvas={isOnCanvas ?? true}\n />\n );\n}\n\nfunction useQueryControllerState(model: SceneObject): boolean {\n const queryController = sceneGraph.getQueryController(model);\n if (!queryController) {\n return false;\n }\n\n return queryController.useState().isRunning;\n}\n\nfunction isIntervalString(str: string): boolean {\n try {\n const res = rangeUtil.describeInterval(str);\n return res.count > 0;\n } catch {\n return false;\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SceneRefreshPicker.js","sources":["../../../src/components/SceneRefreshPicker.tsx"],"sourcesContent":["import React from 'react';\nimport { Unsubscribable } from 'rxjs';\nimport { rangeUtil } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { RefreshPicker } from '@grafana/ui';\n\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneComponentProps, SceneObject, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { REFRESH_INTERACTION } from '../behaviors/SceneRenderProfiler';\n\nexport const DEFAULT_INTERVALS = ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'];\n\nexport interface SceneRefreshPickerState extends SceneObjectState {\n /**\n * Refresh interval, e.g. 5s, 1m, 2h\n */\n refresh: string;\n autoEnabled?: boolean;\n autoMinInterval?: string;\n autoValue?: string;\n /**\n * List of allowed refresh intervals, e.g. ['5s', '1m']\n */\n intervals?: string[];\n isOnCanvas?: boolean;\n primary?: boolean;\n withText?: boolean;\n /**\n * Overrides the default minRefreshInterval from the grafana config. Can be set to \"0s\" to remove the minimum refresh interval.\n */\n minRefreshInterval?: string;\n}\n\nexport class SceneRefreshPicker extends SceneObjectBase<SceneRefreshPickerState> {\n public static Component = SceneRefreshPickerRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['refresh'] });\n private _intervalTimer: ReturnType<typeof setInterval> | undefined;\n private _autoTimeRangeListener: Unsubscribable | undefined;\n private _autoRefreshBlocked = false;\n\n public constructor(state: Partial<SceneRefreshPickerState>) {\n const filterDissalowedIntervals = (i: string) => {\n const minInterval = state.minRefreshInterval ?? config.minRefreshInterval;\n try {\n return minInterval ? rangeUtil.intervalToMs(i) >= rangeUtil.intervalToMs(minInterval) : true;\n } catch (e) {\n // Unable to parse interval\n return false;\n }\n };\n\n super({\n refresh: '',\n ...state,\n autoValue: undefined,\n autoEnabled: state.autoEnabled ?? true,\n autoMinInterval: state.autoMinInterval ?? config.minRefreshInterval,\n intervals: (state.intervals ?? DEFAULT_INTERVALS).filter(filterDissalowedIntervals),\n });\n\n this.addActivationHandler(() => {\n this.setupIntervalTimer();\n\n const onVisibilityChange = () => {\n if (this._autoRefreshBlocked && document.visibilityState === 'visible') {\n this._autoRefreshBlocked = false;\n this.onRefresh();\n }\n };\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n return () => {\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n document.removeEventListener('visibilitychange', onVisibilityChange);\n this._autoTimeRangeListener?.unsubscribe();\n };\n });\n }\n\n public onRefresh = () => {\n const queryController = sceneGraph.getQueryController(this);\n\n if (queryController?.state.isRunning) {\n queryController.cancelAll();\n queryController.cancelProfile();\n return;\n }\n\n queryController?.startProfile(REFRESH_INTERACTION);\n\n const timeRange = sceneGraph.getTimeRange(this);\n\n if (this._intervalTimer) {\n clearInterval(this._intervalTimer);\n }\n\n timeRange.onRefresh();\n this.setupIntervalTimer();\n };\n\n public onIntervalChanged = (interval: string) => {\n this.setState({ refresh: interval });\n this.setupIntervalTimer();\n };\n\n public getUrlState() {\n let refresh: string | undefined = this.state.refresh;\n\n if (typeof refresh !== 'string' || refresh.length === 0) {\n refresh = undefined;\n }\n\n return { refresh };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n const { intervals } = this.state;\n let refresh = values.refresh;\n\n if (typeof refresh === 'string' && isIntervalString(refresh)) {\n if (intervals?.includes(refresh)) {\n this.setState({ refresh });\n } else {\n this.setState({\n // Default to the first refresh interval if the interval from the URL is not allowed, just like in the old architecture.\n refresh: intervals ? intervals[0] : undefined,\n });\n }\n }\n }\n\n private setupAutoTimeRangeListener = () => {\n // If the time range has changed, we need to recalculate the auto interval but prevent unnecessary processing\n return sceneGraph.getTimeRange(this).subscribeToState((newState, prevState) => {\n if (newState.from !== prevState.from || newState.to !== prevState.to) {\n this.setupIntervalTimer();\n }\n });\n };\n\n private calculateAutoRefreshInterval = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const resolution = window?.innerWidth ?? 2000;\n return rangeUtil.calculateInterval(timeRange.state.value, resolution, this.state.autoMinInterval);\n };\n\n private isTabVisible() {\n return document.visibilityState === undefined || document.visibilityState === 'visible';\n }\n\n private setupIntervalTimer = () => {\n const timeRange = sceneGraph.getTimeRange(this);\n const { refresh, intervals } = this.state;\n\n if (this._intervalTimer || refresh === '') {\n clearInterval(this._intervalTimer);\n }\n\n if (refresh === '') {\n return;\n }\n\n // If the provided interval is not allowed\n if (refresh !== RefreshPicker.autoOption.value && intervals && !intervals.includes(refresh)) {\n return;\n }\n\n let intervalMs: number;\n\n // Unsubscribe from previous listener no matter what\n this._autoTimeRangeListener?.unsubscribe();\n\n if (refresh === RefreshPicker.autoOption.value) {\n const autoRefreshInterval = this.calculateAutoRefreshInterval();\n\n intervalMs = autoRefreshInterval.intervalMs;\n\n this._autoTimeRangeListener = this.setupAutoTimeRangeListener();\n\n if (autoRefreshInterval.interval !== this.state.autoValue) {\n this.setState({ autoValue: autoRefreshInterval.interval });\n }\n } else {\n intervalMs = rangeUtil.intervalToMs(refresh);\n }\n\n this._intervalTimer = setInterval(() => {\n if (this.isTabVisible()) {\n const queryController = sceneGraph.getQueryController(this);\n\n if (queryController?.state.isRunning) {\n queryController.cancelProfile();\n }\n\n queryController?.startProfile(REFRESH_INTERACTION);\n timeRange.onRefresh();\n } else {\n this._autoRefreshBlocked = true;\n }\n }, intervalMs);\n };\n}\n\nexport function SceneRefreshPickerRenderer({ model }: SceneComponentProps<SceneRefreshPicker>) {\n const { refresh, intervals, autoEnabled, autoValue, isOnCanvas, primary, withText } = model.useState();\n const isRunning = useQueryControllerState(model);\n\n let text = refresh === RefreshPicker.autoOption?.value ? autoValue : withText ? 'Refresh' : undefined;\n let tooltip: string | undefined;\n let width: string | undefined;\n\n if (isRunning) {\n tooltip = 'Cancel all queries';\n\n if (withText) {\n text = 'Cancel';\n }\n }\n\n if (withText) {\n width = '96px';\n }\n\n return (\n <RefreshPicker\n showAutoInterval={autoEnabled}\n value={refresh}\n intervals={intervals}\n tooltip={tooltip}\n width={width}\n text={text}\n onRefresh={() => {\n model.onRefresh();\n }}\n primary={primary}\n onIntervalChanged={model.onIntervalChanged}\n isLoading={isRunning}\n isOnCanvas={isOnCanvas ?? true}\n />\n );\n}\n\nfunction useQueryControllerState(model: SceneObject): boolean {\n const queryController = sceneGraph.getQueryController(model);\n if (!queryController) {\n return false;\n }\n\n return queryController.useState().isRunning;\n}\n\nfunction isIntervalString(str: string): boolean {\n try {\n const res = rangeUtil.describeInterval(str);\n return res.count > 0;\n } catch {\n return false;\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -26,9 +26,15 @@ const DEFAULT_COMPARE_OPTIONS = [
|
|
|
26
26
|
{ label: "Month before", value: "1M" }
|
|
27
27
|
];
|
|
28
28
|
class SceneTimeRangeCompare extends SceneObjectBase {
|
|
29
|
-
constructor(state) {
|
|
30
|
-
super({
|
|
31
|
-
|
|
29
|
+
constructor(state = {}) {
|
|
30
|
+
super({
|
|
31
|
+
key: state.key || "compareWith",
|
|
32
|
+
compareOptions: DEFAULT_COMPARE_OPTIONS,
|
|
33
|
+
...state
|
|
34
|
+
});
|
|
35
|
+
this._urlSync = new SceneObjectUrlSyncConfig(this, {
|
|
36
|
+
keys: () => [this.state.key || "compareWith"]
|
|
37
|
+
});
|
|
32
38
|
this._onActivate = () => {
|
|
33
39
|
const sceneTimeRange = sceneGraph.getTimeRange(this);
|
|
34
40
|
this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });
|
|
@@ -115,25 +121,22 @@ class SceneTimeRangeCompare extends SceneObjectBase {
|
|
|
115
121
|
return void 0;
|
|
116
122
|
}
|
|
117
123
|
getUrlState() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
};
|
|
124
|
+
const key = this.state.key || "compareWith";
|
|
125
|
+
return { [key]: this.state.compareWith };
|
|
121
126
|
}
|
|
122
127
|
updateFromUrl(values) {
|
|
123
|
-
|
|
128
|
+
const key = this.state.key || "compareWith";
|
|
129
|
+
if (values[key] === PREVIOUS_PERIOD_VALUE) {
|
|
130
|
+
this.setState({ compareWith: PREVIOUS_PERIOD_VALUE });
|
|
124
131
|
return;
|
|
125
132
|
}
|
|
126
|
-
const compareWith = parseUrlParam(values
|
|
133
|
+
const compareWith = parseUrlParam(values[key]);
|
|
127
134
|
if (compareWith) {
|
|
128
135
|
const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);
|
|
129
136
|
if (compareOptions.find(({ value }) => value === compareWith)) {
|
|
130
|
-
this.setState({
|
|
131
|
-
compareWith
|
|
132
|
-
});
|
|
137
|
+
this.setState({ compareWith });
|
|
133
138
|
} else {
|
|
134
|
-
this.setState({
|
|
135
|
-
compareWith: "__previousPeriod"
|
|
136
|
-
});
|
|
139
|
+
this.setState({ compareWith: PREVIOUS_PERIOD_VALUE });
|
|
137
140
|
}
|
|
138
141
|
}
|
|
139
142
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneTimeRangeCompare.js","sources":["../../../src/components/SceneTimeRangeCompare.tsx"],"sourcesContent":["import { t, Trans } from '@grafana/i18n';\nimport { DataQueryRequest, DateTime, dateTime, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';\nimport { ButtonGroup, ButtonSelect, Checkbox, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React from 'react';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { DataQueryExtended } from '../querying/SceneQueryRunner';\nimport { ExtraQueryDescriptor, ExtraQueryDataProcessor, ExtraQueryProvider } from '../querying/ExtraQueryProvider';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { getCompareSeriesRefId } from '../utils/getCompareSeriesRefId';\nimport { parseUrlParam } from '../utils/parseUrlParam';\nimport { css } from '@emotion/css';\nimport { of } from 'rxjs';\n\ninterface SceneTimeRangeCompareState extends SceneObjectState {\n compareWith?: string;\n compareOptions: Array<{ label: string; value: string }>;\n hideCheckbox?: boolean;\n}\n\nconst PREVIOUS_PERIOD_VALUE = '__previousPeriod';\nconst NO_PERIOD_VALUE = '__noPeriod';\n\nexport const PREVIOUS_PERIOD_COMPARE_OPTION = {\n label: 'Previous period',\n value: PREVIOUS_PERIOD_VALUE,\n};\n\nexport const NO_COMPARE_OPTION = {\n label: 'None',\n value: NO_PERIOD_VALUE,\n};\n\nexport const DEFAULT_COMPARE_OPTIONS = [\n { label: 'Day before', value: '24h' },\n { label: 'Week before', value: '1w' },\n { label: 'Month before', value: '1M' },\n];\n\nexport class SceneTimeRangeCompare\n extends SceneObjectBase<SceneTimeRangeCompareState>\n implements ExtraQueryProvider<SceneTimeRangeCompareState>\n{\n static Component = SceneTimeRangeCompareRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, { keys: ['compareWith'] });\n\n public constructor(state: Partial<SceneTimeRangeCompareState>) {\n super({ compareOptions: DEFAULT_COMPARE_OPTIONS, ...state });\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });\n\n this._subs.add(\n sceneTimeRange.subscribeToState((timeRange) => {\n const compareOptions = this.getCompareOptions(timeRange.value);\n const stateUpdate: Partial<SceneTimeRangeCompareState> = { compareOptions };\n\n // if current compareWith is not applicable to the new time range, set it to previous period comparison\n if (Boolean(this.state.compareWith) && !compareOptions.find(({ value }) => value === this.state.compareWith)) {\n stateUpdate.compareWith = PREVIOUS_PERIOD_VALUE;\n }\n\n this.setState(stateUpdate);\n })\n );\n };\n\n public getCompareOptions = (timeRange: TimeRange) => {\n const diffDays = Math.ceil(timeRange.to.diff(timeRange.from));\n\n const matchIndex = DEFAULT_COMPARE_OPTIONS.findIndex(({ value }) => {\n const intervalInMs = rangeUtil.intervalToMs(value);\n return intervalInMs >= diffDays;\n });\n\n return [\n NO_COMPARE_OPTION,\n PREVIOUS_PERIOD_COMPARE_OPTION,\n ...DEFAULT_COMPARE_OPTIONS.slice(matchIndex).map(({ label, value }) => ({ label, value })),\n ];\n };\n\n public onCompareWithChanged = (compareWith: string) => {\n if (compareWith === NO_PERIOD_VALUE) {\n this.onClearCompare();\n } else {\n this.setState({ compareWith });\n }\n };\n\n public onClearCompare = () => {\n this.setState({ compareWith: undefined });\n };\n\n // Get a time shifted request to compare with the primary request.\n public getExtraQueries(request: DataQueryRequest): ExtraQueryDescriptor[] {\n const extraQueries: ExtraQueryDescriptor[] = [];\n const compareRange = this.getCompareTimeRange(request.range);\n if (!compareRange) {\n return extraQueries;\n }\n\n const targets = request.targets.filter((query: DataQueryExtended) => query.timeRangeCompare !== false);\n if (targets.length) {\n extraQueries.push({\n req: {\n ...request,\n targets,\n range: compareRange,\n },\n processor: timeShiftAlignmentProcessor,\n });\n }\n return extraQueries;\n }\n\n // The query runner should rerun the comparison query if the compareWith value has changed and there are queries that haven't opted out of TWC\n public shouldRerun(\n prev: SceneTimeRangeCompareState,\n next: SceneTimeRangeCompareState,\n queries: SceneDataQuery[]\n ): boolean {\n return (\n prev.compareWith !== next.compareWith && queries.find((query) => query.timeRangeCompare !== false) !== undefined\n );\n }\n\n public getCompareTimeRange(timeRange: TimeRange): TimeRange | undefined {\n let compareFrom: DateTime;\n let compareTo: DateTime;\n\n if (this.state.compareWith) {\n if (this.state.compareWith === PREVIOUS_PERIOD_VALUE) {\n const diffMs = timeRange.to.diff(timeRange.from);\n compareFrom = dateTime(timeRange.from!).subtract(diffMs);\n compareTo = dateTime(timeRange.to!).subtract(diffMs);\n } else {\n compareFrom = dateTime(timeRange.from!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n compareTo = dateTime(timeRange.to!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n }\n return {\n from: compareFrom,\n to: compareTo,\n raw: {\n from: compareFrom,\n to: compareTo,\n },\n };\n }\n\n return undefined;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n return {\n compareWith: this.state.compareWith,\n };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n if (!values.compareWith) {\n return;\n }\n\n const compareWith = parseUrlParam(values.compareWith);\n\n if (compareWith) {\n const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);\n\n if (compareOptions.find(({ value }) => value === compareWith)) {\n this.setState({\n compareWith,\n });\n } else {\n this.setState({\n compareWith: '__previousPeriod',\n });\n }\n }\n }\n}\n\n// Processor function for use with time shifted comparison series.\n// This aligns the secondary series with the primary and adds custom\n// metadata and config to the secondary series' fields so that it is\n// rendered appropriately.\nconst timeShiftAlignmentProcessor: ExtraQueryDataProcessor = (primary, secondary) => {\n const diff = secondary.timeRange.from.diff(primary.timeRange.from);\n secondary.series.forEach((series) => {\n series.refId = getCompareSeriesRefId(series.refId || '');\n series.meta = {\n ...series.meta,\n // @ts-ignore Remove when https://github.com/grafana/grafana/pull/71129 is released\n timeCompare: {\n diffMs: diff,\n isTimeShiftQuery: true,\n },\n };\n });\n return of(secondary);\n};\n\nfunction SceneTimeRangeCompareRenderer({ model }: SceneComponentProps<SceneTimeRangeCompare>) {\n const styles = useStyles2(getStyles);\n const { compareWith, compareOptions, hideCheckbox } = model.useState();\n\n const [previousCompare, setPreviousCompare] = React.useState(compareWith);\n const previousValue = compareOptions.find(({ value }) => value === previousCompare) ?? PREVIOUS_PERIOD_COMPARE_OPTION;\n\n const value = compareOptions.find(({ value }) => value === compareWith);\n const enabled = Boolean(value);\n\n const onClick = () => {\n if (enabled) {\n setPreviousCompare(compareWith);\n model.onClearCompare();\n } else if (!enabled) {\n model.onCompareWithChanged(previousValue.value);\n }\n };\n\n // When hideCheckbox is true, always show select and use NO_COMPARE_OPTION when no comparison is active\n const selectValue = hideCheckbox && !compareWith ? NO_COMPARE_OPTION : value;\n const showSelect = hideCheckbox || enabled;\n\n // Create display value with \"Comparison\" prefix when hideCheckbox is true\n const displayValue =\n hideCheckbox && selectValue\n ? {\n ...selectValue,\n label: `Comparison: ${selectValue.label}`,\n }\n : selectValue;\n\n return (\n <ButtonGroup>\n {!hideCheckbox && (\n <ToolbarButton\n variant=\"canvas\"\n tooltip={t(\n 'grafana-scenes.components.scene-time-range-compare-renderer.button-tooltip',\n 'Enable time frame comparison'\n )}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }}\n >\n <Checkbox label=\" \" value={enabled} onClick={onClick} />\n <Trans i18nKey=\"grafana-scenes.components.scene-time-range-compare-renderer.button-label\">Comparison</Trans>\n </ToolbarButton>\n )}\n\n {showSelect ? (\n <ButtonSelect\n variant=\"canvas\"\n value={displayValue}\n options={compareOptions}\n onChange={(v) => {\n model.onCompareWithChanged(v.value!);\n }}\n />\n ) : (\n <ToolbarButton className={styles.previewButton} disabled variant=\"canvas\" isOpen={false}>\n {previousValue.label}\n </ToolbarButton>\n )}\n </ButtonGroup>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n previewButton: css({\n '&:disabled': {\n border: `1px solid ${theme.colors.secondary.border}`,\n color: theme.colors.text.disabled,\n opacity: 1,\n },\n }),\n };\n}\n"],"names":["value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SceneTimeRangeCompare.js","sources":["../../../src/components/SceneTimeRangeCompare.tsx"],"sourcesContent":["import { t, Trans } from '@grafana/i18n';\nimport { DataQueryRequest, DateTime, dateTime, GrafanaTheme2, rangeUtil, TimeRange } from '@grafana/data';\nimport { ButtonGroup, ButtonSelect, Checkbox, ToolbarButton, useStyles2 } from '@grafana/ui';\nimport React from 'react';\nimport { sceneGraph } from '../core/sceneGraph';\nimport { SceneObjectBase } from '../core/SceneObjectBase';\nimport { SceneComponentProps, SceneDataQuery, SceneObjectState, SceneObjectUrlValues } from '../core/types';\nimport { DataQueryExtended } from '../querying/SceneQueryRunner';\nimport { ExtraQueryDescriptor, ExtraQueryDataProcessor, ExtraQueryProvider } from '../querying/ExtraQueryProvider';\nimport { SceneObjectUrlSyncConfig } from '../services/SceneObjectUrlSyncConfig';\nimport { getCompareSeriesRefId } from '../utils/getCompareSeriesRefId';\nimport { parseUrlParam } from '../utils/parseUrlParam';\nimport { css } from '@emotion/css';\nimport { of } from 'rxjs';\n\ninterface SceneTimeRangeCompareState extends SceneObjectState {\n compareWith?: string;\n compareOptions: Array<{ label: string; value: string }>;\n hideCheckbox?: boolean;\n key?: string;\n}\n\nconst PREVIOUS_PERIOD_VALUE = '__previousPeriod';\nconst NO_PERIOD_VALUE = '__noPeriod';\n\nexport const PREVIOUS_PERIOD_COMPARE_OPTION = {\n label: 'Previous period',\n value: PREVIOUS_PERIOD_VALUE,\n};\n\nexport const NO_COMPARE_OPTION = {\n label: 'None',\n value: NO_PERIOD_VALUE,\n};\n\nexport const DEFAULT_COMPARE_OPTIONS = [\n { label: 'Day before', value: '24h' },\n { label: 'Week before', value: '1w' },\n { label: 'Month before', value: '1M' },\n];\n\nexport class SceneTimeRangeCompare\n extends SceneObjectBase<SceneTimeRangeCompareState>\n implements ExtraQueryProvider<SceneTimeRangeCompareState>\n{\n static Component = SceneTimeRangeCompareRenderer;\n protected _urlSync = new SceneObjectUrlSyncConfig(this, {\n keys: () => [this.state.key || 'compareWith'],\n });\n\n public constructor(state: Partial<SceneTimeRangeCompareState> = {}) {\n super({\n key: state.key || 'compareWith',\n compareOptions: DEFAULT_COMPARE_OPTIONS,\n ...state,\n });\n this.addActivationHandler(this._onActivate);\n }\n\n private _onActivate = () => {\n const sceneTimeRange = sceneGraph.getTimeRange(this);\n this.setState({ compareOptions: this.getCompareOptions(sceneTimeRange.state.value) });\n\n this._subs.add(\n sceneTimeRange.subscribeToState((timeRange) => {\n const compareOptions = this.getCompareOptions(timeRange.value);\n const stateUpdate: Partial<SceneTimeRangeCompareState> = { compareOptions };\n\n // if current compareWith is not applicable to the new time range, set it to previous period comparison\n if (Boolean(this.state.compareWith) && !compareOptions.find(({ value }) => value === this.state.compareWith)) {\n stateUpdate.compareWith = PREVIOUS_PERIOD_VALUE;\n }\n\n this.setState(stateUpdate);\n })\n );\n };\n\n public getCompareOptions = (timeRange: TimeRange) => {\n const diffDays = Math.ceil(timeRange.to.diff(timeRange.from));\n\n const matchIndex = DEFAULT_COMPARE_OPTIONS.findIndex(({ value }) => {\n const intervalInMs = rangeUtil.intervalToMs(value);\n return intervalInMs >= diffDays;\n });\n\n return [\n NO_COMPARE_OPTION,\n PREVIOUS_PERIOD_COMPARE_OPTION,\n ...DEFAULT_COMPARE_OPTIONS.slice(matchIndex).map(({ label, value }) => ({ label, value })),\n ];\n };\n\n public onCompareWithChanged = (compareWith: string) => {\n if (compareWith === NO_PERIOD_VALUE) {\n this.onClearCompare();\n } else {\n this.setState({ compareWith });\n }\n };\n\n public onClearCompare = () => {\n this.setState({ compareWith: undefined });\n };\n\n // Get a time shifted request to compare with the primary request.\n public getExtraQueries(request: DataQueryRequest): ExtraQueryDescriptor[] {\n const extraQueries: ExtraQueryDescriptor[] = [];\n const compareRange = this.getCompareTimeRange(request.range);\n if (!compareRange) {\n return extraQueries;\n }\n\n const targets = request.targets.filter((query: DataQueryExtended) => query.timeRangeCompare !== false);\n if (targets.length) {\n extraQueries.push({\n req: {\n ...request,\n targets,\n range: compareRange,\n },\n processor: timeShiftAlignmentProcessor,\n });\n }\n return extraQueries;\n }\n\n // The query runner should rerun the comparison query if the compareWith value has changed and there are queries that haven't opted out of TWC\n public shouldRerun(\n prev: SceneTimeRangeCompareState,\n next: SceneTimeRangeCompareState,\n queries: SceneDataQuery[]\n ): boolean {\n return (\n prev.compareWith !== next.compareWith && queries.find((query) => query.timeRangeCompare !== false) !== undefined\n );\n }\n\n public getCompareTimeRange(timeRange: TimeRange): TimeRange | undefined {\n let compareFrom: DateTime;\n let compareTo: DateTime;\n\n if (this.state.compareWith) {\n if (this.state.compareWith === PREVIOUS_PERIOD_VALUE) {\n const diffMs = timeRange.to.diff(timeRange.from);\n compareFrom = dateTime(timeRange.from!).subtract(diffMs);\n compareTo = dateTime(timeRange.to!).subtract(diffMs);\n } else {\n compareFrom = dateTime(timeRange.from!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n compareTo = dateTime(timeRange.to!).subtract(rangeUtil.intervalToMs(this.state.compareWith));\n }\n return {\n from: compareFrom,\n to: compareTo,\n raw: {\n from: compareFrom,\n to: compareTo,\n },\n };\n }\n\n return undefined;\n }\n\n public getUrlState(): SceneObjectUrlValues {\n const key = this.state.key || 'compareWith';\n return { [key]: this.state.compareWith };\n }\n\n public updateFromUrl(values: SceneObjectUrlValues) {\n const key = this.state.key || 'compareWith';\n if (values[key] === PREVIOUS_PERIOD_VALUE) {\n this.setState({ compareWith: PREVIOUS_PERIOD_VALUE });\n return;\n }\n const compareWith = parseUrlParam(values[key]);\n if (compareWith) {\n const compareOptions = this.getCompareOptions(sceneGraph.getTimeRange(this).state.value);\n if (compareOptions.find(({ value }) => value === compareWith)) {\n this.setState({ compareWith });\n } else {\n this.setState({ compareWith: PREVIOUS_PERIOD_VALUE });\n }\n }\n }\n}\n\n// Processor function for use with time shifted comparison series.\n// This aligns the secondary series with the primary and adds custom\n// metadata and config to the secondary series' fields so that it is\n// rendered appropriately.\nconst timeShiftAlignmentProcessor: ExtraQueryDataProcessor = (primary, secondary) => {\n const diff = secondary.timeRange.from.diff(primary.timeRange.from);\n secondary.series.forEach((series) => {\n series.refId = getCompareSeriesRefId(series.refId || '');\n series.meta = {\n ...series.meta,\n // @ts-ignore Remove when https://github.com/grafana/grafana/pull/71129 is released\n timeCompare: {\n diffMs: diff,\n isTimeShiftQuery: true,\n },\n };\n });\n return of(secondary);\n};\n\nfunction SceneTimeRangeCompareRenderer({ model }: SceneComponentProps<SceneTimeRangeCompare>) {\n const styles = useStyles2(getStyles);\n const { compareWith, compareOptions, hideCheckbox } = model.useState();\n\n const [previousCompare, setPreviousCompare] = React.useState(compareWith);\n const previousValue = compareOptions.find(({ value }) => value === previousCompare) ?? PREVIOUS_PERIOD_COMPARE_OPTION;\n\n const value = compareOptions.find(({ value }) => value === compareWith);\n const enabled = Boolean(value);\n\n const onClick = () => {\n if (enabled) {\n setPreviousCompare(compareWith);\n model.onClearCompare();\n } else if (!enabled) {\n model.onCompareWithChanged(previousValue.value);\n }\n };\n\n // When hideCheckbox is true, always show select and use NO_COMPARE_OPTION when no comparison is active\n const selectValue = hideCheckbox && !compareWith ? NO_COMPARE_OPTION : value;\n const showSelect = hideCheckbox || enabled;\n\n // Create display value with \"Comparison\" prefix when hideCheckbox is true\n const displayValue =\n hideCheckbox && selectValue\n ? {\n ...selectValue,\n label: `Comparison: ${selectValue.label}`,\n }\n : selectValue;\n\n return (\n <ButtonGroup>\n {!hideCheckbox && (\n <ToolbarButton\n variant=\"canvas\"\n tooltip={t(\n 'grafana-scenes.components.scene-time-range-compare-renderer.button-tooltip',\n 'Enable time frame comparison'\n )}\n onClick={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }}\n >\n <Checkbox label=\" \" value={enabled} onClick={onClick} />\n <Trans i18nKey=\"grafana-scenes.components.scene-time-range-compare-renderer.button-label\">Comparison</Trans>\n </ToolbarButton>\n )}\n\n {showSelect ? (\n <ButtonSelect\n variant=\"canvas\"\n value={displayValue}\n options={compareOptions}\n onChange={(v) => {\n model.onCompareWithChanged(v.value!);\n }}\n />\n ) : (\n <ToolbarButton className={styles.previewButton} disabled variant=\"canvas\" isOpen={false}>\n {previousValue.label}\n </ToolbarButton>\n )}\n </ButtonGroup>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n previewButton: css({\n '&:disabled': {\n border: `1px solid ${theme.colors.secondary.border}`,\n color: theme.colors.text.disabled,\n opacity: 1,\n },\n }),\n };\n}\n"],"names":["value"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t } from '@grafana/i18n';
|
|
2
|
-
import { toUtc, getPanelOptionsWithDefaults, renderMarkdown, applyFieldOverrides, compareArrayValues, compareDataFrameStructures,
|
|
2
|
+
import { toUtc, getPanelOptionsWithDefaults, renderMarkdown, applyFieldOverrides, compareArrayValues, compareDataFrameStructures, CoreApp, DashboardCursorSync, PanelPlugin, PluginType } from '@grafana/data';
|
|
3
3
|
import { getPluginImportUtils, config, getAppEvents } from '@grafana/runtime';
|
|
4
4
|
import { SceneObjectBase } from '../../core/SceneObjectBase.js';
|
|
5
5
|
import { sceneGraph } from '../../core/sceneGraph/index.js';
|
|
@@ -14,7 +14,6 @@ import { mergeWith, cloneDeep, isArray, merge, isEmpty } from 'lodash';
|
|
|
14
14
|
import { UserActionEvent } from '../../core/events.js';
|
|
15
15
|
import { evaluateTimeRange } from '../../utils/evaluateTimeRange.js';
|
|
16
16
|
import { LiveNowTimer } from '../../behaviors/LiveNowTimer.js';
|
|
17
|
-
import { VizPanelRenderProfiler } from '../../behaviors/VizPanelRenderProfiler.js';
|
|
18
17
|
import { wrapPromiseInStateObservable, registerQueryWithController } from '../../querying/registerQueryWithController.js';
|
|
19
18
|
import { SceneDataTransformer } from '../../querying/SceneDataTransformer.js';
|
|
20
19
|
import { SceneQueryRunner } from '../../querying/SceneQueryRunner.js';
|
|
@@ -192,20 +191,6 @@ class VizPanel extends SceneObjectBase {
|
|
|
192
191
|
this.publishEvent(new UserActionEvent({ origin: this, interaction: "panel-menu-shown" }), true);
|
|
193
192
|
});
|
|
194
193
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Get the VizPanelRenderProfiler behavior if attached
|
|
197
|
-
*/
|
|
198
|
-
getProfiler() {
|
|
199
|
-
if (!this.state.$behaviors) {
|
|
200
|
-
return void 0;
|
|
201
|
-
}
|
|
202
|
-
for (const behavior of this.state.$behaviors) {
|
|
203
|
-
if (behavior instanceof VizPanelRenderProfiler) {
|
|
204
|
-
return behavior;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return void 0;
|
|
208
|
-
}
|
|
209
194
|
_onActivate() {
|
|
210
195
|
if (!this._plugin) {
|
|
211
196
|
this._loadPlugin(this.state.pluginId);
|
|
@@ -216,16 +201,12 @@ class VizPanel extends SceneObjectBase {
|
|
|
216
201
|
this.setState({ _renderCounter: ((_a = this.state._renderCounter) != null ? _a : 0) + 1 });
|
|
217
202
|
}
|
|
218
203
|
async _loadPlugin(pluginId, overwriteOptions, overwriteFieldConfig, isAfterPluginChange) {
|
|
219
|
-
const profiler = this.getProfiler();
|
|
220
204
|
const plugin = loadPanelPluginSync(pluginId);
|
|
221
205
|
if (plugin) {
|
|
222
|
-
const endPluginLoadCallback = profiler == null ? void 0 : profiler.onPluginLoadStart(pluginId);
|
|
223
|
-
endPluginLoadCallback == null ? void 0 : endPluginLoadCallback(plugin, true);
|
|
224
206
|
this._pluginLoaded(plugin, overwriteOptions, overwriteFieldConfig, isAfterPluginChange);
|
|
225
207
|
} else {
|
|
226
208
|
const { importPanelPlugin } = getPluginImportUtils();
|
|
227
209
|
try {
|
|
228
|
-
const endPluginLoadCallback = profiler == null ? void 0 : profiler.onPluginLoadStart(pluginId);
|
|
229
210
|
const panelPromise = importPanelPlugin(pluginId);
|
|
230
211
|
const queryControler = sceneGraph.getQueryController(this);
|
|
231
212
|
if (queryControler && queryControler.state.enableProfiling) {
|
|
@@ -233,7 +214,6 @@ class VizPanel extends SceneObjectBase {
|
|
|
233
214
|
});
|
|
234
215
|
}
|
|
235
216
|
const result = await panelPromise;
|
|
236
|
-
endPluginLoadCallback == null ? void 0 : endPluginLoadCallback(result, false);
|
|
237
217
|
this._pluginLoaded(result, overwriteOptions, overwriteFieldConfig, isAfterPluginChange);
|
|
238
218
|
} catch (err) {
|
|
239
219
|
this._pluginLoaded(getPanelPluginNotFound(pluginId));
|
|
@@ -353,16 +333,13 @@ class VizPanel extends SceneObjectBase {
|
|
|
353
333
|
*/
|
|
354
334
|
applyFieldConfig(rawData) {
|
|
355
335
|
var _a, _b, _c, _d;
|
|
356
|
-
const timestamp = performance.now();
|
|
357
336
|
const plugin = this._plugin;
|
|
358
|
-
const profiler = this.getProfiler();
|
|
359
337
|
if (!plugin || plugin.meta.skipDataQuery || !rawData) {
|
|
360
338
|
return emptyPanelData;
|
|
361
339
|
}
|
|
362
340
|
if (this._prevData === rawData && this._dataWithFieldConfig) {
|
|
363
341
|
return this._dataWithFieldConfig;
|
|
364
342
|
}
|
|
365
|
-
const endFieldConfigCallback = profiler == null ? void 0 : profiler.onFieldConfigStart(timestamp);
|
|
366
343
|
const pluginDataSupport = plugin.dataSupport || { alertStates: false, annotations: false };
|
|
367
344
|
const fieldConfigRegistry = plugin.fieldConfigRegistry;
|
|
368
345
|
const prevFrames = (_b = (_a = this._dataWithFieldConfig) == null ? void 0 : _a.series) != null ? _b : [];
|
|
@@ -402,18 +379,6 @@ class VizPanel extends SceneObjectBase {
|
|
|
402
379
|
this._dataWithFieldConfig.annotations = void 0;
|
|
403
380
|
}
|
|
404
381
|
this._prevData = rawData;
|
|
405
|
-
if (profiler) {
|
|
406
|
-
let dataPointsCount = 0;
|
|
407
|
-
let seriesCount = 0;
|
|
408
|
-
for (const frame of newFrames) {
|
|
409
|
-
if (frame.length && frame.fields.length) {
|
|
410
|
-
const numericFields = frame.fields.filter((field) => field.type === FieldType.number).length;
|
|
411
|
-
seriesCount += numericFields;
|
|
412
|
-
dataPointsCount += frame.fields.reduce((sum, field) => sum + field.values.length, 0);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
endFieldConfigCallback == null ? void 0 : endFieldConfigCallback(performance.now(), dataPointsCount, seriesCount);
|
|
416
|
-
}
|
|
417
382
|
return this._dataWithFieldConfig;
|
|
418
383
|
}
|
|
419
384
|
clone(withState) {
|