158 lines
6.2 KiB
JavaScript
158 lines
6.2 KiB
JavaScript
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
|
|
import puppeteer from "puppeteer";
|
|
import * as fs from "node:fs";
|
|
import * as cp from "node:child_process";
|
|
import * as path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import EXAMPLES from "./src/data/features.js";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
// features.js uses CJS exports.default, import it dynamically
|
|
// const EXAMPLES = (await import("./src/data/features.ts")).default;
|
|
|
|
const perspective = import(
|
|
"@perspective-dev/client/dist/esm/perspective.node.js"
|
|
);
|
|
|
|
const DEFAULT_VIEWPORT = {
|
|
width: 400,
|
|
height: 300,
|
|
};
|
|
|
|
async function run_with_theme(page, is_dark = false, order) {
|
|
await page.goto("http://localhost:8080/");
|
|
await page.setContent(template(is_dark));
|
|
await page.setViewport(DEFAULT_VIEWPORT);
|
|
await page.evaluate(async () => {
|
|
while (!window.__TEST_PERSPECTIVE_READY__) {
|
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
}
|
|
});
|
|
|
|
await page.evaluate(async function () {
|
|
const viewer = document.querySelector("perspective-viewer");
|
|
await viewer.flush();
|
|
await viewer.toggleConfig();
|
|
});
|
|
|
|
for (const idx in EXAMPLES) {
|
|
const { config, viewport } = EXAMPLES[idx];
|
|
await page.setViewport(viewport || DEFAULT_VIEWPORT);
|
|
const new_config = Object.assign(
|
|
{
|
|
plugin: "Datagrid",
|
|
group_by: [],
|
|
expressions: {},
|
|
split_by: [],
|
|
sort: [],
|
|
aggregates: {},
|
|
},
|
|
config,
|
|
);
|
|
console.log(JSON.stringify(new_config));
|
|
|
|
await page.evaluate(async (config) => {
|
|
const viewer = document.querySelector("perspective-viewer");
|
|
await viewer.reset();
|
|
await viewer.restore(config);
|
|
}, new_config);
|
|
|
|
const screenshot = await page.screenshot({
|
|
captureBeyondViewport: false,
|
|
fullPage: true,
|
|
});
|
|
|
|
const name = `static/features/feature_${idx}${
|
|
is_dark ? "_dark" : ""
|
|
}.png`;
|
|
|
|
fs.writeFileSync(name, screenshot);
|
|
cp.execSync(`convert ${name} -resize 200x150 ${name}`);
|
|
}
|
|
|
|
const suffix = is_dark ? "_dark" : "";
|
|
const montage_files = order.map(
|
|
(idx) => `static/features/feature_${idx}${suffix}.png`,
|
|
);
|
|
|
|
cp.execSync(
|
|
`montage -mode concatenate -background none -tile 5x ${montage_files.join(
|
|
" ",
|
|
)} static/features/montage${is_dark ? "_dark" : "_light"}.png`,
|
|
);
|
|
}
|
|
|
|
async function run() {
|
|
if (
|
|
!fs.existsSync("static/features") ||
|
|
fs.readdirSync("static/features").length === 0
|
|
) {
|
|
console.log("Generating feature screenshots!");
|
|
fs.mkdirSync(path.join(__dirname, "static/features"), {
|
|
recursive: true,
|
|
});
|
|
|
|
const x = await perspective;
|
|
const server = new x.WebSocketServer({
|
|
assets: [
|
|
path.join(__dirname, "."),
|
|
path.join(__dirname, "../node_modules"),
|
|
],
|
|
});
|
|
|
|
const indices = Array.from({ length: EXAMPLES.length }, (_, i) => i);
|
|
for (let i = indices.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[indices[i], indices[j]] = [indices[j], indices[i]];
|
|
}
|
|
|
|
const browser = await puppeteer.launch({ headless: true });
|
|
const page = await browser.newPage();
|
|
await run_with_theme(page, false, indices);
|
|
await run_with_theme(page, true, indices);
|
|
await page.close();
|
|
await browser.close();
|
|
await server.close();
|
|
|
|
fs.writeFileSync(
|
|
path.join(__dirname, "static/features/montage_map.json"),
|
|
JSON.stringify({
|
|
tile_width: 200,
|
|
tile_height: 150,
|
|
columns: 5,
|
|
order: indices,
|
|
}),
|
|
);
|
|
}
|
|
|
|
if (!fs.existsSync("static/blocks")) {
|
|
fs.mkdirSync("static/blocks");
|
|
}
|
|
|
|
const { dist_examples } = await import("../examples/blocks/index.mjs");
|
|
await dist_examples(`${__dirname}/static/blocks`);
|
|
}
|
|
|
|
function template(is_dark) {
|
|
return fs
|
|
.readFileSync(path.join(__dirname, "template.html"))
|
|
.toString()
|
|
.replace("/css/pro.css", is_dark ? "/css/pro-dark.css" : "/css/pro.css")
|
|
.trim();
|
|
}
|
|
|
|
run();
|