Как создать изображение гистограммы на nodejs без браузера?

У вас есть один проект nodejs, использующий генератор PDF, и вам нужно вставить в него гистограмму, но проект работает на сервере без настольного компьютера.

Есть ли какая-либо библиотека или метод для создания изображения гистограммы на nodejs во время выполнения без веб-браузера для вставки его в файл PDF?

Я использую puppeteer для создания PDF-файла, но библиотека Chart.js не может визуализировать холст, например:

await page.setContent(`<!DOCTYPE html>
<html><body>
<canvas id = "chart"></canvas>
<script>
    const ctx = document.getElementById('chart');

    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
            datasets: [{
                label: '# of Votes',
                data: [12, 19, 3, 5, 2, 3],
                borderWidth: 1
            }]
        },
        options: {
            scales: { y: { beginAtZero: true } }
        }
    });
</script>
</body></html>`,
{ waitUntil: 'domcontentloaded' });

await page.addScriptTag({ url: 'https://cdn.jsdelivr.net/npm/chart.js' })

Результат — пустая страница. Вот почему я ищу лучший вариант — создать простое изображение и вставить его напрямую.

Я также попробовал:

await page.setContent(`<!DOCTYPE html>
<html><body>
<canvas id = "chart"></canvas>
</body></html>`,
{ waitUntil: [ 'load', 'networkidle0' ] });

await page.addScriptTag({ url: 'https://cdn.jsdelivr.net/npm/chart.js' });
await page.addScriptTag({ content: `
    const ctx = document.getElementById('chart');

    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
            datasets: [{
                label: '# of Votes',
                data: [12, 19, 3, 5, 2, 3],
                borderWidth: 1
            }]
        },
        options: {
            scales: { y: { beginAtZero: true } }
        }
    });
});

Вам нужно добавить тег сценария, а затем установить содержимое страницы. В противном случае вы пытаетесь запуститьchart.js до его загрузки. См. Puppeteer с Chart.js

ggorlen 20.04.2024 00:59

Спасибо, я изменил ожидание на waitUntil: ["load","networkidle0"] и переместил тег сценария на page.addScriptTag в конец URL-адреса cdn, но это не работает.

e-info128 20.04.2024 01:12

Вы пытались запустить точный код в моем ответе? Дайте мне знать, если это сработает для вас. В ["load", "networkidle0"] нет смысла, поскольку «загрузка» всегда происходит до «networkidle0».

ggorlen 20.04.2024 01:12

Я обновляю вопрос с изменениями.

e-info128 20.04.2024 01:13

Ваше обновление немного сделало мой ответ недействительным, поэтому мне, вероятно, придется откатить его. Можете ли вы сообщить мне, подойдет ли мой ответ вам или нет? Пожалуйста, дословно запустите точный код и убедитесь, что файл test.png записан. Ваша вторая попытка имеет больше смысла, но я бы просто сделал все это за один setContent вызов, как показано. Если это не сработает, я рассмотрю возможность устранения неполадок при второй попытке.

ggorlen 20.04.2024 01:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
175
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы добавляете скрипт после запуска кодаchart.js, который от него зависит. Попробуйте сначала добавить скрипт:

const puppeteer = require("puppeteer"); // ^22.6.0

const html = `<!DOCTYPE html>
<html><body>
<script src = "https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id = "chart"></canvas>
<script>
    const ctx = document.getElementById('chart');
    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
            datasets: [{
                label: '# of Votes',
                data: [12, 19, 3, 5, 2, 3],
                borderWidth: 1
            }]
        },
        options: {
            scales: { y: { beginAtZero: true } },
            animation: { duration: 0 },
        }
    });
</script>
</body></html>`;

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  await page.setContent(html);
  await page.pdf({path: "test.pdf"});
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

Обратите внимание, что я также отключаю анимацию, поэтому на снимке экрана отображается окончательная диаграмма, а не ее текущий рендеринг. Если вы все еще видите недостающие части, вы можете подождать, пока не поступят запросы, или использовать более широкий (менее оптимальный) подход, например setContent(html, {waitUntil: "networkidle0"}).

Когда кажется, что что-то «не отображается» (или что-то еще) в веб-проектах, обязательно посмотрите в инструментах разработчика, нет ли ошибок JS. Ваш исходный код должен содержать Uncaught ReferenceError: Chart is not defined, что является довольно четким описанием проблемы.

Вопреки первоначальному заголовку вашего поста, мы используем здесь браузер, он просто работает без головы. Полезно открыть его для временной отладки с помощью puppeteer.launch({headless: false}).

Смотрите также:

Другие вопросы по теме