Print Task not printing textsymbol in correct format

1371
7
09-24-2021 05:27 AM
YashvitNaik
New Contributor III

I'm using ArcGIS Javascript API 4.15 for a web application, I have a TextSymbol added on the map, when I try to print the map using PrintTask, it is not printing the text in the proper format.

YashvitNaik_0-1632485743231.png

the above image is of the map with textsymbol, and the print version is this.

YashvitNaik_1-1632485832379.png

it prints all the text in a single line.

 

here's my code:

var template = new this.esri.PrintTemplate()
template.exportOptions = {
width: screen.availWidth,
height: screen.availHeight,
dpi: 96 //dots per inch
};
template.format = "pdf"
template.layout ="A4Landscape"
var printParameters = new this.esri.PrintParameters();
printParameters.view = this.mapView;
printParameters.template = template;
var printTask = new this.esri.PrintTask({ url: this.printUrl });
printTask.execute(printParameters)

 

0 Kudos
7 Replies
SailiTang1
New Contributor III

Hi,

The Printing service doesn't work like screenshot. It needs to grab your data and create a PDF (or other formats) on the ArcGIS server and then returns to client side. Where is the text from? It is part of your map or from a layer service?

0 Kudos
YashvitNaik
New Contributor III

Hi SailiTang1

It is the TextSymbol added on GarphicsLayer of the map

this.textGraphic = new Graphic({
id: "textGraphic",
geometry: geometry,
symbol: {
type: "text", // autocasts as new TextSymbol()
color: "black",
font: { // autocast as new Font()
size: 12,
family: "sans-serif"
},
text: "demo text"
}
});

0 Kudos
Noah-Sager
Esri Regular Contributor

Thank you for reporting this issue @YashvitNaik. It looks like the lineWidth property is not being properly honored. We are currently investigating, and I will respond this post when we have an update to share.

As a workaround, if you manually add newline escapes ("\n") to the text, it will print better. Example (ignore the missing symbols as the Esri Icon Font is not installed on the print service server):

https://codepen.io/noash/pen/ExXGVKd?editors=1000

 

Andy_Morgan
New Contributor III

Noah, thank you so much for looking into it. Will this bug be marked by the ESRI Development team as a fairly high priority? Soon I will be deploying an application I've migrated from 3.x to 4.x, and I discovered lineWidth is ignored at the last minute. 

Taking your idea of adding line escapes, some of us need to do this dynamically. So I found a handy regular expression that works to wrap user input which is being entered through a textarea element. It looks like this patch will do the trick for now. 

function addLineBreaks(textLabel) {

    //apply line breaks to wrap text with max width of 32 characters
    const wrappedText = textLabel.replace(
        /(?![^\n]{1,32}$)([^\n]{1,32})\s/g, '$1\n'
    );

    return wrappedText;
}

 

 

Andy_Morgan
New Contributor III

Also, I noticed multi-line text needs a vertical alignment of "bottom" in order to have a predictable location in the output pdf.

verticalAlignment: "bottom"

Otherwise, the default "baseline" setting will throw all text upward (when rendering the pdf) rather than going downward as it increases in length.

0 Kudos
Noah-Sager
Esri Regular Contributor

Thanks for posting your regex idea @Andy_Morgan, that's a really nice dynamic workaround. One word of caution though, and this gets to the heart of why this issue is tricky to fix, if you only count the number of characters, you won't get a consistent newline experience. This is because the characters can vary in width depending on the font family, the font size, the font weight, and what characters make-up the label (e.g. W is wider than I).

For the multi-text vertical alignment, I'm not sure I follow. Do you have a simplified test-app that I can see the issue with? 

0 Kudos
Andy_Morgan
New Contributor III

Hi Noah,

True, I don't think the solution is perfect for the reasons you've stated, but here's my final solution below. I had to add a second function on top of the initial wrapped text in order to break really long continuous strings that exceeded the preferred character max.  For example, if you included a long hyperlink like "https://community.esri.com/t5/arcgis-api-for-javascript-questions/print-task-not-printing-textsymbol..."

function addLineBreaks(textLabel) {
    //apply line breaks to wrap text with max width of 50 characters
    const wrappedText = textLabel.replace(
        /(?![^\n]{1,50}$)([^\n]{1,50})\s/g, '$1\n'
    );
    return wrappedText.replace(/(.{80})/g, "$1\n");
}

 

My text symbol is defined as follows:

       var textSymbolGeneric = {
            type: "text",  // autocasts as new TextSymbol()
            color: "white",
            haloColor: selectedColor,
            haloSize: "1px",
            text: "",
            xoffset: 0,
            yoffset: 0,
            font: {
                size: 12,
                family: "sans-serif",
                weight: "bold"
            },
            lineWidth: 300,
            horizontalAlignment: "left",
            verticalAlignment: "bottom"
        };

 

This is how it looks for verticalAlignment: "bottom"

Note the orange circle edit point which indicates the starting point for where I clicked to add the text.

vert_align_bottom.jpg

 

This is how it looks if I accept the default verticalAlignment value of "baseline"

vert_align_baseline.jpg

 

While the baseline setting is preferred, since it goes downward based on where you clicked and started your text, the problem is when our users go to export the map to pdf. They expect whatever is showing on the map, with all their redline markups and text, will be sent to another person and appear the same way. I am forced to make text start from the "bottom" only because it's reliable in the output pdf.

The result of printing the last image above, with "baseline" as the vertical alignment, will be the following.

I realize it's difficult to compare to the one above without the line and point features, but you can see the text shifted to way above the thick white (highway) line. 

 

vert_align_baseline_print_pdf_result.jpg

Side note: all the layers you're seeing turned on in this output pdf are not visible (unchecked in the layer list). This is a JS 4.20 application, way too large to share all the code broken up into many files. This is either another bug or something going on with my code. Either way it's not obvious to me yet, because the Web Map JSON string does not include those layers you see shown (blue and red lines, the yellow points, etc.). I would think the print task is including too much, but again maybe an oversight by me somewhere. 

For the sake of staying on topic with the original post I will not go further with this issue.

I'm unfortunately out of time to offer anything else for now. It may be days before I can return to this discussion. 

 

 

 

0 Kudos