How can I make number counter to count multiple elements in Wix Velo - counter

I'm making a website on Wix and it has Velo which works like javascript (I don't understand much in coding)
I was trying to do a number counter which counts from 0 to a given number and I did it, but I need 4 different counters not sure how to do it maybe someone can help, please.
so my code looks like this
$w.onReady(function() {});
let startNum = 0;
let endNum = 145;
const duration = 20;
$w.onReady(function() {
setInterval(() => {
countUp();
}, duration);
});
function countUp() {
if (startNum <= endNum) {
$w('#StartNumber').text = startNum.toString();
startNum++;
}
}
#startnumber is a text element that goes from 0 to 145
I want to do the same with 3 more elements #startnumber2, 3, and 4.
this is what I'm trying to do

The counting logic can be extracted to a function so you could call it for all the text components.
$w.onReady(function () {
count($w('#text1'), 0, 150, 1000);
count($w('#text2'), 0, 250, 1000);
count($w('#text3'), 0, 500, 1000);
count($w('#text4'), 0, 1000, 1000);
});
function count(obj, start, end, duration) {
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
obj.text = `${Math.floor(progress * (end - start) + start)}`;
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
}
Demo: https://moshef9.wixsite.com/count-numbers
The counter function is taken from: https://stackoverflow.com/a/60291224/863110

Related

Vehicle routing problem with dependent dimension constraints (Google ORTools)

I'm very new to OR-Tools and I'm trying to solve a modified VRP with capacity constraints from Google's guide.
In my problem vehicles transport multiple types of items. Some types can be transported together and others cannot.
What I tried
In the following code the types are A and B (they should not be transported together).
First I defined the two callbacks for demands and added the dimensions to the routing model
int demandACallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
var fromNode = manager.IndexToNode(fromIndex);
return demandsA[fromNode];
});
int demandBCallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
var fromNode = manager.IndexToNode(fromIndex);
return demandsB[fromNode];
});
routing.AddDimensionWithVehicleCapacity(demandACallbackIndex, 0,
capacitiesA,
true,
"CapacityA");
routing.AddDimensionWithVehicleCapacity(demandBCallbackIndex, 0,
capacitiesB,
true,
"CapacityB");
Then I retrieved the dimensions and added constraints to routing.solver() for every node
var capacityADimension = routing.GetDimensionOrDie("CapacityA");
var capacityBDimension = routing.GetDimensionOrDie("CapacityB");
for (int i = 0; i < noDeliveries; i++) {
var index = manager.NodeToIndex(i);
routing.solver().Add(capacityADimension.CumulVar(index) * capacityBDimension.CumulVar(index) == 0);
}
When I run the solver (with two vehicles) these constraints seem to be ignored (one vehicle remains parked while the other does all the work even though it shouldn't transport both types of items).
Is this even possible with OR-Tools? If yes, what did I do wrong?
Full code
public SimpleVehicleRoutingSolutionDto SolveVehicleRoutingWithItemConstraints(long[,] distances, long[] capacitiesA, long[] capacitiesB, long[] demandsA, long[] demandsB, int depot)
{
int noVehicles = capacitiesA.Length;
int noDeliveries = deliveriesA.Length;
RoutingIndexManager manager =
new RoutingIndexManager(noDeliveries, noVehicles, depot);
RoutingModel routing = new RoutingModel(manager);
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) => {
var fromNode = manager.IndexToNode(fromIndex);
var toNode = manager.IndexToNode(toIndex);
return distances[fromNode, toNode];
});
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
int demandACallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
// Convert from routing variable Index to demand NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
return demandsA[fromNode];
});
int demandBCallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) => {
// Convert from routing variable Index to demand NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
return demandsB[fromNode];
});
routing.AddDimensionWithVehicleCapacity(demandACallbackIndex, 0,
capacitiesA,
true,
"CapacityA");
routing.AddDimensionWithVehicleCapacity(demandBCallbackIndex, 0,
capacitiesB,
true,
"CapacityB");
var capacityADimension = routing.GetDimensionOrDie("CapacityA");
var capacityBDimension = routing.GetDimensionOrDie("CapacityB");
for (int i = 0; i < noDeliveries; i++) {
var index = manager.NodeToIndex(i);
routing.solver().Add(capacityADimension.CumulVar(index) * capacityBDimension.CumulVar(index) == 0);
}
RoutingSearchParameters searchParameters =
operations_research_constraint_solver.DefaultRoutingSearchParameters();
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch;
searchParameters.TimeLimit = new Duration { Seconds = 1 };
Assignment solution = routing.SolveWithParameters(searchParameters);
var ret = new SimpleVehicleRoutingSolutionDto();
long totalDistance = 0;
for (int i = 0; i < noVehicles; ++i)
{
var vecihle = new VehiclePathDto { Index = i };
long routeDistance = 0;
var index = routing.Start(i);
while (routing.IsEnd(index) == false)
{
long nodeIndex = manager.IndexToNode(index);
vecihle.Waypoints.Add(new WaypointDto { Index = nodeIndex });
var previousIndex = index;
index = solution.Value(routing.NextVar(index));
routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
}
vecihle.Distance = routeDistance;
ret.Vehicles.Add(vecihle);
totalDistance += routeDistance;
}
ret.TotalDistance = totalDistance;
return ret;
}
And the input:
long[,] dist = {
{ 0, 5, 6 },
{ 5, 0, 3 },
{ 6, 3, 0 }
};
long[] capA = { 5, 5 };
long[] capB = { 5, 5 };
long[] demA = { 0, 1, 0 };
long[] demB = { 0, 0, 1 };
var routingSolution = vehicleRouting.SolveVehicleRoutingWithItemConstraints(dist, capA, capB, demA, demB, 0);
I fixed the problem.
The issue was that the number of nodes was 3 (noDeliveries), however the number of indices was 6, so I only set the constraint on half of them.
Fixed code:
for (int i = 0; i < manager.GetNumberOfIndices(); i++) {
routing.solver().Add(capacityADimension.CumulVar(i) * capacityBDimension.CumulVar(i) == 0);
}
EDIT:
Even better if constraints are set only for the route end node, since the CumulVar value is strictly increasing.
for (int j = 0; j < noVehicles; j++) {
var index = routing.End(j);
routing.solver().Add(capacityADimension.CumulVar(index) * capacityBDimension.CumulVar(index) == 0);
}

Can this stock graph be made using Highstock?

Could this graph be made using Highstock?
I'm currently using Highstock, but never saw this kind.
Before I waste weeks trying, the question needs to be asked...
If yes, how can this be made? by shifting the stock chart, and create another Xaxis at the right?
Stock projection
According to the comments - a similar result could be achieved by adding additional series with proper data.
Demo: https://jsfiddle.net/BlackLabel/mkpj71n4/
chart: {
events: {
load() {
let chart = this;
function addNewSeries(y, color) {
let data = [],
xValue = startDay,
yData = 420; // last candle
for (let i = 0; i < 20; i++) {
xValue = xValue + 30 * 60 * 1000;
yData = yData + i * y
data.push([xValue, yData])
}
chart.addSeries({
data: data,
color: color
})
}
for (let i = 0; i < 4; i++) {
if (i === 0) {
addNewSeries(0.1, 'orange')
} else if (i === 2) {
addNewSeries(-0.1, 'orange')
} else if (i === 3) {
addNewSeries(0.2, 'red')
} else {
addNewSeries(-0.2, 'red')
}
}
}
}
},
API: https://api.highcharts.com/highcharts/chart.events.load
API: https://api.highcharts.com/class-reference/Highcharts.Chart#addSeries

How to Round up the Date-Time nearest to 30 min interval in DART (Flutter)?

I would like to round DateTime to the nearest 30 mins. Is there rounding mechanism provided in DART?
I had a similar problem today and but it was to clamp to the next 15 mins.
DateTime nearestQuarter(DateTime val) {
return DateTime(val.year, val.month, val.day, val.hour,
15, 30, 45, 60][(val.minute / 15).floor()]);
}
or in your case
DateTime nearestHalf(DateTime val) {
return DateTime(val.year, val.month, val.day, val.hour,
[30, 60][(val.minute / 30).floor()]);
}
I just noticed you said 'nearest half hour'
DateTime nearestHalf(DateTime val) {
return DateTime(val.year, val.month, val.day, val.hour,
[0, 30, 60][(val.minute / 30).round()]);
}
https://francescocirillo.com/pages/anti-if-campaign
You can use this function to roundup the time.
DateTime alignDateTime(DateTime dt, Duration alignment,
[bool roundUp = false]) {
assert(alignment >= Duration.zero);
if (alignment == Duration.zero) return dt;
final correction = Duration(
days: 0,
hours: alignment.inDays > 0
? dt.hour
: alignment.inHours > 0
? dt.hour % alignment.inHours
: 0,
minutes: alignment.inHours > 0
? dt.minute
: alignment.inMinutes > 0
? dt.minute % alignment.inMinutes
: 0,
seconds: alignment.inMinutes > 0
? dt.second
: alignment.inSeconds > 0
? dt.second % alignment.inSeconds
: 0,
milliseconds: alignment.inSeconds > 0
? dt.millisecond
: alignment.inMilliseconds > 0
? dt.millisecond % alignment.inMilliseconds
: 0,
microseconds: alignment.inMilliseconds > 0 ? dt.microsecond : 0);
if (correction == Duration.zero) return dt;
final corrected = dt.subtract(correction);
final result = roundUp ? corrected.add(alignment) : corrected;
return result;
}
and then use it the following way
void main() {
DateTime dt = DateTime.now();
var newDate = alignDateTime(dt,Duration(minutes:30));
print(dt); // prints 2022-01-07 15:35:56.288
print(newDate); // prints 2022-01-07 15:30:00.000
}
This function converts a DateTime to the nearest 30 minute mark in a clock. Be warned that this 30 minute mark is obtained with respect to the local time zone of the machine in which this code runs on.
DateTime roundWithin30Minutes(DateTime d) {
final int deltaMinute;
if (d.minute < 15) {
deltaMinute = -d.minute; // go back to zero
} else if (d.minute < 45) {
deltaMinute = 30 - d.minute; // go to 30 minutes
} else {
deltaMinute = 60 - d.minute;
}
return d.add(Duration(
milliseconds: -d.millisecond,
// reset milliseconds to zero
microseconds: -d.microsecond,
// reset microseconds to zero,
seconds: -d.second,
// reset seconds to zero
minutes: deltaMinute));
}
If you are presenting this DateTime in another non local time zone whose offset duration is not a multiple of 30 minutes (eg: Nepal time zone is GMT+5:45) this implementation will not work.
extension DateTimeExt on DateTime {
DateTime get roundMin =>
DateTime(this.year, this.month, this.day, this.hour, () {
if (this.minute <= 15) {
return 0;
} else if (this.minute > 15 && this.minute <= 45) {
return 30;
} else {
return 60;
}
}());
}
You can do It with a simple extension just call it like this
var a = DateTime(2021, 5, 4, 3, 46, 4, 7);
print(a.roundMin);

Dygraphs - How do I restrict drawing to canvas

I have a graph where I am using underlays to draw vertical lines between the points. I have a line of code that restricts these vertical lines to NOT draw outside the active canvas. But when I use this underlayCallback, the 'points' are still drawn outside the canvas. If I remove my underlayCallback, the points are restricted to the canvas as one would expect. Here is what they look like and my code. (Sorry, the site is too secure to provide working sample.)
g[i] = new Dygraph(thisdiv, mylines, {
labels: graphlbls[i],
ylabel: graphunits[i].capitalizeFirstLetter(),
xlabel: '',
xLabelHeight:15,
yLabelWidth:15,
rightGap: 5,
labelsDivStyles: {
'text-align': 'right',
'background': 'none'
},
colors: ['#D48513','#1D6EB5'],
title: graphtitles[i],
titleHeight:23,
drawPoints: true,
showRoller: false,
drawXGrid: false,
drawYGrid: true,
strokeWidth: 0,
pointSize: 4,
highlightCircleSize: 6,
gridLineColor: "#ddd",
axisLabelFontSize: 12,
xAxisHeight: 20,
valueRange: [minval, maxval],
rangeSelectorHeight: 30,
showRangeSelector: true,
rangeSelectorPlotFillColor: '#ffffff',
rangeSelectorPlotStrokeColor: '#ffffff',
interactionModel: Dygraph.defaultInteractionModel,
axes: {
x: {
valueFormatter: function (ms) {
var d = new Date(ms);
var day = "0"+d.getDate();
var month = "0"+(d.getMonth()+1);
var year = d.getFullYear();
var hour = "0"+ d.getHours();
var min = "0"+d.getMinutes();
var p = "AM";
if (hour > 12) { p = "PM"; hour = hour - 12; }
if (df == 0) var dd = month.slice(-2)+"/"+day.slice(-2)+"/"+year;
if (df == 1) var dd = day.slice(-2)+"/"+month.slice(-2)+"/"+year;
if (tf == 0) var tt = hour.slice(-2)+":"+min.slice(-2)+" "+p+" ";
if (tf == 1) var tt = hour.slice(-2)+":"+min.slice(-2)+" ";
return dd + " - " + tt;
}
}
},
underlayCallback: function(ctx, area, g) {
//if (typeof(g[i]) == 'undefined') return; // won't be set on the initial draw.
var range = g.xAxisRange();
var rows = g.numRows();
// get max and min y
for (var i = 0; i < rows; i++) {
miny = 99999;
maxy = -99999;
xx = g.getValue(i,0);
if (xx < range[0] || xx > range[1]) continue; // constrain to graph canvas
for (var j=1; j<= range.length; j++) {
if (g.getValue(i,j) <= miny) miny = g.getValue(i,j);
if (g.getValue(i,j) >= maxy) maxy = g.getValue(i,j);
}
p1 = g.toDomCoords(xx, miny);
p2 = g.toDomCoords(xx, maxy);
ctx.strokeStyle = "rgba(192,192,224,1)";
ctx.lineWidth = 1.0;
ctx.beginPath();
ctx.moveTo(p1[0], p1[1]);
ctx.lineTo(p2[0], p2[1]);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
}
});
You're calling ctx.restore() many times without corresponding calls to ctx.save(). This pops off dygraphs' own drawing context, including the clipping rectangle. Make one call to save at the top of your underlayCallback and one to restore at the end.
Stepping back a bit, what you're doing might be easier with a custom plotter, rather than an underlayCallback.

jsPDF multi page PDF with HTML renderer

I am using jsPDF in my site to generate PDFs. But now I have multiple DIVs to print in a single PDF. which may take 2 to 3 pages.
For example:
<div id="part1">
content
</div>
<div id="part2">
content
</div>
<div id="part2">
content
</div>
my JS code
This works but not as I expected, It add a part of the content(which cannot be included in more than one page).
It removes html tags like br, h1 etc.
function formtoPDF() {
jsPDF.API.mymethod = function() {
// 'this' will be ref to internal API object. see jsPDF source
// , so you can refer to built-in methods like so:
// this.line(....)
// this.text(....)
};
var doc = new jsPDF();
doc.mymethod();
var pdfPart1 = jQuery('#genPDFpart1');
var pdfPart2 = jQuery(".ltinerary");
var pdfPart3 = jQuery("#domElementHTML");
var specialElementHandlers = {
'#loadVar': function(element, renderer) {
return true;
}
};
doc.fromHTML(pdfPart1.html() + pdfPart3.html() + pdfPart3.html(), 15, 15, {
'width': 170,
'elementHandlers': specialElementHandlers
});
doc.output('save', 'Download.pdf');
}
What's the solution for this?
I have the same working issue. Searching in MrRio github I found this: https://github.com/MrRio/jsPDF/issues/101
Basically, you have to check the actual page size always before adding new content
doc = new jsPdf();
...
pageHeight= doc.internal.pageSize.height;
// Before adding new content
y = 500 // Height position of new content
if (y >= pageHeight)
{
doc.addPage();
y = 0 // Restart height position
}
doc.text(x, y, "value");
here's an example using html2canvas & jspdf, although how you generate the canvas doesn't matter--we're just going to use the height of that as the breakpoint on a for loop, in which a new page is created and content added to it.
after the for loop, the pdf is saved.
function makePDF() {
var quotes = document.getElementById('container-fluid');
html2canvas(quotes).then((canvas) => {
//! MAKE YOUR PDF
var pdf = new jsPDF('p', 'pt', 'letter');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 980*i; // start 980 pixels down for every new page
var sWidth = 900;
var sHeight = 980;
var dX = 0;
var dY = 0;
var dWidth = 900;
var dHeight = 980;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 900);
onePageCanvas.setAttribute('height', 980);
var ctx = onePageCanvas.getContext('2d');
// details on this usage of this function:
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);
// document.body.appendChild(canvas);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
//! If we're on anything other than the first page,
// add another page
if (i > 0) {
pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
}
//! now we declare that we're working on that page
pdf.setPage(i+1);
//! now we add content to that page!
pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width*.62), (height*.62));
}
//! after the for loop is finished running, we save the pdf.
pdf.save('Test.pdf');
});
}
I found the solution on this page: https://github.com/MrRio/jsPDF/issues/434
From the user: wangzhixuan
I copy the solution here:
// suppose your picture is already in a canvas
var imgData = canvas.toDataURL('image/png');
/*
Here are the numbers (paper width and height) that I found to work.
It still creates a little overlap part between the pages, but good enough for me.
if you can find an official number from jsPDF, use them.
*/
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save( 'file.pdf');
var doc = new jsPDF('p', 'mm');
var imgData = canvas.toDataURL('image/png');
var pageHeight= doc.internal.pageSize.getHeight();
var pageWidth= doc.internal.pageSize.getWidth();
var imgheight = $('divName').height() * 25.4 / 96; //px to mm
var pagecount = Math.ceil(imgheight / pageHeight);
/* add initial page */
doc.addPage('l','mm','a4');
doc.addImage(imgData, 'PNG', 2, 0, pageWidth-4, 0);
/* add extra pages if the div size is larger than a a4 size */
if (pagecount > 0) {
var j = 1;
while (j != pagecount) {
doc.addPage('l','mm','a4');
doc.addImage(imgData, 'PNG', 2, -(j * pageHeight), pageWidth-4, 0);
j++;
}
}
You can use html2canvas plugin and jsPDF both. Process order:
html to png & png to pdf
Example code:
jQuery('#part1').html2canvas({
onrendered: function( canvas ) {
var img1 = canvas.toDataURL('image/png');
}
});
jQuery('#part2').html2canvas({
onrendered: function( canvas ) {
var img2 = canvas.toDataURL('image/png');
}
});
jQuery('#part3').html2canvas({
onrendered: function( canvas ) {
var img3 = canvas.toDataURL('image/png');
}
});
var doc = new jsPDF('p', 'mm');
doc.addImage( img1, 'PNG', 0, 0, 210, 297); // A4 sizes
doc.addImage( img2, 'PNG', 0, 90, 210, 297); // img1 and img2 on first page
doc.addPage();
doc.addImage( img3, 'PNG', 0, 0, 210, 297); // img3 on second page
doc.save("file.pdf");
$( document ).ready(function() {
$('#cmd').click(function() {
var options = {
pagesplit: true //include this in your code
};
var pdf = new jsPDF('p', 'pt', 'a4');
pdf.addHTML($("#pdfContent"), 15, 15, options, function() {
pdf.save('Menu.pdf');
});
});
});
This is my first post which support only a single page http://www.techumber.com/html-to-pdf-conversion-using-javascript/
Now, the second one will support the multiple pages.
http://www.techumber.com/how-to-convert-html-to-pdf-using-javascript-multipage/
Below is my code but the problem is that the document doesn't split to display the other part of the document in a new page.
Please improve this code.
<script type='text/javascript'>
$(document).on("click", "#btnExportToPDF", function () {
var table1 =
tableToJson($('#table1')[0]),
cellWidth =42,
rowCount = 0,
cellContents,
leftMargin = 2,
topMargin = 12,
topMarginTable =5,
headerRowHeight = 13,
rowHeight = 12,
l = {
orientation: 'p',
unit: 'mm',
format: 'a3',
compress: true,
fontSize: 11,
lineHeight: 1,
autoSize: false,
printHeaders: true
};
var doc = new jsPDF(l,'pt', 'letter');
doc.setProperties({
title: 'Test PDF Document',
subject: 'This is the subject',
author: 'author',
keywords: 'generated, javascript, web 2.0, ajax',
creator: 'author'
});
doc.cellInitialize();
$.each(table1, function (i, row)
{
rowCount++;
$.each(row, function (j, cellContent) {
if (rowCount == 1) {
doc.margins = 1;
doc.setFont("Times New Roman");
doc.setFontType("bold");
doc.setFontSize(11);
doc.cell(leftMargin, topMargin, cellWidth, headerRowHeight, cellContent, i)
}
else if (rowCount == 2) {
doc.margins = 1;
doc.setFont("Times ");
doc.setFontType("normal");
// or for normal font type use ------ doc.setFontType("normal");
doc.setFontSize(11);
doc.cell(leftMargin, topMargin, cellWidth, rowHeight, cellContent, i);
}
else {
doc.margins = 1;
doc.setFont("Times ");
doc.setFontType("normal ");
doc.setFontSize(11);
doc.cell(leftMargin, topMargin, cellWidth, rowHeight, cellContent, i);
// 1st=left margin 2nd parameter=top margin, 3rd=row cell width 4th=Row height
}
})
})
doc.save('sample Report.pdf');
});
function tableToJson(table) {
var data = [];
// first row needs to be headers
var headers = [];
for (var i=0; i<table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
}
// go through cells
for (var i=1; i<table.rows.length; i++) {
var tableRow = table.rows[i];
var rowData = {};
for (var j=0; j<tableRow.cells.length; j++) {
rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data;
}
</script>
Automatically not split data to multi pages. You may split manually.
If your ( rowCount * rowHeight ) > 420mm ( A3 Height in mm ) add new page function. ( Sorry I can't edit your code without run )
After add new page leftMargin, topMargin = 0; ( start over )
I added sample code with yours. I hope it's right.
else {
doc.margins = 1;
doc.setFont("Times ");
doc.setFontType("normal ");
doc.setFontSize(11);
if ( rowCount * rowHeight > 420 ) {
doc.addPage();
rowCount = 3; // skip 1 and 2 above
} else {
// now rowcount = 3 ( top of new page for 3 )
// j is your x axis cell index ( j start from 0 on $.each function ) or you can add cellCount like rowCount and replace with
// rowcount is your y axis cell index
left = ( ( j ) * ( cellWidth + leftMargin );
top = ( ( rowcount - 3 ) * ( rowHeight + topMargin );
doc.cell( leftMargin, top, cellWidth, rowHeight, cellContent, i);
// 1st=left margin 2nd parameter=top margin, 3rd=row cell width 4th=Row height
}
}
You can convert html directly to pdf lossless. Youtube video for html => pdf example
html2canvas(element[0], {
onrendered: function (canvas) {
pages = Math.ceil(element[0].clientHeight / 1450);
for (i = 0; i <= pages; i += 1) {
if (i > 0) {
pdf.addPage();
}
srcImg = canvas;
sX = 0;
sY = 1450 * i;
sWidth = 1100;
sHeight = 1450;
dX = 0;
dY = 0;
dWidth = 1100;
dHeight = 1450;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 1100);
onePageCanvas.setAttribute('height', 1450);
ctx = onePageCanvas.getContext('2d');
ctx.drawImage(srcImg, sX, sY, sWidth, sHeight, dX, dY, dWidth, dHeight);
canvasDataURL = onePageCanvas.toDataURL("image/png");
width = onePageCanvas.width;
height = onePageCanvas.clientHeight;
pdf.setPage(i + 1);
pdf.addImage(canvasDataURL, 'PNG', 35, 30, (width * 0.5), (height * 0.5));
}
pdf.save('testfilename.pdf');
}
});
var a = 0;
var d;
var increment;
for(n in array){
d = a++;
if(n % 6 === 0 && n != 0){
doc.addPage();
a = 1;
d = 0;
}
increment = d == 0 ? 10 : 50;
size = (d * increment) <= 0 ? 10 : d * increment;
doc.text(array[n], 10, size);
}