Simple Newspaper Layout with jsPDF

published on June 29, 2015 in technical

In our previous post we examined basic methods from the jsPDF library and now we will build a realistic layout, a newspaper page.

In case you want to have a look at the previous post, you may read it here. Also, if you prefer jumping directly to the code, I have shared it on Github.

Now that we got those out of the way, let’s have a look at what I did and how I did that.

Page layout

As I mentioned, we will build a simple newspaper page layout. It will have two colums, a header and a footer. Columns will contain text and some charts.

For putting text in there we used the paragraph adding code snipped which I shared in the previous post. For the rest of the content, I created some simple functions with mock data. Let us check them out.

Bar chart

I used a simple visualisation, just to make sure the exmple is easily understandable. Here is the code

function barChart(x, y, pdf, data) {
  var chartWidth = page.columnWidth + 10; 
  var totalLength = data.length;
  var stepSize = chartWidth / totalLength;

  pdf.setLineWidth(20)
    .setDrawColor(21, 124, 197);
    
  for (i = 0; i < totalLength; i++) {
    pdf.line((i + 1) * stepSize, y + 90, (i + 1) * stepSize, 
y + 90 - data[i].value)
    .setFont("arial", "normal")
    .setTextColor(0)
    .setFontSize(6)
    .text((i + 1) * stepSize - pdf.getStringUnitWidth(data[i].label) * 
6 / pdf.internal.scaleFactor / 2, y + 95, data[i].label)
    .setFontSize(12)
    .text((i + 1) * stepSize - pdf.getStringUnitWidth(data[i].value) * 
12 / pdf.internal.scaleFactor / 2 - 5, y + 85 - data[i].value, data[i].value + "");
}

I basically drew a number of vertical lines equal to the number of the elements in the data array. I set the thickness of the line to 20, so that they look like bars. Also, I use a trick for adding text centered

.text(
    x - pdf.getStringUnitWidth(text) * 12 
    / pdf.internal.scaleFactor / 2 - 5, 
    y + 85 - text
);

What we have here is a simpe calculation of the widht of text, for a certain font size. The part deducted from x is half the size of the rendered text string, which is very helpful for the cases when we don’t want the text to be inserted with a left bottom origin, but use instead a center bottom one.

We can modify or improve the above code in several ways. For instance, we can make the thickness of the bars dynamic, so that when we insert several bars the don’t overlap. Or we could add axis, which are basically lines with labels.

Round chart

Given that the jsPDF library does not have a good way of inserting arcs, I replaced that with inserting image data coming from a HTML5 canvas element. This should be very straight forward operation, the line should look something like this

pdf.addImage(canvas.toDataURL("image/jpeg", 1.0), "JPEG", x, y, 110, 110);

As you may see, I specify the image data, its type, the coordinates in the pdf and its width and height. This is very similar to how we insert images in PDF files with this library, the only thing we need to be careful with images is that they have to be available in the browser when we try to add them to the canvas element.

Quote

Sometime we need to quote other resources in newspapers, so I made a simple quote method, which actually inserts a quote character and a differently style text to make ait all look like a designed quote

function quote(x, y, pdf, text) {
  var lines = pdf.setFontSize(20)
    .setFont("times", "italic")
    .setTextColor(0)
    .splitTextToSize("\"" + text + "\"", page.columnWidth);
  pdf.text(x + 10, y, lines);
}

Rap up

As I mentioned above, the put together a github repo for this code which you may find here. Please have a look, please feel free to reach out.