How to tile svg print output dynamically
I have large svg drawings, with unknown sizes at the beginning. I want to print them on multiple pages; but the number of pages are not known initially. So I have to decide on the number of pages within Javascript after I idetify the drawing size and add svg elements accordingly.
There is a nice example at https://codepen.io/anon/pen/roYXVJ which is a "static" tiling, i.e., the size and number of pages are fixed beforehand. A simplified version of the code (without the arrows and index letters) looks like the following:
<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>
So, I am trying to replace
<svg class="print landscape"... />
static definitions with such dynamic definitions within the script:
EDIT: I correct some definitions and added some missing ones. Updated dynamic definitions are:
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);
But that (STILL) does not work. What would be the correct way to get similar output dynamically?
After some research I understand xlink:href is not an attribute of the svg since it is used by the "use" function(?). So, another use element should be defined to point to xlink:href. Also, printLanscape should be part of the container, "figure". Final definitions are as follows:
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);
Now, with these definitions I have the fourth page appeared in the tiling, but it is empty. There must be some more error or missing things in linking output data to the tile page.
EDIT: Here is full test case. HTML document with embedded svg and javascript. It provides 4- page static tiling. I took out the fourth static page definition and tried to implement a dynamic tile definitin within the Javascript.
So now, it prints three pages correctly. There is fourth page, but blank, with the content missing.
<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>
javascript svg dynamic tile
add a comment |
I have large svg drawings, with unknown sizes at the beginning. I want to print them on multiple pages; but the number of pages are not known initially. So I have to decide on the number of pages within Javascript after I idetify the drawing size and add svg elements accordingly.
There is a nice example at https://codepen.io/anon/pen/roYXVJ which is a "static" tiling, i.e., the size and number of pages are fixed beforehand. A simplified version of the code (without the arrows and index letters) looks like the following:
<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>
So, I am trying to replace
<svg class="print landscape"... />
static definitions with such dynamic definitions within the script:
EDIT: I correct some definitions and added some missing ones. Updated dynamic definitions are:
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);
But that (STILL) does not work. What would be the correct way to get similar output dynamically?
After some research I understand xlink:href is not an attribute of the svg since it is used by the "use" function(?). So, another use element should be defined to point to xlink:href. Also, printLanscape should be part of the container, "figure". Final definitions are as follows:
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);
Now, with these definitions I have the fourth page appeared in the tiling, but it is empty. There must be some more error or missing things in linking output data to the tile page.
EDIT: Here is full test case. HTML document with embedded svg and javascript. It provides 4- page static tiling. I took out the fourth static page definition and tried to implement a dynamic tile definitin within the Javascript.
So now, it prints three pages correctly. There is fourth page, but blank, with the content missing.
<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>
javascript svg dynamic tile
stackoverflow.com/help/mcve
– ksav
Jan 2 at 7:33
add a comment |
I have large svg drawings, with unknown sizes at the beginning. I want to print them on multiple pages; but the number of pages are not known initially. So I have to decide on the number of pages within Javascript after I idetify the drawing size and add svg elements accordingly.
There is a nice example at https://codepen.io/anon/pen/roYXVJ which is a "static" tiling, i.e., the size and number of pages are fixed beforehand. A simplified version of the code (without the arrows and index letters) looks like the following:
<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>
So, I am trying to replace
<svg class="print landscape"... />
static definitions with such dynamic definitions within the script:
EDIT: I correct some definitions and added some missing ones. Updated dynamic definitions are:
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);
But that (STILL) does not work. What would be the correct way to get similar output dynamically?
After some research I understand xlink:href is not an attribute of the svg since it is used by the "use" function(?). So, another use element should be defined to point to xlink:href. Also, printLanscape should be part of the container, "figure". Final definitions are as follows:
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);
Now, with these definitions I have the fourth page appeared in the tiling, but it is empty. There must be some more error or missing things in linking output data to the tile page.
EDIT: Here is full test case. HTML document with embedded svg and javascript. It provides 4- page static tiling. I took out the fourth static page definition and tried to implement a dynamic tile definitin within the Javascript.
So now, it prints three pages correctly. There is fourth page, but blank, with the content missing.
<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>
javascript svg dynamic tile
I have large svg drawings, with unknown sizes at the beginning. I want to print them on multiple pages; but the number of pages are not known initially. So I have to decide on the number of pages within Javascript after I idetify the drawing size and add svg elements accordingly.
There is a nice example at https://codepen.io/anon/pen/roYXVJ which is a "static" tiling, i.e., the size and number of pages are fixed beforehand. A simplified version of the code (without the arrows and index letters) looks like the following:
<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>
So, I am trying to replace
<svg class="print landscape"... />
static definitions with such dynamic definitions within the script:
EDIT: I correct some definitions and added some missing ones. Updated dynamic definitions are:
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);
But that (STILL) does not work. What would be the correct way to get similar output dynamically?
After some research I understand xlink:href is not an attribute of the svg since it is used by the "use" function(?). So, another use element should be defined to point to xlink:href. Also, printLanscape should be part of the container, "figure". Final definitions are as follows:
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);
Now, with these definitions I have the fourth page appeared in the tiling, but it is empty. There must be some more error or missing things in linking output data to the tile page.
EDIT: Here is full test case. HTML document with embedded svg and javascript. It provides 4- page static tiling. I took out the fourth static page definition and tried to implement a dynamic tile definitin within the Javascript.
So now, it prints three pages correctly. There is fourth page, but blank, with the content missing.
<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>
javascript svg dynamic tile
javascript svg dynamic tile
edited Jan 2 at 14:07
user2800464
asked Jan 1 at 22:19
user2800464user2800464
3718
3718
stackoverflow.com/help/mcve
– ksav
Jan 2 at 7:33
add a comment |
stackoverflow.com/help/mcve
– ksav
Jan 2 at 7:33
stackoverflow.com/help/mcve
– ksav
Jan 2 at 7:33
stackoverflow.com/help/mcve
– ksav
Jan 2 at 7:33
add a comment |
1 Answer
1
active
oldest
votes
xlink:href
is in the xlink namespace, not the svg namespace. Actually, the use of the namespace is deprecated, and practically all browsers understand the href
attribute without a namespace. Simply write
useElem.setAttribute('href', '#graphic');
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999383%2fhow-to-tile-svg-print-output-dynamically%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
xlink:href
is in the xlink namespace, not the svg namespace. Actually, the use of the namespace is deprecated, and practically all browsers understand the href
attribute without a namespace. Simply write
useElem.setAttribute('href', '#graphic');
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
add a comment |
xlink:href
is in the xlink namespace, not the svg namespace. Actually, the use of the namespace is deprecated, and practically all browsers understand the href
attribute without a namespace. Simply write
useElem.setAttribute('href', '#graphic');
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
add a comment |
xlink:href
is in the xlink namespace, not the svg namespace. Actually, the use of the namespace is deprecated, and practically all browsers understand the href
attribute without a namespace. Simply write
useElem.setAttribute('href', '#graphic');
xlink:href
is in the xlink namespace, not the svg namespace. Actually, the use of the namespace is deprecated, and practically all browsers understand the href
attribute without a namespace. Simply write
useElem.setAttribute('href', '#graphic');
answered Jan 2 at 13:56
ccprogccprog
9,81521128
9,81521128
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
add a comment |
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
I do not understand why the review board keeps bugging the question owner. As you can see, people can read, understand and answer the question quietly, peacefuly , and more importantly. usefully.
– user2800464
Jan 3 at 15:53
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999383%2fhow-to-tile-svg-print-output-dynamically%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
stackoverflow.com/help/mcve
– ksav
Jan 2 at 7:33