По-видимому, (локально) преобразование диаграмм (в PDF-файлы) из chart.js на самом деле не так просто, а преобразование диаграмм из vue-chartjs еще сложнее. К счастью, есть (по крайней мере) два способа сделать это, хотя они не очень оптимальны.
1) Легкий путь (и)
image-charts.com предоставляет API, который может принимать данные диаграммы в формате chart.js и преобразовывать их в изображение. , но, похоже, он не может преобразовать его в PDF.
Например, вы можете передать эти данные в виде URL-адреса диаграммам изображений:
https://image-charts.com/chart.js/2.8.0?
bkg=white
&c= {
type: 'line',
data: { labels: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug'],
datasets: [
{
backgroundColor: 'rgba(255,150,150,0.5)',
borderColor:'rgb(255,150,150)',
data:[-23,64,21,53,-39,-30,28,-10],
label:'Dataset',fill:'origin'
}
]
}
}
... и вы получите это обратно:
![image-charts-demo](https://i.stack.imgur.com/E1Huh.png)
Его можно использовать бесплатно, без ограничения скорости, но в правом верхнем углу есть водяной знак, как вы можете видеть на изображении выше. Бесплатный план включает (в настоящее время):
- Неограниченное создание диаграмм
- Водяной знак
- Задержка запроса менее секунды
- Премиум-сеть Google
- CDN по всему миру
- Поддержка WebP и Gif
... но вы можете ознакомиться с их ценами для получения дополнительной информации и других планов. Также ознакомьтесь с их документами для получения дополнительной информации и поиграйте в их песочница, чтобы узнать, что вам нужно.
В качестве альтернативы Quickchart.io также предоставляет простой в использовании API, который принимает данные диаграммы и выводит PDF-файл (или другие форматы) для использования. Просто сделайте запрос к /chart
конечной точке с вашими данными диаграммы / параметрами форматирования, и вы получите вывод в формате PDF:
https://quickchart.io/chart?
format=PDF
&bkg=white
&c= {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [
{ label: 'Users', data: [50, 60, 70, 180] },
{ label: 'Revenue', data: [100, 200, 300, 400] }
]
}
}
Просмотреть PDF здесь
Вы можете поиграть в их песочнице и ознакомиться с их документами здесь для получения дополнительной информации, но обратите внимание, что API имеет ограничение скорости, если вы оплатить премиальные планы. Также имеется модуль node.js / JS, который вы можете импортировать и использовать в своем проекте здесь.
Хотя водяного знака нет и вы получаете PDF-файл, графические диаграммы по-прежнему, вероятно, являются лучшим решением, если ваше приложение обслуживает множество пользователей, и вам не хочется платить за премиальные планы, поскольку они (графические диаграммы) не Запросы на ограничение скорости.
2) Свободный и местный и слишком сложный путь
Для подхода без внешнего API, который может работать автономно и локально, вы можете использовать html2canvas и jsPDF для визуализации диаграмм в PDF-файлы. Это значительно сложнее, особенно с vue-chartjs, потому что вам нужно специально поместить диаграмму в контейнер размером 594 на 459 пикселей (для бумаги формата Letter) и убедиться, что параметры диаграммы установлены на
{ responsive: true, maintainAspectRatio: false }
... или изображение будет либо растянутым, либо сжатым, либо слишком маленьким или слишком большим, например:
![отказ 4]( https://i.stack.imgur.com/Pb1Dt.png )
Но, если вы сделаете все это, вы можете получить довольно красивые PDF-файлы с диаграммами:
![успех 2](https: // i. stack.imgur.com/EgfpQ.png )
Я думаю, что самый простой способ экспортировать диаграммы в PDF-файлы - это создать модуль, который можно будет импортировать туда, где вам нужно их экспортировать:
exporter.js
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
export default class Exporter {
constructor(charts) {
this.charts = charts;
this.doc = new jsPDF("landscape", "px", "letter");
}
export_pdf() {
return new Promise((resolve, reject) => {
try {
this.charts.forEach(async (chart, index, charts) => {
this.doc = await this.create_page(chart, this.doc);
if (index === charts.length - 1) resolve(this.doc); // this.doc.save("charts.pdf"); // <-- at the end of the loop; display PDF
this.doc.addPage("letter");
});
} catch (error) {
reject(error);
}
});
}
async create_page(chart, doc) {
const canvas = await html2canvas(chart, {
scrollY: -window.scrollY,
scale: 5 // <-- this is to increase the quality. don't raise this past 5 as it doesn't get much better and just takes longer to process
});
const image = canvas.toDataURL("image/jpeg", 1.0),
pageWidth = doc.internal.pageSize.getWidth(),
pageHeight = doc.internal.pageSize.getHeight(),
ratio = (pageWidth - 50) / canvas.width,
canvasWidth = canvas.width * ratio,
canvasHeight = canvas.height * ratio,
marginX = (pageWidth - canvasWidth) / 2,
marginY = (pageHeight - canvasHeight) / 2;
doc.addImage(image, "JPEG", marginX, marginY, canvasWidth, canvasHeight);
return doc;
}
}
Вы можете импортировать это в App.vue или где угодно, где у вас есть диаграммы, и создать новый экземпляр Exporter
с массивом элементов диаграммы для экспорта, затем вызвать для него метод export_pdf()
и делать все, что вы хотите, с PDF:
let area = document.getElementById("area");
let line = document.getElementById("line");
const exp = new Exporter([line, area]);
exp.export_pdf().then((pdf) => pdf.save("charts.pdf"));
Таким образом вы можете визуализировать столько диаграмм, сколько захотите.
Пример App.vue:
import Exporter from "@/assets/exporter.js";
...
export default {
methods: {
exportToPDF() {
let bar = document.getElementById("bar");
let radar = document.getElementById("radar");
let pie = document.getElementById("pie");
let area = document.getElementById("area");
let line = document.getElementById("line");
const exp = new Exporter([line, bar, radar, pie, area]);
exp.export_pdf().then((pdf) => pdf.save("charts.pdf"));
}
...
}
Теперь обратите внимание, что, как упоминалось выше, элемент диаграммы, который вы передаете в Exporter
, должен содержаться в элементе размером 594 на 459 пикселей, так как это размер бумаги и является оптимальным размером для диаграммы. Но тогда вы не сможете изменить размер диаграммы на своем веб-сайте или чего-то подобного, поэтому вы можете создать две идентичные диаграммы, одну, с которой вы можете делать все, что захотите, а другую, содержащуюся в правом div. размер, но размещен за пределами экрана, поэтому пользователь не видит его.
Что-то вроде этого:
<template>
<BarChart />
<div class="hidden">
<BarChart id="bar" />
</div>
</template>
<script>
export default { STUFF GOES HERE}
</script>
<style>
.hidden {
width: 594px !important;
height: 459px !important;
position: absolute !important;
left: -600px !important;
}
</style>
![example1](https://i.stack.imgur.com/vjHqH.png)
Другой график скрыт слева, где вы его не видите.
Обе диаграммы будут заполнены одними и теми же данными, но при экспорте в PDF внеэкранная диаграмма будет преобразована в PDF, а не в тот, который увидит пользователь. Это слишком сложно, но это единственный способ, который я смог найти. Если вы попытаетесь скрыть диаграммы с помощью v-if или v-show, при отображении скрытой диаграммы по какой-то причине будет удалена другая. Возможно, вы могли бы создать один компонент, который бы создавал две диаграммы вместе, чтобы упростить задачу, но это потребует дополнительной работы.
Также обратите внимание, что вам может потребоваться увеличить расстояние, на которое скрытая диаграмма перемещается влево, если она все еще отображается на экране.
Обязательно установите зависимости:
npm i html2canavs jspdf
Я создал модуль node.js для exporter.js, который вы можете установить и использовать в качестве альтернативы. См. здесь, чтобы получить инструкции по установке и дополнительную информацию.
Как обновить диаграммы с помощью vue-chartjs
На самом деле это довольно просто. vue-chartjs имеет два миксина, которые вы можете использовать для этого: reactiveProp
и reactiveData
. Если вы хотите передать динамические данные в компонент диаграммы, созданный вами в качестве опоры, вы можете использовать reactiveProp
:
Linechart.js
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['options'],
mounted () {
// this.chartData is created in the mixin.
// If you want to pass options please create a local options object
this.renderChart(this.chartData, this.options)
}
}
// from https://vue-chartjs.org/guide/#updating-charts
Везде, где вы хотите отобразить диаграмму, просто импортируйте Linechart.js и зарегистрируйте его как компонент:
import LineChart from './LineChart.js'
export default {
components: {
LineChart
},
...
}
... затем поместите диаграмму в свой шаблон и передайте данные через опору chart-data
:
<line-chart :chart-data="datacollection"></line-chart>
Он будет автоматически обновляться при datacollection
изменениях.
Примеры кода и много более подробной информации об этом доступны в документации. < / а>
Просмотрите демонстрацию обновления диаграмм и их преобразования в файлы PDF здесь.
person
marsnebulasoup
schedule
23.12.2020