diff --git a/package-lock.json b/package-lock.json index 78d4b9eba1a..fc7d30bd968 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19785,6 +19785,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/html-to-image": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-1.11.13.tgz", + "integrity": "sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==", + "dev": true, + "license": "MIT" + }, "node_modules/html-void-elements": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", @@ -36113,6 +36120,7 @@ "fflate": "^0.8.2", "globals": "^16.0.0", "gridstack": "^11.3.0", + "html-to-image": "^1.11.13", "jsdom": "^26.0.0", "json-schema": "^0.4.0", "lucide-svelte": "^0.298.0", diff --git a/web-common/package.json b/web-common/package.json index cb7343d0923..fbc8a1d5ece 100644 --- a/web-common/package.json +++ b/web-common/package.json @@ -73,6 +73,7 @@ "fflate": "^0.8.2", "globals": "^16.0.0", "gridstack": "^11.3.0", + "html-to-image": "^1.11.13", "jsdom": "^26.0.0", "json-schema": "^0.4.0", "lucide-svelte": "^0.298.0", diff --git a/web-common/src/features/dashboards/time-series/MetricsTimeSeriesCharts.svelte b/web-common/src/features/dashboards/time-series/MetricsTimeSeriesCharts.svelte index 559305143cd..a814d0ed0a5 100644 --- a/web-common/src/features/dashboards/time-series/MetricsTimeSeriesCharts.svelte +++ b/web-common/src/features/dashboards/time-series/MetricsTimeSeriesCharts.svelte @@ -44,6 +44,8 @@ import MeasureChart from "./measure-chart/MeasureChart.svelte"; import MeasureChartXAxis from "./measure-chart/MeasureChartXAxis.svelte"; import { ScrubController } from "./measure-chart/ScrubController"; + import ThreeDot from "@rilldata/web-common/components/icons/ThreeDot.svelte"; + import ScreenshotContainer from "@rilldata/web-common/features/dashboards/time-series/ScreenshotContainer.svelte"; const { rillTime } = featureFlags; @@ -179,6 +181,9 @@ $: annotationsEnabled = !!$exploreValidSpec.data?.metricsView?.annotations?.length; + let screenshotDialogOpen = false; + let screenshotDialogMeasure: MetricsViewSpecMeasure | undefined = undefined; + // Pan handler function handlePan(direction: "left" | "right") { const panRange = $getNewPanRange(direction); @@ -253,6 +258,11 @@ measureSelection.clear(); } } + + function openScreenshotDialog(measure: MetricsViewSpecMeasure) { + screenshotDialogMeasure = measure; + screenshotDialogOpen = true; + } @@ -392,39 +402,54 @@ /> {#if activeTimeGrain} - handlePan("left")} - onPanRight={() => handlePan("right")} - {showComparison} - {showTimeDimensionDetail} - dynamicYAxis={dynamicYAxisScale} - onScrub={handleScrub} - onScrubClear={() => { - metricsExplorerStore.setSelectedScrubRange( - exploreName, - undefined, - ); - }} - /> +
+ handlePan("left")} + onPanRight={() => handlePan("right")} + {showComparison} + {showTimeDimensionDetail} + dynamicYAxis={dynamicYAxisScale} + onScrub={handleScrub} + onScrubClear={() => { + metricsExplorerStore.setSelectedScrubRange( + exploreName, + undefined, + ); + }} + /> + + + + + + + openScreenshotDialog(measure)} + > + Download as PNG + + + +
{:else}
@@ -442,3 +467,23 @@ }} onReplace={createPivot} /> + +{#if screenshotDialogMeasure} + +{/if} diff --git a/web-common/src/features/dashboards/time-series/ScreenshotContainer.svelte b/web-common/src/features/dashboards/time-series/ScreenshotContainer.svelte new file mode 100644 index 00000000000..c85f1906e96 --- /dev/null +++ b/web-common/src/features/dashboards/time-series/ScreenshotContainer.svelte @@ -0,0 +1,182 @@ + + + + + + Export chart + + + +
+
+
+

+ {measure.displayName || measure.name} +

+ {#if measure.description} +

{measure.description}

+ {/if} +
+
+
{formattedTimeRange}
+
+ + + +
+ {#if timeGranularity} +
+
+ +
+ {/if} + + + + {#if timeGranularity} + + {/if} +
+ +
+ Rill + Generated {generatedTime} +
+
+
+ + + + + +
+
diff --git a/web-common/src/features/themes/selectors.ts b/web-common/src/features/themes/selectors.ts index d05ab43a6a2..5a55017bddc 100644 --- a/web-common/src/features/themes/selectors.ts +++ b/web-common/src/features/themes/selectors.ts @@ -72,6 +72,7 @@ export function createResolvedThemeStore( queryClient, ); return themeQuery.subscribe(($themeQuery) => { + console.log(name, $themeQuery.data); if ($themeQuery.data?.theme?.spec) { set(new Theme($themeQuery.data.theme.spec)); } else {