UNPKG

23.2 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4<meta charset="utf-8"/>
5<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
6
7<link rel="stylesheet" href="../assets/css/style.css"/>
8<!-- Copyright 1998-2021 by Northwoods Software Corporation. --> <title> GoJS Printing -- Northwoods Software </title>
9 <link rel="stylesheet" href="../assets/css/prism.css" />
10 </head>
11 <script>
12
13 window.diagrams = [];
14 window.goCode = function(pre, w, h, parentid, animation) {
15 window.diagrams.push([pre, w, h, parentid, animation]);
16 }
17 </script>
18 <body>
19 <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
20 <div class="w-full container max-w-screen-lg mx-auto flex flex-wrap sm:flex-nowrap items-center justify-between mt-0 py-2">
21 <div class="md:pl-4">
22 <a class="text-white hover:text-white no-underline hover:no-underline
23 font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
24 <h1 class="mb-0 p-1 ">GoJS</h1>
25 </a>
26 </div>
27 <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
28 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
29 <path id="topnavOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
30 <path id="topnavClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
31 </svg>
32 </button>
33 <div id="topnavList" class="hidden sm:block items-center w-auto mt-0 text-white p-0 z-20">
34 <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
35 <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
36 <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
37 <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
38 <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
39 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
40 <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
41 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
42 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
43 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
44 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
45 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
46 </ul>
47 </div>
48 </div>
49 <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
50 </nav>
51
52 <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
53
54 <div id="navSide" class="flex flex-col w-full md:w-40 lg:w-48 text-gray-700 bg-white flex-shrink-0">
55 <div class="flex-shrink-0 px-8 py-4">
56 <button id="navButton" class="rounded-lg md:hidden focus:outline-none focus:ring" aria-label="Navigation">
57 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
58 <path id="navOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
59 <path id="navClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
60 </svg>
61 </button>
62 </div>
63 <nav id="navList" class="min-h-screen hidden md:block sidebar-nav flex-grow px-1 lg:px-4 pb-4 md:pb-0 md:overflow-y-auto break-words">
64 <a href="index.html">Basics</a>
65 <a href="buildingObjects.html">Building Parts</a>
66 <a href="usingModels.html">Using Models</a>
67 <a href="dataBinding.html">Data Binding</a>
68 <a href="react.html">GoJS with React</a>
69 <a href="angular.html">GoJS with Angular</a>
70 <a href="textBlocks.html">TextBlocks</a>
71 <a href="shapes.html">Shapes</a>
72 <a href="pictures.html">Pictures</a>
73 <a href="panels.html">Panels</a>
74 <a href="tablePanels.html">Table Panels</a>
75 <a href="brush.html">Brushes</a>
76 <a href="sizing.html">Sizing Objects</a>
77 <a href="itemArrays.html">Item Arrays</a>
78 <a href="changedEvents.html">Changed Events</a>
79 <a href="transactions.html">Transactions</a>
80 <a href="viewport.html">Coordinates</a>
81 <a href="initialView.html">Initial View</a>
82 <a href="collections.html">Collections</a>
83 <a href="links.html">Links</a>
84 <a href="linkLabels.html">Link Labels</a>
85 <a href="connectionPoints.html">Link Points</a>
86 <a href="ports.html">Ports</a>
87 <a href="nodes.html">Nodes</a>
88 <a href="debugging.html">Debugging</a>
89 <a href="layouts.html">Layouts</a>
90 <a href="trees.html">Trees</a>
91 <a href="subtrees.html">SubTrees</a>
92 <a href="groups.html">Groups</a>
93 <a href="subgraphs.html">SubGraphs</a>
94 <a href="sizedGroups.html">Sized Groups</a>
95 <a href="selection.html">Selection</a>
96 <a href="highlighting.html">Highlighting</a>
97 <a href="animation.html">Animation</a>
98 <a href="toolTips.html">ToolTips</a>
99 <a href="contextmenus.html">Context Menus</a>
100 <a href="events.html">Diagram Events</a>
101 <a href="tools.html">Tools</a>
102 <a href="commands.html">Commands</a>
103 <a href="permissions.html">Permissions</a>
104 <a href="validation.html">Validation</a>
105 <a href="HTMLInteraction.html">HTML Interaction</a>
106 <a href="layers.html">Layers &amp; Z-ordering</a>
107 <a href="palette.html">Palette</a>
108 <a href="overview.html">Overview</a>
109 <a href="resizing.html">Resizing Diagrams</a>
110 <a href="replacingDeleting.html">Replacing and Deleting</a>
111 <a href="buttons.html">Buttons</a>
112 <a href="templateMaps.html">Template Maps</a>
113 <a href="legends.html">Legends and Titles</a>
114 <a href="extensions.html">Extensions</a>
115 <a href="geometry.html">Geometry Strings</a>
116 <a href="grids.html">Grid Patterns</a>
117 <a href="graduatedPanels.html">Graduated Panels</a>
118 <a href="makingImages.html">Diagram Images</a>
119 <a href="makingSVG.html">Diagram SVG</a>
120 <a href="printing.html">Printing</a>
121 <a href="serverSideImages.html">Server-side Images</a>
122 <a href="nodeScript.html">GoJS in Node.js</a>
123 <a href="testing.html">Testing</a>
124 <a href="storage.html">Storage</a>
125 <a href="performance.html">Performance</a>
126 <a href="source.html">Building from Source</a>
127 <a href="platforms.html">Platforms</a>
128 <a href="deployment.html">Deployment</a>
129 </nav>
130 </div>
131 <div class="pt-4 px-2 md:px-0 lg:px-4 pb-16 w-full overflow-hidden">
132
133
134 <style type="text/css">
135 @media screen {
136 img {
137 border: 1px solid rgba(255,0,0,.4);
138 }
139 }
140
141 /* @media print specifies CSS rules that only apply when printing */
142 @media print {
143 /* CSS reset to clear styles for printing */
144 html, body, div {
145 margin: 0;
146 padding: 0;
147 border: 0;
148 font-size: 100%;
149 font: inherit;
150 vertical-align: baseline;
151 }
152
153 /* Hide everything on the page */
154 body * {
155 display: none;
156 }
157
158 #container, #content, #myImages, #myImages * {
159 /* Only display the images we want printed */
160 /* all of the image's parent divs
161 leading up to the body must be un-hidden (displayed) too
162 */
163 display: block;
164 /* CSS reset to clear the specific visible divs for printing */
165 margin: 0;
166 padding: 0;
167 border: 0;
168 font-size: 100%;
169 font: inherit;
170 vertical-align: baseline;
171 }
172
173 /* We have line breaks in the DIV
174 to separate the images in the browser,
175 but do not want those line breaks when printing
176 */
177 #myImages br {
178 display: none;
179 }
180
181 #manyImgCode {
182 display: none;
183 }
184
185 #mycss {
186 display: none;
187 }
188
189 img {
190 /* Only some browsers respect this rule: */
191 page-break-inside: avoid;
192 /* Almost all browsers respect this rule: */
193 page-break-after:always;
194 }
195 }
196
197 /* The @page rules specify additional printing directives that browsers may respect
198 Here we suggest printing in landscape (instead of portrait) with a small margin.
199 Browsers, however, are free to ignore or override these suggestions.
200 See also:
201 https://developer.mozilla.org/en-US/docs/CSS/@page
202 https://dev.w3.org/csswg/css3-page/#at-page-rule
203 */
204 @page {
205 /* Some browsers respect rules such as size: landscape */
206 margin: 1cm;
207 }
208 </style>
209
210
211
212
213<h1>Printing</h1>
214<p>
215Printing a Diagram is typically accomplished by making several images of the Diagram and either saving them, inserting them into a PDF or other document, or printing them directly from the browser. On this page we will create several images out of a large Diagram and prepare some CSS so that printing this page prints only those images.
216</p>
217<p>
218This page uses <a>Diagram.makeImage</a>, which has its own introduction page: <a href="makingImages.html">Making Images with GoJS</a>.
219</p>
220
221<p class="box bg-info">
222Depending on your situation, you may want to use SVG to print instead, and there is also a page on <a href="makingSVG.html">Making SVG with GoJS</a>, which is nearly identical to making images. In this page's examples you could substitute <a>Diagram.makeSvg</a> for the same result.
223</p>
224
225<p>
226 Below is the Diagram we are going to prepare for print.
227</p>
228<!-- Don't bother showing this source -->
229<pre class="lang-js" id="diag" style="display: none;"><code>
230 window.myDiagram = diagram;
231 myDiagram.autoScale = go.Diagram.Uniform;
232
233 // define the Node template
234 myDiagram.nodeTemplate =
235 $(go.Node, "Spot",
236 { locationSpot: go.Spot.Center },
237 $(go.Shape, "Rectangle",
238 { fill: "lightgray", // the initial value, but data-binding may provide different value
239 stroke: "black",
240 desiredSize: new go.Size(30, 30) },
241 new go.Binding("fill", "fill")),
242 $(go.TextBlock,
243 new go.Binding("text", "text"))
244 );
245
246 // define the Link template to be minimal
247 myDiagram.linkTemplate =
248 $(go.Link,
249 { selectable: false },
250 $(go.Shape));
251
252 myDiagram.layout = new go.LayeredDigraphLayout();
253
254 var minNodes = 125, maxNodes = 125;
255 myDiagram.startTransaction("generateDigraph");
256 // replace the diagram's model's nodeDataArray
257 var nodeArray = [];
258 // get the values from the fields and create a random number of nodes within the range
259 var min = parseInt(minNodes, 10);
260 var max = parseInt(maxNodes, 10);
261 if (isNaN(min)) min = 0;
262 if (isNaN(max) || max &lt; min) max = min;
263 var numNodes = Math.floor(Math.random() * (max - min + 1)) + min;
264 var i;
265 for (i = 0; i &lt; numNodes; i++) {
266 nodeArray.push({
267 key: i,
268 text: i.toString(),
269 fill: go.Brush.randomColor()
270 });
271 }
272
273 // randomize the node data
274 for (i = 0; i &lt; nodeArray.length; i++) {
275 var swap = Math.floor(Math.random() * nodeArray.length);
276 var temp = nodeArray[swap];
277 nodeArray[swap] = nodeArray[i];
278 nodeArray[i] = temp;
279 }
280
281 // set the nodeDataArray to this array of objects
282 myDiagram.model.nodeDataArray = nodeArray;
283 // replace the diagram's model's linkDataArray
284 var linkArray = [];
285 var nit = myDiagram.nodes;
286 var nodes = new go.List();
287 nodes.addAll(nit);
288 for (var i = 0; i &lt; nodes.count - 1; i++) {
289 var from = nodes.elt(i);
290 var numto = Math.floor(1 + (Math.random() * 3) / 2);
291 for (var j = 0; j &lt; numto; j++) {
292 var idx = Math.floor(i + 5 + Math.random() * 10);
293 if (idx &gt;= nodes.count) idx = i + (Math.random() * (nodes.count - i)) | 0;
294 var to = nodes.elt(idx);
295 linkArray.push({ from: from.data.key, to: to.data.key });
296 }
297 }
298 myDiagram.model.linkDataArray = linkArray;
299 myDiagram.commitTransaction("generateDigraph");
300
301</code></pre>
302<script>goCode("diag", 500, 500)</script>
303<script>
304 window.extras = [];
305 window.goCode3 = function(pre) {
306 extras.push(pre);
307 }
308
309 window.extra = function() {
310 for (var i = 0; i < extras.length; i++) {
311 var ex = extras[i];
312 var pre = document.getElementById(ex);
313 var f = eval("(function () {" + pre.textContent + "\n})");
314 f();
315 }
316 }
317</script>
318<p>
319 Our code for print preparation contains a <code>generateImages</code> function that cuts the Diagram into several images of a given width and height. On this page it is called by default with (700, 960), but the width and height can be modified dynamically with HTML inputs below.
320</p>
321<pre class="lang-js" id="manyImgCode"><code>
322 // if width or height are below 50, they are set to 50
323 function generateImages(width, height) {
324 // sanitize input
325 width = parseInt(width);
326 height = parseInt(height);
327 if (isNaN(width)) width = 100;
328 if (isNaN(height)) height = 100;
329 // Give a minimum size of 50x50
330 width = Math.max(width, 50);
331 height = Math.max(height, 50);
332
333 var imgDiv = document.getElementById('myImages');
334 imgDiv.innerHTML = ''; // clear out the old images, if any
335 var db = myDiagram.documentBounds;
336 var boundswidth = db.width;
337 var boundsheight = db.height;
338 var imgWidth = width;
339 var imgHeight = height;
340 var p = db.position;
341 for (var i = 0; i &lt; boundsheight; i += imgHeight) {
342 for (var j = 0; j &lt; boundswidth; j += imgWidth) {
343 var img = myDiagram.makeImage({
344 scale: 1,
345 position: new go.Point(p.x + j, p.y + i),
346 size: new go.Size(imgWidth, imgHeight)
347 });
348 // Append the new HTMLImageElement to the #myImages div
349 img.className = 'images';
350 imgDiv.appendChild(img);
351 imgDiv.appendChild(document.createElement('br'));
352 }
353 }
354 }
355
356 var button = document.getElementById('makeImages');
357 button.addEventListener('click', function() {
358 var width = parseInt(document.getElementById('widthInput').value);
359 var height = parseInt(document.getElementById('heightInput').value);
360 generateImages(width, height);
361 }, false);
362
363 // Call it with some default values
364 generateImages(700, 960);
365</code></pre>
366
367<p>
368 We want to show nothing but the images when this HTML page is printed, so we must use CSS rules to hide all page elements except the images themselves and the DOM parents of the images leading up to the body (#content, #myImages).
369</p>
370<p>
371 With the CSS below, printing this page will give yield nothing but the generated images that have been added to the end of this page. Typically the image or images used for printing may be hidden from the user completely, except when printing, or else added to a separate page in a new window.
372</p>
373<pre class="lang-css" id="mycss"><code>
374/* @media print specifies CSS rules that only apply when printing */
375@media print {
376 /* CSS reset to clear styles for printing */
377 html, body, div {
378 margin: 0;
379 padding: 0;
380 border: 0;
381 font-size: 100%;
382 font: inherit;
383 vertical-align: baseline;
384 }
385
386 /* Hide everything on the page */
387 body * {
388 display: none;
389 }
390
391 #content, #myImages, #myImages * {
392 /* Only display the images we want printed */
393 /* all of the image's parent divs
394 leading up to the body must be un-hidden (displayed) too
395 */
396 display: block;
397 /* CSS reset to clear the specific visible divs for printing */
398 margin: 0;
399 padding: 0;
400 border: 0;
401 font-size: 100%;
402 font: inherit;
403 vertical-align: baseline;
404 }
405
406 /* We have line breaks in the DIV
407 to separate the images in the browser,
408 but do not want those line breaks when printing
409 */
410 #myImages br {
411 display: none;
412 }
413
414 img {
415 /* Only some browsers respect this rule: */
416 page-break-inside: avoid;
417 /* Almost all browsers respect this rule: */
418 page-break-after:always;
419 }
420}
421
422/* The @page rules specify additional printing directives that browsers may respect
423 Here we suggest printing in landscape (instead of portrait) with a small margin.
424 Browsers, however, are free to ignore or override these suggestions.
425 See also:
426 https://developer.mozilla.org/en-US/docs/CSS/@page
427 https://dev.w3.org/csswg/css3-page/#at-page-rule
428*/
429@page {
430 /* Some browsers respect rules such as size: landscape */
431 margin: 1cm;
432}
433</code></pre>
434<p>
435 The images at the end of this page are generated by calling <code>generateImages(700, 960)</code>. Using the inputs below the images can be replaced with those of a different size. Different papers, page orientations, and margins will require different sized images if they are to fill the paper, and (700, 960) is a suggested size for 8.5 inch by 11 paper in portrait orientation, with minimal margins.
436</p>
437<div style="border: 1px solid gray; padding: 10px; margin-bottom: 20px;">
438Width: <input id="widthInput" value="700" />
439Height: <input id="heightInput" value="960" />
440<button id="makeImages">Generate images for printing</button>
441</div>
442<div id="myImages">
443</div>
444<script>goCode3('manyImgCode');</script>
445
446 </div>
447 </div>
448
449 <div class="bg-nwoods-primary">
450 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
451 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
452 </section>
453 </div><footer class="bg-nwoods-primary text-white">
454 <div class="container max-w-screen-lg mx-auto px-8">
455 <div class="w-full py-6">
456
457 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
458 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
459 <li class="list-none row-span-2">
460 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
461 <ul class="list-none space-y-4 md:space-y-1 px-0">
462 <li>
463 <a href="../samples/index.html">Samples</a>
464 </li>
465 <li>
466 <a href="../learn/index.html">Learn</a>
467 </li>
468 <li>
469 <a href="../intro/index.html">Intro</a>
470 </li>
471 <li>
472 <a href="../api/index.html">API</a>
473 </li>
474 <li>
475 <a href="../changelog.html">Changelog</a>
476 </li>
477 <li>
478 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
479 </li>
480 </ul>
481 </li>
482 <li class="list-none row-span-2">
483 <h2 class="text-base font-semibold tracking-wide">Support</h2>
484 <ul class="list-none space-y-4 md:space-y-1 px-0">
485 <li>
486 <a href="https://www.nwoods.com/contact.html"
487 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
488 </li>
489 <li>
490 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
491 </li>
492 <li>
493 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
494 </li>
495 <li>
496 <a href="https://www.nwoods.com/sales/index.html"
497 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
498 </li>
499 <li>
500 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
501 </li>
502 </ul>
503 </li>
504 <li class="list-none row-span-2">
505 <h2 class="text-base font-semibold tracking-wide">Company</h2>
506 <ul class="list-none space-y-4 md:space-y-1 px-0">
507 <li>
508 <a href="https://www.nwoods.com">Northwoods</a>
509 </li>
510 <li>
511 <a href="https://www.nwoods.com/about.html">About Us</a>
512 </li>
513 <li>
514 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
515 </li>
516 <li>
517 <a href="https://twitter.com/northwoodsgo">Twitter</a>
518 </li>
519
520 </ul>
521 </li>
522 </ul>
523
524
525 <p class="text-sm text-gray-100 md:mb-6">
526 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
527 </p>
528 </div>
529 </div>
530</footer> </body>
531
532<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
533<script>
534 window.dataLayer = window.dataLayer || [];
535 function gtag(){dataLayer.push(arguments);}
536 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
537 var getOutboundLink = function(url, label) {
538 gtag('event', 'click', {
539 'event_category': 'outbound',
540 'event_label': label,
541 'transport_type': 'beacon'
542 });
543 }
544
545 // topnav
546 var topButton = document.getElementById("topnavButton");
547 var topnavList = document.getElementById("topnavList");
548 topButton.addEventListener("click", function() {
549 this.classList.toggle("active");
550 topnavList.classList.toggle("hidden");
551 document.getElementById("topnavOpen").classList.toggle("hidden");
552 document.getElementById("topnavClosed").classList.toggle("hidden");
553 });
554</script>
555 <script src="../assets/js/prism.js"></script>
556 <script src="../release/go.js"></script>
557 <script src="../assets/js/goDoc.js"></script>
558 <script>
559 document.addEventListener("DOMContentLoaded", function() {
560 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
561 if (window.goDoc) window.goDoc();
562 var d = window.diagrams;
563 for (var i = 0; i < d.length; i++) {
564 var dargs = d[i];
565 goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
566 }
567 if (window.extra) window.extra();
568 });
569 </script>
570</html>