how to get pagecount in background object in pdfmake? - node.js

how to get pageCount in background object, here is my code.
background: (currentPage, pageCount) => {
if (currentPage === 1) {
return [
{
image: img.coverbg,
height: 521,
width: 756
}
]
}
else if(currentPage == pageCount) {
return [
{
image: img.headbg,
width: 755,
height: 30,
},
]
}
},
i want pageCount in background, but i didnt get that,
i only get currentPage,
so how to get pageCount in background object.

You can use the header and footer functions to access the pageCount parameter.
These functions have three parameters - currentPage, pageCount and pageSize and you can apply any logic and return any valid pdfmake element from these functions.
So essentially, what you're doing in background can be done in either header or footer.

Access current page using currentPage and total page count using pageCount
docDefinition = {
pageMargins: [40, 150, 40, 40],
header: {
margin: 25.5,
columns: [
{
image: logo,
height: 106.4,
width: 540
// alignment: 'center'
}
]
},
footer: function (currentPage, pageCount) {
return [{ text: 'Page ' + currentPage.toString() + ' of ' + pageCount, alignment: 'center' }];
},
content: pdf, //pdf is all the data i use to generate pdf
defaultStyle: {
font: 'Times'
}
}

can't get pageCount in the background object,
we have to find another way for that.

Related

Multiline footer with PDFMake

I am trying to create a multiline footer with pdfmake; what I was able to do until now:
const docDefinition = {
footer: [
{
stack: [
{ text: "Line 1" },
{ text: "Line 2" },
{ text: "Line 3" },
{ text: "Line 4" }
], style: 'footer'
}
],
styles: {
footer: {
fontSize: 6, bold: true, alignment: 'center'
}
}
};
While this creates what I want, the style is not correct. As soon as I increase the font size, the bottom line starts to disappear. If I set the font size to 12, only the first two lines appear in the generated PDF on the server-side.
What change do I need to make here?
You just need to add margin to the page and you can accommodate as many lines as you want. e.g. Enter the code below in pdfmake playground: http://pdfmake.org/playground.html
// playground requires you to assign document definition to a variable called dd
let textFooter = `
A 12.4% discretionary service charge will be added to your bill. All prices are inclusive of VAT. Thank You!\n\n
This is line 2 - 263139\n
Line 3 comes here\n
Go big or go home!!!
`;
var dd = {
header: function(currentPage, pageCount, pageSize) {
return [
{ text: 'simple text\naaa\nbbb\nccc\nddd', alignment: 'center', fontSize: 9 },
]
},
footer: function(currentPage, pageCount, pageSize) {
return [
{ text: textFooter, alignment: 'center', fontSize: 9 },
]
},
// margin: [left, top, right, bottom]
pageMargins: [ 40, 60, 40, 100 ],
content: [
'First paragraph',
'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
]
}
In the code above, I have set margin bottom to 100 which gives us space to include 4 lines.

Vertical lines in pdfkit-tables in node.js

I have API that generate pdf file after saving values into database. My customer needed to generate this pdf and then send it by mail. He sended my photo of how should that pdf look like. I recreated it, it looks same as in that picture but it is hard to read because there are missing vertical lines. I looked trought docs and also tried to google, bud I did not found anyithing.
Here is how my PDF looks like:
As you can see, vertical lines are missing and because of that is harder to read.
Is there any possibility to add vertical lines?
Here is my code:
let doc = new PDFDocument({ margin: 30, size: "A4" });
doc.pipe(
fs.createWriteStream(`${problemName}_${creationDate}` + ".pdf")
);
const table = {
title:
"Zápis koordinátora " +
koordinatorName +
" zo dna " +
creationDate +
".",
divider: {
header: { disabled: true },
horizontal: { disabled: false, width: 1, opacity: 1 },
padding: 5,
columnSpacing: 10,
},
headers: [
{ width: 130, renderer: null },
{ width: 130, renderer: null },
{ width: 130, renderer: null },
{ width: 130, renderer: null },
],
rows: [
["Nazov", problemName, "", ""],
[
"Nazov staveniska (Projekt)",
constructionName,
"Na vedomie komu",
"mailing list 1",
],
[
"Vytvoril koordinator BOZP",
koordinatorName,
"Priorita",
problemPriority,
],
["Datum zistenia", creationDate, "Datum odstranenia", ""],
[
"Zodpovedny za vyriesenie zistenia",
"Janko Maly",
"Celkovy pocet zisteni v dni",
10,
],
["Miesto zistenia", discoveryPlace, "Zistenie císlo", 1],
["Popis", problemText],
[
"Navrh na udelenie sankcie",
"50€",
"Pre spolocnost",
adressedFor,
],
],
};
doc.table(table, {
prepareHeader: () => doc.font("Helvetica-Bold").fontSize(8),
prepareRow: (row, indexColumn, indexRow, rectRow, rectCell) => {
doc.font("Helvetica").fontSize(8);
indexColumn === 0;
},
});
doc.end();
I am using pdfkit-table package.
Thank you all
By definition simple PDF structure is not tabular there is one cell (the page) and that one column can be subdivide into two or more rows with null spaces between the text sub columns.
That is why tables are difficult to sub[ex]tract
So adding coloured rows in one area is fairly simple to make like a table, thus to make vertical sub dividers is more difficult, However that feature was added in January 2022 https://github.com/natancabral/pdfkit-table/files/7865078/document-5.pdf
For exsample see https://github.com/natancabral/pdfkit-table/issues/16#issuecomment-1012389097

how to keep the same width in all bars in C3 Javascript library?

I wan't to set all bars the same width, because if I have few bars they get super big, and If I have a lot bars they get very thin.
Here is what I mean:
I have bar width 50 because I tought this was the size of the bar, but it keeps making bars small if the amount increases.
Here is my code:
$(document).ready(function () {
var chart = c3.generate({
bindto: '#stocked',
size: {
height: 320,
width: 1500
},
data: {
labels: ['y',1,2,3,4,5,6],
columns: [
['MUSCLE', <?php echo substr($muscle,1,strlen($muscle)); ?>],
['FAT', <?php echo substr($fat,1,strlen($fat)); ?>]
],
groups: [
['MUSCLE', 'FAT']
],
type: 'bar',
colors: {
MUSCLE: '#75e3ff',
FAT: '#23bbe8'
}
},
bar: {
// width: { ratio: 0.8 }
width: 50,
},
axis: {
x: {
type: 'categories',
show: true,
label: {
text: 'Measurements',
position: 'outer-middle'
},
tick: {
format: "%b",
fit: true,
},
},
y: {
label: {
text: '<?php echo $_SESSION["unit"]; ?>',
position: 'outer-middle'
}
},
},
// subchart: {
// show: true
// },
// zoom: {
// enabled: true
// }
});
});
Thanks and greetings!
The width of your bars is the result of the width of your chart and the amount of data you have populating it. My recommendation would be to size your chart or the container holding your chart accordingly. This will prevent having large white spaces in between each of your bars and result in a more uniform look between your charts.
ex: pseudo code of how to determine how wide you chart should be.
var chart = c3.generate({
size: {
height: 240,
width: function () {
return 6 * 20 + 15
},
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
]
}
});
Here you can see that there of 6 pieces of data and each data is given 20 space and then an extra 15 to account for the axis/labels etc. If each you had 50 data then it should be width: 6 * 20 + 15 ..... of course now you have different width chart but the bar widths and space between bars should be pretty uniform. The more data the longer the chart. You might need to "20" and "15" to get the look you want.

Rotate Element at Center

I am trying to build a custom shape - a diamond that stays centered over the text in its label (bonus if we can make the shape expand as the label changes).
Right now, I am transforming a rectangle by 45 degrees to create the diamond. Problem is this seems to rotate around to top left corner and not the center point.
How can I make JointJS rotate this shape around it's center? Or is there a better way to accomplish this?
Here is a JSFiddle.
http://jsfiddle.net/dfqpbLyn/3/
var baseRhombus = joint.shapes.standard.Rectangle.define('crt.BaseRhombus',
{
attrs: {
label: {
textAnchor: 'middle',
textVerticalAnchor: 'middle',
fontSize: 25,
text: 'Test'
},
body: {
strokeWidth: 1,
stroke: 'green',
fill: 'gray',
//transform-origin: center center,
transform: 'rotate(45, center, center)',
}
}
},
{
markup:
[
{
tagName: 'rect',
selector: 'body'
},
{
tagName: 'text',
selector: 'label'
}
]
},
{
initialize: function (width, height, x, y) {
var newElement = new this({
id: 'g1',
position: {x:x, y:y},
size: {width: width, height: height},
//position: { x: x, y: y },
});
return newElement;
}
}
);
var baseRhombus = joint.shapes.crt.BaseRhombus.initialize(250, 250, 60, 50);
Thanks!
Will
Figured it out. Used
transform: 'rotate(45, 50, 50) on the body of my element, but calculated the transform origin based on the current width and height of the element. The documentation around transform was a bit difficult to find but once I found an example of it in use it became clear.

2 different font sizes for text inside basic Rect, jointjs

I have a basic Rect shape like this:
var rectShape = new joint.shapes.basic.Rect({
position: { x: 60, y: 10 },
size: { width: 160, height: 35 },
attrs: {
rect: {
fill: '#F5F5F5'
},
text: {
fill: '#FC8A26',
'font-size': 12,
'font-weight': 'bold',
'font-variant': 'small-caps'
}
}
});
I use clone() to create more rectangles like that one:
var rect1 = rectShape.clone().translate(520, 10).attr('text/text','rect1');
I want to have 2 different words inside the rect, one at the size 12 and the other at the size 8. Any idea on how I can do that?
Thank you!
you need to create a custom shape with new SVG markup containing a text element that contains a <tspan> for each word that you want. You could adapt the markup from the standard Rect element. Give each element a different class name, for example replace the <text/> element in the Rect markup with <text><tspan class="word1"/><tspan class="word2"/></text>. The shape definition would look like this:
joint.shapes.my.twoTextRect = joint.shapes.basic.Generic.extend({
markup: '<g class="rotatable"><g class="scalable"><rect/></g><text><tspan class="word1"></tspan> <tspan class="word2"></tspan></text></g>',
defaults: joint.util.deepSupplement({
type: 'my.twoTextRect',
attrs: {
rect: { fill: 'white', stroke: 'black', 'stroke-width': 1, 'follow-scale': true, width: 160, height: 35 },
text: { ref: 'rect' },
'.word1': { 'font-size': 12 },
'.word2': { 'font-size': 8 }
},
size: { width: 160, height: 35 }
}, joint.shapes.basic.Generic.prototype.defaults)
});
Then to create your shape instance:
var rectShape = new joint.shapes.my.twoTextRect();
To set the text of the <tspan> SVG elements you can use
rectShape.attr('.word1/text', 'word 1');
rectShape.attr('.word2/text', 'word 2');
This results in an element that looks like this:
You can clone the element like this:
var clone = rectShape.clone().translate(520, 10).attr({'.word1': {text: 'clone1'}, '.word2': {text: 'clone2' }});
And this makes a new element:

Resources