I'm trying to add print functionality to a 4.x solution I'm working on using the PrintViewModel. I'm able to use all the functionality as described in the documentation, but there seems to be an inherent problem where the actual printout (pdf) returned from the printservice only contain a portion of the map that is visible in the browser.
It's very easy to reproduce this by opening the official print sample in fullscreen (Print widget - 4.14), and hitting print. The resulting printout will vary depending on your screen size, but in the majority of cases the printout will only contain a center envelope of the map which is displayed in the application.
Here are some screenshots to illustrate the problem:
This is what the user sees in the browser window when hitting print:
This is the result from the print service:
This is not a new problem and I've seen several questions about this on other forums. The problem also exists in version 3.x. Probably the problem is more connected to the print service than the JS api.
I've tried using the map-only option in PrintTemplate to specify a width and a height, and this kind of solves the problem, but then I'm stuck with a new problem which is that it is impossible to include a legend when printing using map-only.
For those of you familiar with Geocortex (which is a partner of ESRI), I've noticed that they have somehow solved the problem there, but I cannot access any readable source code to figure out how they've done it. In geocortex applications they show a print preview box, which illustrates what is going to be included in the printout. They also allow the user to specify which scale to use in the print. I want to build the same kind of printing functionality in my solution but currently I'm stuck with the bug above. If I at least could add a preview box so that the user could see what would be included in the printout that would be a huge step in the right direction.
Please, does anyone have any advice/suggestions?
There are some limitations when working with the Print widget. It is designed to be a simple, out-of-the-box solution for most use cases. Typically, we'd recommend using the PrintTask if you want finer grained control over the printout.
However, there are a couple of options that might be useful. First, you can modify the scale of the printout by changing the scale in the Print widget UI (under Advanced options) by setting the Set scale to true, and supplying a useful scale number (I used 40,000,000 as a test for the Print widget sample). Alternatively, you can also do this programmatically like in the codepen below.
Another approach is to use the takeScreenshot() method. This is a more interactive tool that can allow a user to select (similar to preview) the target area for printing. We have a live working sample using a 3D SceneView.
I hope this information is helpful.
print scale sample (codepen)
mapView.takeScreenshot() method doc
Screenshot of SceneView sample
Hi Jeff, you can't use custom code or custom widgets if you're talking about an application hosted in ArcGIS Online. If you're hosting the app yourself, then you're fine, but AGO will not allow customized code like this for security reasons.
Thanks for the input Noah. I actually managed to solve my problem, and create a preview box for the print (using only the printViewModel and some custom logic). My printouts now only contain the portion of the map that is visible within the preview box. The user selects which map scale to use in a dropdown, and the bounding box updates accordingly.
The key to solving my problem was to understand the relationship between pixels and resolutions. Each zoom level has a specific resolution, and that resolution defines how many map units (for example meters) there will be in one pixel. Using this information it is possible to calculate the area that will be included in a printout and highlight this area in the map. You also need to know exactly how big the map image in the printout will be (in pixels).
I can add a fiddle to better explain my solution later, if other users are interested (I'm guessing Noah already know what I'm talking about ).
I'm not familiar with implementing stuff for AGOL webapps, but I guess it's based on the JS API and I think you can make your own widgets, so it's probably possible to build a widget using the same logic I'm using. I will provide a sample of what I have built soon, but this will be a pure arcgis js implementation, and not an AGOL webapp widget.