diff --git a/package.json b/package.json
index ed573845c..f151e4e6b 100644
--- a/package.json
+++ b/package.json
@@ -84,6 +84,7 @@
"@ollion/flow-system-icon": "latest",
"@ollion/flow-table": "workspace:*",
"d3": "^7.6.1",
+ "html2canvas": "^1.4.1",
"jspdf": "^2.5.1",
"lit": "^3.1.0"
},
diff --git a/packages/flow-dashboard/src/components/f-dashboard/f-dashboard.ts b/packages/flow-dashboard/src/components/f-dashboard/f-dashboard.ts
index dbe44bcfe..59fa5bb7f 100644
--- a/packages/flow-dashboard/src/components/f-dashboard/f-dashboard.ts
+++ b/packages/flow-dashboard/src/components/f-dashboard/f-dashboard.ts
@@ -50,7 +50,7 @@ export class FDashboard extends FRoot {
render() {
return html`
- ${this.config.widgets.map(wgt => {
+ ${this.config?.widgets.map(wgt => {
return keyed(
wgt.id,
html`
= createRef
();
chartLegends: Ref = createRef();
@@ -252,7 +252,7 @@ export class FTimeseriesChart extends FRoot {
height="100%"
>
${svg``}
+ >${svg``}
) =>
this.handleHeaderInput(event, columnHeader[1])}
@@ -297,7 +296,7 @@ export class FTableSchema extends FRoot {
.actions=${actions}
.align=${cell.align}
data-background="${this.stickyCellBackground}"
- ?sticky-left=${ifDefined(sticky)}
+ ?sticky-left=${sticky}
>${this.getCellTemplate(row.data[columnHeader[0]], highlightTerm)}
`;
})}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 73c2d5c77..bd1c581e7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -47,6 +47,9 @@ importers:
d3:
specifier: ^7.6.1
version: 7.8.5
+ html2canvas:
+ specifier: ^1.4.1
+ version: 1.4.1
jspdf:
specifier: ^2.5.1
version: 2.5.1
@@ -6883,7 +6886,6 @@ packages:
engines: {node: '>= 0.6.0'}
requiresBuild: true
dev: false
- optional: true
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -7713,7 +7715,6 @@ packages:
dependencies:
utrie: 1.0.2
dev: false
- optional: true
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -9705,7 +9706,6 @@ packages:
css-line-break: 2.1.0
text-segmentation: 1.0.3
dev: false
- optional: true
/http-assert@1.5.0:
resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==}
@@ -13830,7 +13830,6 @@ packages:
dependencies:
utrie: 1.0.2
dev: false
- optional: true
/text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
@@ -14418,7 +14417,6 @@ packages:
dependencies:
base64-arraybuffer: 1.0.2
dev: false
- optional: true
/uuid@3.4.0:
resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
diff --git a/stories/flow-dashboard/f-dashboard.stories.ts b/stories/flow-dashboard/f-dashboard.stories.ts
index 657ae5dbf..bf64c2cfe 100644
--- a/stories/flow-dashboard/f-dashboard.stories.ts
+++ b/stories/flow-dashboard/f-dashboard.stories.ts
@@ -1,14 +1,11 @@
import { Meta } from "@storybook/web-components";
import { html } from "lit-html";
-import {
- FDashboard,
- FDashboardConfig,
- FDashboardWidget,
- FTimeseriesChartConfig
-} from "@ollion/flow-dashboard";
+import type { FDashboard, FDashboardConfig, FDashboardWidget } from "@ollion/flow-dashboard";
import { generateTimeseriesChartData } from "./mock-data-utils";
import { faker } from "@faker-js/faker";
import { createRef, ref } from "lit/directives/ref.js";
+import html2canvas from "html2canvas";
+import jsPDF from "jspdf";
export default {
title: "@ollion/flow-dashboard/f-dashboard",
@@ -32,7 +29,7 @@ const getWidgets = () => {
];
const widgets: FDashboardWidget[] = [];
const startFrom = new Date();
- for (let index = 0; index < 10; index++) {
+ for (let index = 0; index < 20; index++) {
if (index % 2 === 0) {
widgets.push({
type: "timeseries",
@@ -52,7 +49,9 @@ const getWidgets = () => {
>
- ${name}
+ ${name}
${description}
`;
@@ -101,8 +100,10 @@ const getWidgets = () => {
return widgets;
};
+
const Template = () => {
const dashboardRef = createRef();
+ const imgRef = createRef();
const dashboardConfig: FDashboardConfig = {
widgets: getWidgets()
};
@@ -114,7 +115,68 @@ const Template = () => {
}
};
- return html`
+ /**
+ * Download file as image in pdf
+ *
+ *
+ */
+ const downloadFile = () => {
+ const element = document.querySelector("#dashboard-to-export") as FDashboard;
+
+ html2canvas(element, { scale: 1 }).then(function (canvas) {
+ const imgData = canvas.toDataURL("image/png");
+ const imgWidth = 794;
+ const pageHeight = 1115;
+ const imgHeight = (canvas.height * imgWidth) / canvas.width;
+ let heightLeft = imgHeight;
+ // Initialize jsPDF
+ const pdf = new jsPDF({
+ orientation: "p",
+ unit: "px",
+ format: [794, 1115]
+ });
+ pdf.setDisplayMode("original");
+ let position = 0; // give some top padding to first page
+
+ const allAnchors = element.querySelectorAll("a");
+ for (let l = 0; l < allAnchors.length; l++) {
+ const anchorElement = allAnchors.item(l);
+ const linkX = anchorElement.getBoundingClientRect().x - element.getBoundingClientRect().x;
+ const linkY = anchorElement.getBoundingClientRect().y - element.getBoundingClientRect().y;
+ const linkWidth = anchorElement.offsetWidth;
+ const linkHeight = anchorElement.offsetHeight;
+
+ pdf.link(linkX, linkY, linkWidth, linkHeight, {
+ url: anchorElement.href
+ });
+ }
+
+ pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
+ heightLeft -= pageHeight;
+
+ while (heightLeft >= 0) {
+ position += heightLeft - imgHeight; // top padding for other pages
+ pdf.addPage();
+
+ pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
+ heightLeft -= pageHeight;
+ }
+
+ // Save the PDF
+ pdf.save("canvas_to_pdf.pdf");
+ });
+ };
+
+ return html`
+ Ollion
+
{
gap="auto"
align="middle-left"
>
- Click on randomize button to generate new data
-
+ Click on export button to generate pdf
+
-
+
+
`;
};