scripts/thumbnail.js (73 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ const fs = require('fs'); const path = require('path'); const echarts = require('echarts'); const chalk = require('chalk'); const seedrandom = require('seedrandom'); /** Use seed to make sure each time data is the same when making thumbnails */ let myRandom = new seedrandom('echarts-random'); // Fixed random generator Math.random = function () { const val = myRandom(); return val; }; /** * Generate a thumbnail for the custom series using SVG SSR. */ async function thumbnail(seriesName) { const seriesPath = path.join(__dirname, '..', 'custom-series', seriesName); const testPath = path.join(seriesPath, 'test', 'index.html'); const outputPath = path.join('./screenshots', `${seriesName}.svg`); // Install the custom series const customSeries = require(`../custom-series/${seriesName}`); echarts.use(customSeries); let chart = echarts.init(null, null, { renderer: 'svg', ssr: true, width: 600, height: 400, }); // Load the js code from the content of the last <script></script> // in 'test/index.html' const html = fs.readFileSync(testPath, 'utf8'); const lastScriptStartIndex = html.lastIndexOf('<script>'); const lastScriptEndIndex = html.lastIndexOf('</script>'); const jsCode = html.substring(lastScriptStartIndex + 8, lastScriptEndIndex); // Ignore the lines containing `echarts.use`, `echarts.init` and `.setOption` // TODO: Not considered the case where there are multiple `chart.setOption` // calls const lines = jsCode.split('\n'); const code = lines .filter( (line) => !line.includes('echarts.use') && !line.includes('echarts.init') && !line.includes('chart.setOption') ) .join('\n'); // Run the code try { // Load d3 and d3-contour using dynamic import const d3 = await import('d3'); const d3Contour = await import('d3-contour'); // Assign d3 and d3Contour to the global object globalThis.d3 = d3; globalThis.d3Contour = d3Contour; eval(code); // To make sure text is readable in dark mode option.backgroundColor = '#fff'; chart.setOption(option); } catch (error) { console.error(chalk.red(error.stack)); console.info(chalk.blue(code)); return; } const svg = chart.renderToSVGString(); chart.dispose(); chart = null; option = null; // Save the SVG to file fs.writeFileSync(outputPath, svg); } const args = process.argv.slice(2); if (args.length === 0) { // Generate thumbnails for all custom series const dirs = fs.readdirSync(path.join(__dirname, '..', 'custom-series')); dirs.forEach((name) => { if ( fs .statSync(path.join(__dirname, '..', 'custom-series', name)) .isDirectory() ) { console.log(chalk.cyan(`Generating thumbnail for ${name}.`)); thumbnail(name); } }); } else { // Generate thumbnail for the specified custom series args.forEach((name) => { console.log(`Generating thumbnail for ${name}.`); thumbnail(name); }); }