我有大型svg图纸,一开始的尺寸未知。我想将它们打印在多页上;但是最初不知道页数。因此,在确定绘图大小并相应添加svg元素后,我必须决定Javascript中的页面数。
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);
但是(STILL)不起作用。动态获得相似输出的正确方法是什么?
经过一些研究,我了解xlink:href不是svg的属性,因为它是由“ use”函数(?)使用的。因此,应该定义另一个use元素以指向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);
现在,使用这些定义,我将第四页显示在平铺中,但是它是空的。将输出数据链接到平铺页面时,肯定还有更多错误或遗漏。
编辑:这是完整的测试案例。带有嵌入式svg和javascript的HTML文档。它提供4页静态平铺。我取出了第四个静态页面定义,并尝试在Javascript中实现动态图块definitin。
因此,现在,它可以正确打印三页。有第四页,但空白,缺少内容。
<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>
答案 0 :(得分:0)
xlink:href
在xlink命名空间中,而不是svg命名空间中。实际上,不建议使用名称空间,并且实际上所有浏览器都了解href
属性,而没有名称空间。只需写
useElem.setAttribute('href', '#graphic');