Как динамически распределять вывод svg на печать

У меня есть большие svg-рисунки с неизвестными размерами в начале. Я хочу напечатать их на нескольких страницах; но количество страниц изначально не известно. Поэтому я должен выбрать количество страниц в Javascript после того, как я определю размер рисунка и добавлю элементы svg соответственно.

Есть хороший пример https://codepen.io/anon/pen/roYXVJ, который представляет собой «статический» тайлинг, т.е. размер и количество страниц фиксируются заранее. Упрощенная версия кода (без стрелок и букв индекса) выглядит следующим образом:

<figure class = "svg-container">
  <!-- The actual graphic is a 3:2 image
       which will be wrapped in a scrolling
       container on screen. -->
  <svg class = "screen" width = "18in" height = "12in"
       viewBox = "0 0 1800 1200">
    <g id = "graphic"><!-- 
      Actual graphic goes here.  I'm using a script to generate it. 
--></g>
  </svg>
  <!-- For printing in landscape mode,
       the graphic is divided into four
       overlapping quadrants which will
       each fit on a letter/A4 page
       without scaling.  The 1000*700 viewBox
       is equivalent to 10in*7in of the
       onscreen dimensions. -->
  <svg class = "print landscape" viewBox = "0 0 1000 700">
    <use xlink:href = "#graphic" />
  </svg>
  <svg class = "print landscape" viewBox = "800 0 1000 700">
    <use xlink:href = "#graphic" />
  </svg>
  <svg class = "print landscape" viewBox = "0 500 1000 700">
    <use xlink:href = "#graphic" />
  </svg>
  <svg class = "print landscape" viewBox = "800 500 1000 700">
    <use xlink:href = "#graphic" />
  </svg>

  <!-- For printing in portrait mode,
       the graphic is scaled down slightly
       to fit on two pages.  Again,
       the content of each page will 
       overlap slightly. -->
  <svg class = "print portrait" viewBox = "0 0 1000 1200">
    <use xlink:href = "#graphic" />
  </svg>
  <svg class = "print portrait" viewBox = "800 0 1000 1200">
    <use xlink:href = "#graphic" />
  </svg>
</figure>

<script>

var doc = document;
var g = doc.getElementById("graphic");
var svgNS = g.namespaceURI;
var r, t;

for (var i=0; i<18; i++){
  for (var j=0; j<12; j++) {
    r = doc.createElementNS(svgNS, "rect");
    r.setAttribute("width", "80");
    r.setAttribute("height", "80");
    r.setAttribute("x", (i*100 + 10));
    r.setAttribute("y", (j*100 + 10));
    r.style.setProperty("fill-opacity", ((i*j + 1)%20)/20, null);
    g.insertBefore(r, null);
    t = doc.createElementNS(svgNS, "text");
    t.setAttribute("x", (i*100 + 50));
    t.setAttribute("y", (j*100 + 50));
    t.setAttribute("class", "diagram")
    t.textContent = [i,j];
    g.insertBefore(t, null);
  }  
}

</script>

Итак, я пытаюсь заменить

<svg class = "print landscape"...  />

статические определения с такими динамическими определениями внутри скрипта: Обновлено: я исправляю некоторые определения и добавляю недостающие. Обновленные динамические определения:

var printLandscape = document.createElementNS(svgNS, "svg");
printLandscape.setAttribute("viewBox", " 800 500 1000 700");
printLandscape.setAttribute("orientation", "landscape");
printLandscape.setAttribute("xlink:href", "#graphic");
printLandscape.setAttribute("class", "print landscape")
g.insertBefore(printLandscape, null);

Но это (ЕЩЕ) не работает. Каким будет правильный способ динамического получения аналогичных результатов?

После некоторого исследования я понял, что xlink: href не является атрибутом svg, поскольку он используется функцией «использовать» (?). Итак, должен быть определен другой элемент использования, указывающий на xlink: href. Кроме того, printLanscape должен быть частью контейнера "figure". Окончательные определения следующие:

var doc = document;
var g = doc.getElementById("graphic");
var f = doc.getElementById("mafigure");
var svgNS = g.namespaceURI;

var printLandscape = document.createElementNS(svgNS, "svg");
var useElem = document.createElementNS(svgNS, 'use');

printLandscape.setAttributeNS(svgNS,"class", "print landscape")
printLandscape.setAttributeNS(svgNS, "viewBox", " 800 500 1000 700");
useElem.setAttributeNS(svgNS, 'xlink:href', '#graphic');
printLandscape.appendChild(useElem);
f.insertBefore(printLandscape, null);

Теперь, с этими определениями, у меня появилась четвертая страница в мозаике, но она пуста. При связывании выходных данных со страницей плитки должна быть еще какая-то ошибка или что-то отсутствует.

Обновлено: Вот полный тестовый пример. HTML-документ со встроенным svg и javascript. Он обеспечивает 4-страничную статическую мозаику. Я взял четвертое определение статической страницы и попытался реализовать определение динамической плитки в Javascript.

Итак, теперь он правильно печатает три страницы. Есть четвертая страница, но пустая, без содержания.

 <html>
 <head>

 <style>
 symbol, use, svg {
   overflow: visible;
 }
 rect {
   stroke: navy;
 }

 /* Screen styles */
 figure.svg-container {
   display: block;
   overflow: scroll;
   max-width: 90vw;
   max-height: 90vh;
   border:gray solid thin;
 }

 svg.print {
   display: none;
 }
 @media print{
   figure.svg-container {
     display: inline;
     overflow: auto;
     border: none;
   }
   svg.screen {
     display: none;
   }
   svg.print {
     overflow: hidden;
     border: thin lightgray solid;
     padding: 0.5em;
     -moz-box-sizing: border-box;
     box-sizing: border-box;
     page-break-inside: avoid;
     break-inside: avoid;
   }
 }
 @media print and (orientation: landscape){
   svg.print.landscape {
     display: block;
     height: 7in;
     width: 10in;
   }
 }
 @media print and (orientation: portrait){
   svg.print.portrait {
     display: block;
     height: 9in;
     width: 7.5in;
   }
 }

 </style>

 <figure class = "svg-container" id = "mafigure">
   <!-- The actual graphic is a 3:2 image
        which will be wrapped in a scrolling
        container on screen. -->
   <svg class = "screen" width = "18in" height = "12in"
        viewBox = "0 0 1800 1200">
     <g id = "graphic"><!-- 
       Actual graphic goes here.  I'm using a script to generate it. 
 --></g>
   </svg>
   <!-- For printing in landscape mode,
        the graphic is divided into four
        overlapping quadrants which will
        each fit on a letter/A4 page
        without scaling.  The 1000*700 viewBox
        is equivalent to 10in*7in of the
        onscreen dimensions. -->
   <svg class = "print landscape" viewBox = "0 0 1000 700">
     <use xlink:href = "#graphic" />
   </svg>
   <svg class = "print landscape" viewBox = "800 0 1000 700">
     <use xlink:href = "#graphic" />
   </svg>
   <svg class = "print landscape" viewBox = "0 500 1000 700">
     <use xlink:href = "#graphic" />
   </svg>

   <!-- For printing in portrait mode,
        the graphic is scaled down slightly
        to fit on two pages.  Again,
        the content of each page will 
        overlap slightly. -->
   <svg class = "print portrait" viewBox = "0 0 1000 1200">
     <use xlink:href = "#graphic" />
   </svg>
   <svg class = "print portrait" viewBox = "800 0 1000 1200">
     <use xlink:href = "#graphic" />
   </svg>
 </figure>

 <script>

 var r, t;

 var doc = document;
 var g = doc.getElementById("graphic");
 var f = doc.getElementsByClassName("svg-container");
 var svgNS = g.namespaceURI;

 var printLandscape = document.createElementNS(svgNS, "svg");
 var useElem = document.createElementNS(svgNS, 'use');

 printLandscape.setAttributeNS(svgNS,"class", "print landscape")
 printLandscape.setAttributeNS(svgNS, "viewBox", " 800 500 1000 700");
 useElem.setAttributeNS(svgNS, 'xlink:href', '#graphic');
 printLandscape.appendChild(useElem);
 f[0].appendChild(printLandscape);

 for (var i=0; i<18; i++){
   for (var j=0; j<12; j++) {
     r = doc.createElementNS(svgNS, "rect");
     r.setAttribute("width", "80");
     r.setAttribute("height", "80");
     r.setAttribute("x", (i*100 + 10));
     r.setAttribute("y", (j*100 + 10));
     r.style.setProperty("fill-opacity", ((i*j + 1)%20)/20, null);
     g.insertBefore(r, null);
   }  
 }

 </script>

 <body>

 </body>

 </head>
 </html>
stackoverflow.com/help/mcve
ksav 02.01.2019 08:33
Поведение ключевого слова "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) для оценки ваших знаний,...
1
1
371
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

xlink:href находится в пространстве имен xlink, а не в пространстве имен svg. На самом деле использование пространства имен не рекомендуется, и практически все браузеры понимают атрибут href без пространства имен. Просто напишите

useElem.setAttribute('href', '#graphic');

Я не понимаю, почему обзорная комиссия продолжает приставать к владельцу вопроса. Как видите, люди могут читать, понимать и отвечать на вопрос спокойно, спокойно и, что более важно. с пользой.

user2800464 03.01.2019 16:53

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