i am using FPDF for generating pdf file from PHP. but one difficulty i face is when the file is large it will overlay on footer content and the next page on header content. i need help.
class PDF extends FPDF {
// Page header
function Header() {
// Logo
$this->Image('custom/pics/logoo.png', 8, 15, 20);
// Arial bold 15
$this->SetFont('Arial', 'B', 15);
// Move to the right
$this->Cell(30);
// Title
$this->Cell(30, 20, 'Payment Request', 0, 0, 'C');
// Line break
$this->Ln(20);
}
// Page footer
function Footer() {
// Position at 1.5 cm from bottom
$this->SetY(-25);
// Arial italic 8
$this->SetFont('Arial', '', 6);
// Page number
$this->Cell(0, 3, 'Price Quoted: ETB including VAT', 0, 1, 'L');
$this->Cell(0, 3, 'Delivery Period: Already installed and configured.', 0, 1, 'L');
$this->Cell(0, 3, 'Remarks: Make all checks payable to Mella COMMUNICATION TECHNOLOGY PLC', 0, 1, 'L');
$this->SetFont('Arial', 'I', 8);
$this->Cell(0, 3, 'THANK YOU FOR YOUR BUSINESS!', 0, 0, 'C');
$this->Cell(0, 3, 'Page ' . $this->PageNo() . '/{nb}', 0, 0, 'R');
}
}
// Instanciation of inherited class
$pdf = new PDF();
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetFillColor(176, 179, 177);
$pdf->SetFont('Arial', '', 8);
//Installed Vehicle list with details
if (isset($_POST["device_pdf"])) {
$for = count($_POST["device_pdf"]);
$item_no += 1;
$pdf->SetFont('Arial', 'B', 8);
$pdf->Cell(70, 7, $item_no . '. Device Purchase', 'L,R', 0, 'L');
$pdf->Cell(25, 7, "", 'L,R', 0);
$pdf->Cell(30, 7, "", 'L,R', 0);
$pdf->Cell(25, 7, "", 'L,R', 0);
$pdf->Cell(40, 7, "", 'L,R', 1);
$pdf->SetFont('Arial', '', 7);
}
}
this is just a snippet from the overall code.
Related
GitHub automatically generates meta tag image for each repository with dynamic content if user doesn't provide any thumbnail image.
eg:
<meta property="og:image" content="https://opengraph.githubassets.com/6fa26478850d4904c9e8567353350c87f35c71f7232cce8eec1d44e3ba1ca9a3/e-labInnovations/qr-code-speech">
This is the meta image for one of my repository https://github.com/e-labInnovations/qr-code-speech
I want impliment this feature on my wordpress. Generate dynamic png image contain post title, date, author name, and author avatar image.
Is it possible in WordPress?
If yes, then how?
function.php
<?php
add_action( 'init', function() {
add_rewrite_rule( 'ashad-thumbnail/([a-z0-9-]+)[/]?$', 'index.php?ashad-thumbnail=$matches[1]', 'top' );
} );
add_filter( 'query_vars', function( $query_vars ) {
$query_vars[] = 'ashad-thumbnail';
return $query_vars;
} );
add_action( 'template_include', function( $template ) {
if ( get_query_var( 'ashad-thumbnail' ) == false || get_query_var( 'ashad-thumbnail' ) == '' ) {
return $template;
}
return get_template_directory() . '/templates/ashad-thumbnail.php';
} );
?>
ashad-thumbnail.php
<?php
//setting content type as png
header ('Content-Type: image/png');
//create image object
$img = imagecreatetruecolor(1200, 600)
or die('Cannot Initialize new GD image stream');
//Colors
$background_color = imagecolorallocate($img, 255, 255, 255);
$color_primary = imagecolorallocate($img, 50, 50, 50);
$color_secondary = imagecolorallocate($img, 100, 100, 100);
$post_id = get_query_var('ashad-thumbnail');
//setting background color
imagefill($img, 0, 0, $background_color);
//getting author name using author_id
$author_id = get_post_field ('post_author', $post_id);
$display_name = get_the_author_meta( 'display_name' , $author_id );
// $text = "Post Id: " . get_query_var( 'ashad-thumbnail' ) . get_comments_number($post_id);
// imagestring($img, 5, 10, 10, $text, $color_primary);
//loading ttf fonts
$fontSemiBold = get_stylesheet_directory() . '/assets/fonts/TitilliumWeb-SemiBold.ttf';
$fontRegular = get_stylesheet_directory() . '/assets/fonts/TitilliumWeb-Regular.ttf';
//creating icon image objects
$icon_calendar = imagecreatefrompng(get_stylesheet_directory() . '/assets/img/icon_calendar.png');
$icon_comments = imagecreatefrompng(get_stylesheet_directory() . '/assets/img/icon_comments.png');
//creating site icon(favicon) image object
$site_icon = imagecreatefrompng(get_site_icon_url(200));
//getting title
$title = get_the_title(get_query_var( 'ashad-thumbnail' )) ? get_the_title($post_id) : 'Error';
if(strlen($title) > 21) {
$titleArray = explode("\n", wordwrap( $title, 26));
$titleL1 = $titleArray[0];
if($titleArray[1]) {
if($titleArray[2]) {
$titleL2 = $titleArray[1] . '...';
} else {
$titleL2 = $titleArray[1];
}
} else {
$titleL2 = flase;
}
} else {
$titleL1 = $title;
}
$fsize = 48;
//showing title line 1 and 2
imagettftext($img, $fsize, 0, 80, 140, $color_primary, $fontSemiBold, $titleL1);
if($titleL2) {
imagettftext($img, $fsize, 0, 80, 210, $color_primary, $fontSemiBold, $titleL2);
}
//showing author name
if($display_name) {
imagettftext($img, 26, 0, 80, 295, $color_secondary, $fontRegular, 'By ' . $display_name);
}
//showing site_icon
imagecopyresized($img, $site_icon, 922, 80, 0, 0, 200, 200, 200, 200);
//showing date icon and date
imagecopyresized($img, $icon_calendar, 80, 450, 0, 0, 32, 32, 16, 16);
imagettftext($img, 26, 0, 130, 478, $color_primary, $fontRegular, get_the_date('F j, Y', $post_id));
//showing a circle and post type label
imagearc($img, 550, 465, 32, 32, 0, 360, $color_primary);
imagettftext($img, 26, 0, 580, 478, $color_primary, $fontRegular, get_post_type_object(get_post_type($post_id))->labels->singular_name);
//showing comments icon and count
imagecopyresized($img, $icon_comments, 900, 450, 0, 0, 32, 32, 16, 16);
imagettftext($img, 26, 0, 950, 478, $color_primary, $fontRegular, get_comments_number($post_id));
imagepng($img);
imagedestroy($img);
?>
For getting this thumbnail image use example.com/ashad-thumbnail/:post_id. Replace post_id with real post id
Example image
Note
I used two google fonts as ttf format.
I am trying to place the "Registration form" text at the top but when I do pane.add it separates the spacing between the labels and textfield boxes. How do I add it to the top without it affecting everything below it?
public class RegistrationForm extends Application {
public void start(Stage primaryStage) {
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setPadding(new Insets(11.5, 12.5, 13.5, 14.5));
pane.setHgap(5.5);
pane.setVgap(5.5);
Text text = new Text ("Registration Form");
text.setFont(Font.font("Times New Roman", FontWeight.BOLD,
FontPosture.ITALIC, 20));
pane.getChildren().add(text);
pane.add(new Label("User Name: "), 0, 1);
pane.add(new TextField(), 1, 1);
pane.add(new Label("Password: "), 0, 2);
pane.add(new TextField(), 1, 2);
pane.add(new Label("Email: "), 0, 3);
pane.add(new TextField(), 1, 3);
pane.add(new Label("Phone: "), 0, 4);
pane.add(new TextField(), 1, 4);
Button btReg = new Button("Register");
pane.add(btReg, 0, 5);
GridPane.setHalignment(btReg, HPos.LEFT);
Button btCan = new Button("Cancel");
pane.add(btCan, 1, 5);
GridPane.setHalignment(btCan, HPos.LEFT);
Scene scene = new Scene(pane);
primaryStage.setTitle("Registration Form");
primaryStage.setScene(scene);
primaryStage.show();
}
}
In the Docs
add(Node child, int columnIndex, int rowIndex, int colspan, int
rowspan) Adds a child to the gridpane at the specified column,row
position and spans.
You should use:
pane.add(label, 0, 0, 2, 1);
I am currently working for my school project and using Meteor with AngularJs 1 and ES6. In one of my views I try to update some live data (with AngularCharts) every second which are currently randomly generated. I am new to the way of how Meteor and ES6 works, so I think a have a pretty easy error.
This is my code of the class from the view:
class View2 {
constructor($interval, $scope) {
'ngInject';
this.cardRow = [
{name: 'Drilling Heat', color: 'white', value: 0},
{name: 'Drilling Speed', color: 'white', value: 0},
{name: 'Milling Heat', color: 'white', value: 0},
{name: 'Milling Speed', color: 'white', value: 0}
];
this.type = ['bar', 'line', 'pie', 'doughnut', 'radar'];
this.chartRow = [
{
name: 'Chart1',
type: 'bar',
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
series: ['Series A'],
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
datasetOverride: [{yAxisID: 'y-axis-1'}],
options: {
animation: false,
scales: {
yAxes: [
{
id: 'y-axis-1',
type: 'linear',
display: true,
position: 'left'
}]
}
}
},
{
name: 'Chart2',
type: 'line',
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
series: ['Series A'],
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
datasetOverride: [{yAxisID: 'y-axis-1'}],
options: {
animation: false,
scales: {
yAxes: [
{
id: 'y-axis-1',
type: 'linear',
display: true,
position: 'left'
}]
}
}
}
];
$interval(this.update, 1000);
}
update() {
for (var i = 0; i < this.cardRow.length; i++) {
this.cardRow[i].value = Math.round((Math.random() * 10) * 10);
var value = this.cardRow[i].value;
switch (true) {
case (value > 80):
this.cardRow[i].color = 'red';
break;
case (value > 60):
this.cardRow[i].color = 'orange';
break;
case (value > 40):
this.cardRow[i].color = 'yellow';
break;
default:
this.cardRow[i].color = 'green';
break;
}
}
for (var y = 0; y < this.chartRow.length; y++) {
for (var z = 0; z < this.chartRow[y].data.length; z++) {
this.chartRow[y].data[z] = this.chartRow[y].data[z + 1];
}
this.chartRow[y].data[z - 1] = Math.round((Math.random() * 10) * 10);
}
}
}
The $interval should call the function "update" every second but then the variable is unknown. it throws an error like this:
TypeError: Cannot read property 'length' of undefined
at update (view2.js:74)
at callback (modules.js?hash=7db65c4…:46346)
at Scope.$eval (modules.js?hash=7db65c4…:51381)
at Scope.$digest (modules.js?hash=7db65c4…:51194)
at Scope.$apply (modules.js?hash=7db65c4…:51489)
at tick (modules.js?hash=7db65c4…:46336)
What can I do to solve this problem? And is there a way to use Meteor with the old Javascript Version?
the inner shadow disappears during the transition it looks like the inner shadow is also scaled.
public void showTowerRange(int x0, int y0, double range) {
Circle circle = new Circle(
x0 * MAP_CELLS_WIDTH + MAP_CELLS_WIDTH / 2,
y0 * MAP_CELLS_HEIGHT + MAP_CELLS_HEIGHT / 2,
1,
Color.RED
);
circle.setOpacity(0.5);
gameRoot.getChildren().add(circle);
ScaleTransition scl = new ScaleTransition(Duration.millis(SHOW_RANGE_EFFECT_DURATION),circle);
scl.setByX(range * MAP_CELLS_WIDTH);
scl.setByY(range * MAP_CELLS_HEIGHT);
FadeTransition fd = new FadeTransition(Duration.millis(SHOW_RANGE_EFFECT_DURATION),circle);
fd.setByValue(-.3);
circle.setEffect(new InnerShadow(BlurType.GAUSSIAN, Color.GREEN, 4, 1, 0, 0));
circle.setEffect(new DropShadow(BlurType.GAUSSIAN, Color.WHITE, 2, 0, 0, 0));
ParallelTransition prl = new ParallelTransition(scl,fd);
prl.play();
}
Well, I have good news and bad news for you. The good one - scale transition does not ruin inner shadow. The bad one - it is you ruining inner shadow:)
The point is, setEffect() method does not add another effect, it just set effect property of the Node, replacing previous value. What you need to do is to chain you effects (see example here). So instead of this:
circle.setEffect(new InnerShadow(BlurType.GAUSSIAN, Color.GREEN, 4, 1, 0, 0));
circle.setEffect(new DropShadow(BlurType.GAUSSIAN, Color.WHITE, 2, 0, 0, 0));
You must do this:
InnerShadow is = new InnerShadow(BlurType.GAUSSIAN, Color.GREEN, 4, 1, 0, 0);
DropShadow ds = new DropShadow(BlurType.GAUSSIAN, Color.WHITE, 2, 0, 0, 0);
ds.setInput(is);
circle.setEffect(ds);
I need to add one vertical line in current year (x axis)
Configuration Options in my code follows.
var options = {
title: '*****',
curveType: 'function',
height: 300,
legend: { position: 'bottom' },
chartArea: {width: '80%'},
pointSize:5,
width: 500,
annotation: {
1: {
style: 'line'
}
}
}
Please note I have used annotation for this, but problem is a bit line alone visible. I need a line for full height .
My Full Code :
var options = {
title: 'Chart',
curveType: 'function',
height: 300,
legend: { position: 'bottom' },
chartArea: {width: '80%'},
pointSize:5,
annotation: { height: 300 }
},
chartData = JSON.parse(window._data.chartData), chartPoint = new Array(), i = 0, j = 0;
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Google');
data.addColumn('number', 'Yahoo');
data.addColumn({type: 'boolean', role: 'certainty'});
data.addColumn('number', 'Value');
data.addColumn({type: 'boolean', role: 'certainty'});
data.addColumn({type: 'string', role: 'annotation'});
if(Object.keys(chartData.myMap).length > 0) {
$.each(chartData.myMap, function(k, v) {
var val = Math.round(v * 100) / 100;
chartPoint[i] = new Array();
var cDate = new Date();
if(cDate.getFullYear()==k)
chartPoint[i] = [k, val, null, false, null, false,k];
else
chartPoint[i] = [k, val, null, false, null, false,null];
i++;
});
i--;
}
if(Object.keys(chartData.myDataMap).length > 0) {
$.each(chartData.myDataMap, function(k, v) {
var val = Math.round(v * 100) / 100;
var val1 = Math.round(chartData.averageMap[k] * 100) / 100;
if(j==0) {var l = val; j++; } else l = null;
chartPoint[i] = new Array();
chartPoint[i] = [k,l,val,false,val1, false, null];
i++;
});
}
data.addRows(chartPoint);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
It should be like in this page [http://jsfiddle.net/NC37X/][3]
I have three forks from your fiddle that might be along the lines of what you are looking for:
data.addRow(["G", ' ', 'Foo annotation', 8, 1, 0.5]);
http://jsfiddle.net/Balrog30/W2JWa/1/ -
Using annotations, but just placing a space makes nothing print, but still draws a line.
annotations: {
style: 'line',
textStyle: {
opacity: 0
}
}
http://jsfiddle.net/Balrog30/W2JWa/2/ -
Text is still in annotation, but text opacity set to 0 so that text is totally transparent.
google.load('visualization', '1', {packages: ['corechart']});
google.setOnLoadCallback(drawVisualization);
function drawVisualization() {
// example copied from Google Visualization API playground,
// modified for category axis annotations
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn({type: 'string', role: 'annotationText'});
data.addColumn('number', 'Cats');
data.addColumn('number', 'Blanket 1');
data.addColumn('number', 'Blanket 2');
data.addRow([{v: 0, f:"A"}, null, null, 1, 1, 0.5]);
data.addRow([{v: 1, f:"B"}, null, null, 2, 0.5, 1]);
data.addRow([{v: 2, f:"C"}, null, null, 4, 1, 0.5]);
data.addRow([{v: 3, f:"D"}, null, null, 8, 0.5, 1]);
data.addRow([{v: 4, f:"E"}, null, null, 7, 1, 0.5]);
data.addRow([{v: 5, f:"F"}, null, null, 7, 0.5, 1]);
data.addRow([{v: 6, f:"G"}, null, null, 8, 1, 0.5]);
data.addRow([{v: 7, f:"H"}, null, null, 4, 0.5, 1]);
data.addRow([{v: 8, f:"I"}, null, null, 2, 1, 0.5]);
data.addRow([{v: 9, f:"J"}, null, null, 3.5, 0.5, 1]);
data.addRow([{v: 10, f:"K"}, null, null, 3, 1, 0.5]);
data.addRow([{v: 11, f:"L"}, null, null, 3.5, 0.5, 1]);
data.addRow([{v: 12, f:"M"}, null, null, 1, 1, 0.5]);
data.addRow([{v: 13, f:"N"}, null, null, 1, 0.5, 1]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {
curveType: 'function',
width: 500,
hAxis: {
ticks: [{v:6, f:"G"}, {v:10, f:"K"}]
},
height: 400,
vAxis: {
maxValue: 10
},
annotations: {
style: 'line'
}
});
}
http://jsfiddle.net/Balrog30/W2JWa/3/ -
The third one changes the horizontal axis to a continuous type axis so that I can add ticks. This only works if your x-axis is numberic or date/time in nature. This also kind of messes up your axis labeling because the labeling is tied to the ticks, but I'm not really sure what you're trying to display, so it may or may not matter to you.