Как правильно генерировать холст из сложных SVG - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь экспортировать сложный блок SVG (сгенерированный с помощью c3) с моего сайта в виде изображения (будь то png, svg, pdf), на данный момент я открыт для всего, что решает его, хотя векторный формат будетбыть идеальным).Я пробовал html2canvas, canvg, jsPDF и всех классных ребят из этой банды.Проблема в том, что один из моих сюжетов облажался.Линия становится областью, области переворачиваются, цвета разрушаются, ... вы называете это.

Я довольно далеко от того, чтобы быть экспертом JS.Я только что пришел сюда, и я нахожу свой путь, некоторые, пожалуйста, терпите меня.

Я не знаю, является ли это проблемой CSS или чем-то другим.Да, у нас есть CSS за html.

Мое временное решение - использовать jQuery.print.js для вызова распечатки моего div.Это далеко от идеала по многим причинам:

  • Нет bbox.Он генерирует PDF с размером страницы, определяемым пользователем, а не размером изображения;

  • Я использую загрузочные карты с автоматическим изменением размера.Всякий раз, когда нажимается «печать изображения», печать использует текущий размер.Я пытался скрыть карты, чтобы изменить их масштаб, но изменение размера будет происходить только ПОСЛЕ печати, по неизвестным мне причинам.Если эта проблема решена, это временное решение будет лучше, хотя все еще временно.

Итак, один вопрос:

  • как получить SVGкак показано?
  • В качестве альтернативы, как изменить размер карты ДО того, как будет напечатана печать?
  • Или, как создать растр (png / jpeg) без ошибок форматирования, полученных из canvg / jsPDF?

Функция, выполняющая вызов для печати на данный момент:

function getscreenshot(div) {
  // Hide row pair:
  $('#map-card').addClass('hidden');

  // Temporarily change class attr to spawn all row:
  var divClass = $(div).attr('class');
  $(div).attr('class', 'col');

  // ****PROBLEM****
  // Div size is not upated before calling print()
  // causing the print to have the size as displayed on user screen
  // How to refresh it before print?
  // ********

  // jQuery.print solves it in a non-ideal way, since user has to set save as file and so on
  $(div).print();

  // This solution with jsPDF produces **ugly as hell** image:
  // var pdf = new jsPDF('landscape');
  // pdf.addHTML(document.getElementById(div), function() {
  //     pdf.save(name + 'pdf');
  // });

  // Recover original size after print:
  // Restore row pair and div original state:
  $('#map-card').removeClass('hidden');
  $(div).attr('class', divClass);
}

Вот ряд карточек, как показано на веб-странице: Cards row

Сюжет справа - тот, на котором я сфокусировал свои попытки, и тот, который завершается неформатированным.Проверьте, что получится с помощью html2canvas, jsPDF и тому подобного, и получите ту же ошибку, что и в скрипте с SVG-вставкой , с использованием canvg.js

PS: Да, я много искал,Вот так я и попробовал html2canvas, canvg, jsPDF, jqprint, ...

Ура!

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

В конечном результате используется ответ @tgiachetti с несколькими изменениями.Проблема с оригинальным svg-crowbar-2 заключается в том, что это буклет, который открывает кнопки загрузки для всех SVG-файлов на веб-сайте, что не является желаемым конечным результатом и работает только в Chrome.

Представленное здесь решение работает как на Chrome, так и на Firefox.

Поэтому я в итоге применил несколько модификаций к svg-crowbar-2.js из https://github.com/NYTimes/svg-crowbar:

  • Используется как функция, а не как буклет;
  • Цикл только до 4-го источника SVG, поскольку остальные не нужны;
  • Получает порядковый номер SVG для загрузки одного сюжета;
  • Обновить страницу после загрузки.

Изменения можно найти в виде файла js singledownload-svg-crowbar-2.js по адресу: https://github.com/FluVigilanciaBR/fludashboard/blob/development/fludashboard/static/libs/svg-crowbar-2/singledownload-svg-crowbar-2.js

Для использования:

Во-первых, в качестве источника вставлен твик svg-crowbar-2:

<script src="./static/libs/svg-crowbar-2/singledownload-svg-crowbar-2.js"></script>

Затем, на каждую графическую карту, я вставил кнопку с вызовом функции getcreenshot, передавая порядковый номер нужного номера.SVG:

<div class="container">
 <button type="button" class="btn btn-link btn-sm no-print" onclick="getscreenshot(3);">Salvar imagem</button>
</div>

Эта функция, помещенная в указательСам .html, в основном, определяет имя файла SVG на основе порядкового номера графика и вызывает единственную функцию загрузчика SVG singleSVGcrowbar, определенную в singledownload-svg-crowbar-2.js:

<script language="JavaScript" type="text/javascript">
  function getscreenshot(myplot) {
    var plotName = ['mapa', 'mapa-legenda', 'serie-temporal', 'distribuicao-etaria'];
    var myplotObj = {SVGid: myplot, SVGname: plotName[myplot]};

    singleSVGcrowbar(myplotObj);
  }
</script>

Если вы хотите вставить этона вашем собственном веб-сайте, прежде всего, определите порядковый номер нужного блока SVG, запустив оригинальный svg-crowbar-2.Это номер, вставленный при вызове getscreenshot (myplot).

0 голосов
/ 08 июня 2018

Вы можете решить проблему с Майком Бостоком (или, может быть, это Нью-Йорк Таймс) SVG Crowbar .Используйте SVG Crowbar 2. Вы перетаскиваете его на панель закладок, затем нажимаете на него, когда находитесь на странице, где хотите сохранить SVG.Если есть более одного SVG, вам придется выбрать, какой из них.

Я протестировал SVG Crowbar 1 с c3.js, и он не сохранил стили правильно, поэтому убедитесь, что вы используете SVG Crowbar 2. Я протестировал SVG Crowbar 2 с c3.js, и он работал для меня.

Получив SVG, вы можете использовать Inkscape для создания PNG.Нажмите: файл> экспортировать PNG изображение.Затем выберите желаемые размеры для вывода.Затем нажмите Экспорт. На этом сайте есть пошаговое описание того, как это сделать

В Интернете также есть сайты, которые конвертируют SVG в PNG, но есть несколько, поэтому я не буду публиковать ссылки.Поиск в Google должен найти то, что вам нужно.

Если вы хотите сделать все это программным способом, это другая история.

Обновление : SVG Crowbar (1и 2) работать только в Chrome.

...