I have been using this plugin for data table and exporting Excel and PDF files. My problem comes with PDF file export, I want to add two images on header page side by side but the only result that I got is an image in a row and the other on the next line, this is part of my code:
customize: function (doc) {
if (doc) {
doc.content.splice(0, 0, [{
margin: [0, 0, 0, 0],
alignment: 'left',
image: 'base64_Image',
width: 100,
height: 40,
},{
margin: [0, 0, 0, 0],
alignment: 'right',
image: 'base64_Image',
width: 100,
height: 40,
}]);
console.log(doc);
}
}
and this is the result:
Regards
To add an image to the header as you want, I suggest you do the following:
Add pageMargins attribute to doc
Use the header attribute of doc to add an image.
2 images side by side
customize: function (doc) {
doc.pageMargins = [40, 80, 40, 60]
doc.header = [
{
margin: 10,
columns: [
{
image: 'base64_Image',
width: 100,
height: 40,
padding: 10
},
{
image: 'base64_Image',
width: 100,
height: 40,
}
],
columnGap: 10 // optional space between columns
},
]
return doc
}
If you want an image on the left and an image on the right of the header, you just need to add adjust value of columns attribute in header. Try like this:
customize: function (doc) {
...
doc.header = [
{
...
columns: [
{
image: imageBase64,
width: 100,
height: 40,
padding: 10
},
{
width: '*',
text: ''
},
{
image: imageBase64,
width: 100,
height: 40,
}
],
},
]
}
Sample code here
Related
There are graphics data for which it was necessary to make the appearance of the plate when choosing an item. But the standard function does not support the title of the table in html format, although the title of the chart supports it normally. I did it by adding a new button to the menu, through menuItemDefinitions inside exporting, but how to overwrite its text after selection? It is necessary that, as with the standard output, it was. Changed View data table to Hide data table and vice versa. The code that i have now and the photo as i would like are given below:
var html = '<div style="display: inline-block"></div>';
html += '<div style="display: inline-block; margin-left: 20px; cursor: pointer;" class="description-title" id="">';
html += '<img style="width: 20px;" src="https://img.icons8.com/ios/500/info--v1.png" alt="Info">';
html += '</div>';
new Highcharts.Chart({
chart: {
renderTo: 'chart_1',
type: 'column',
height: 350,
},
title: {
text: html,
useHTML: true,
},
xAxis: {
categories: ['Processing.js', 'Impact.js', 'Other', 'Ease.js', 'Box2D.js', 'WebGL', 'DOM', 'CSS', 'Canvas', 'Javascript']
},
yAxis: {
title: {
text: 'Asked'
}
},
series: [{
name: 'Dev #1',
data: [5, 10, 20, 22, 25, 28, 30, 40, 80, 90],
color: '#FF0000',
states: {
inactive: {
enabled: false
}
}
}, {
name: 'Dev #2',
data: [15, 15, 18, 40, 30, 25, 60, 60, 80, 70],
states: {
inactive: {
enabled: false
}
}
}, {
name: 'Dev #3',
data: [1, 3, 6, 0, 50, 25, 50, 60, 30, 100]
}],
exporting: {
menuItemDefinitions: {
// Custom definition
label: {
onclick: function() {
if (this.dataTableDiv && this.dataTableDiv.style.display !== 'none') {
this.text = "View data table";// Assigned but not displayed in the menu
this.dataTableDiv.style.display = 'none';
this.dataTableDiv.querySelector(".highcharts-table-caption").innerHTML = html;
} else {
this.viewData();
this.text = "Hide data table";// Assigned but not displayed in the menu
this.dataTableDiv.style.display = '';
this.dataTableDiv.querySelector(".highcharts-table-caption").innerHTML = html;
}
},
text:"View data table",
}
},
buttons: {
contextButton: {
menuItems: ["viewFullscreen", "printChart", "separator", "downloadPNG", "downloadJPEG", "downloadPDF", "downloadSVG", "separator", "downloadCSV", "downloadXLS", 'label']
}
}
}
});
.actions, .chart {
margin: 15px auto;
width: 820px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/accessibility.js"></script>
<div id="chart_1" class="chart"></div>
And the solution was easier than I thought. Just instead this.text = "Hide data table"; should have written:
document.getElementsByClassName("highcharts-menu-item")[8].innerHTML = "Hide/View data table";
What solved the problem
It looks like the text inside the button is implemented, it changes the name when you hide the table to show table and vice versa, when you add:
exporting: {
showTable: true,
},
Demo: http://jsfiddle.net/BlackLabel/9musLgp2/
Using pdfmake.js to generate pdf in javascript. But it generates a blank document if the content is too large. Used the html2canvas to create the canvas and created the pdf using this. How can resolve this issue??
self.exportAsCanvas = function (contentObject, fileName, heading) {
var useWidth = $(contentObject)[0].offsetWidth;
var useHeight = $(contentObject)[0].offsetHeight;
//var graphContent = angular.element(contentObject).find('.graph-content');
html2canvas(contentObject, {
onrendered: function (canvas) {
document.body.appendChild(canvas);
var data = canvas.toDataURL();
var docDefinition = {
header: { text: heading, style: 'header' },
footer: {
columns: [
{ text: 'Copyright © 2015 H&R Block. All Rights Reserved.', alignment: 'center',fontSize: 11 }
]
},
pageOrientation: self.pageOrientation,
content: [{
image: data,
fit: [1000, 1100]
//width: 500,
//height:1100
}],
styles: {
header: {
fontSize: 14,
bold: true,
alignment: 'center',
margin: [0, 10, 0, 10]
}
}
};
pdfMake.createPdf(docDefinition).download(fileName + ".pdf");
},
width: useWidth,
height: useHeight
});
};
You should try implementing a page break:
var docDefinition = {
header: { text: heading, style: 'header' },
footer: {
columns: [
{ text: 'Copyright © 2015 H&R Block. All Rights Reserved.', alignment: 'center',fontSize: 11 }
]
},
pageOrientation: self.pageOrientation,
content: [{
image: data,
fit: [1000, 1100],
pageBreak: 'after', //PAGE BREAK
//width: 500,
//height:1100
}],
styles: {
header: {
fontSize: 14,
bold: true,
alignment: 'center',
margin: [0, 10, 0, 10]
}
}
};
In stencils we have png, on drop to paper we replace cell[png] with svg.
cell - represents png
vectorString - markup of png
var currentSvg = new joint.shapes.basic.pwmeter({
position: { x: bbox.x, y: bbox.y },
size: { height: cell.attributes.minHeight, width: cell.attributes.minWidth },
minWidth: cell.attributes.minWidth,
minHeight: cell.attributes.minHeight,
markup: vectorString,
type: cell.attributes.type,
fileName: cell.attributes.fileName,
isInteractive: true,
elementClassName: cell.attributes.elementClassName,
isAnimatedDevice: cell.attributes.isAnimatedDevice,
attrs: {
'.myClass': {
fill: '#ffffff',
stroke: '#000000'
}
}
});
currentSvg.addTo(Rappid.graph);
we are making pwmeter by extending Image
joint.shapes.basic.pwmeter = joint.shapes.basic.Image.extend({
type: 'basic.pwmeter',
initialize: function () {
return joint.shapes.basic.Image.prototype.initialize.apply(this, arguments);
}
});
We drop png from stencils to paper, and get svg markup for corresponding png,
we call currentSvg.addTo(Rappid.graph), during execution of this, all text in meter [svg] are replaced by blank.
our text - 0
auto generated code replaces my text, we are not able to figure out why this is happening
-
above is the generated text
We are new to jointjs, we think we are doing something wrong during extending.
I can see there is a markup in you settings. Make sure there is a text 'placeholder' in the markup.
in this example attr text is tied with the <text/> element
new joint.shapes.basic.pwmeter({
markup: '<g><image/><text/></g>',
attrs: {
text: { text: '48x48' },
image: { 'xlink:href': 'http://placehold.it/48x48', width: 48, height: 48 }
},
size: { width : 50, height: 50 },
position: { x:200, y: 50},
}).addTo(graph)
but in here, attr text has no matching element in the markup, therefore it won't be rendered.
new joint.shapes.basic.pwmeter({
markup: '<g><image/></g>',
attrs: {
text: { text: '90x90' },
image: { 'xlink:href': 'http://placehold.it/90x90', width: 90, height: 90 }
},
size: { width : 90, height: 90 },
position: { x:50, y: 50},
}).addTo(graph)
more information about attr property could be found here http://resources.jointjs.com/docs/jointjs/v1.0/joint.html#joint.dia.Element.presentation
I'm trying to create graph using JointJS, where Link starts from output port od 1 element and can be connected with whole other element (or current element itself) - not only with input port.
My idea is to modify input port style, to cover element it belongs to, but I have problems to change port shape in any way, it's always a little circle on left side of element and none of my css works.
Can someone give any advice?
you can update the port attrib0utes as follows:
var a = new joint.shapes.devs.Model({
position: { x: 50, y: 50 },
size: { width: 100, height: 100 },
attrs: {
'.port-label': {
fill: 'red'
},
// change position and size of the 'a' port
'.inPorts .port0 circle': {
r: 15,
'ref-x': -20,
'ref-y': 10,
stroke: 'red',
'stroke-width': 5
},
// change color on a single port
'.inPorts .port0 .port-label': {
fill: 'blue',
}
},
inPorts: ['a', 'aa', 'aaa'],
outPorts: ['b']
https://jsfiddle.net/vtalas/43sthc6g/
However, you don't need to use ports to achieve this, you can connect to the whole element directly like this:
var a = new joint.shapes.basic.Rect({
size: { width: 100, height: 100 },
position: { x: 300, y: 300 },
attrs: {
'rect': { magnet: true }
}
}).addTo(graph);
var b = new joint.shapes.basic.Rect({
size: { width: 100, height: 100 },
position: { x: 100, y: 100 },
attrs: {
'rect': { magnet: true }
}
}).addTo(graph);
new joint.dia.Link({ source: { id: b.id }, target: { id: a.id } }).addTo(graph);
result: https://jsfiddle.net/vtalas/davLzsng/
I am trying to increase the header size on a pdf using pdfmake.
Currently am able to get a header on both the left and right of the page, which is what I want, but when the height passes 26, the image disappears because there is a limited amount of space for the header.
The margin can be decreased to increase the size but i want the
margin to remain.
I've searched pdfMake github for similar issues with no success.
If you need to test anything, try the code I have so far on
pdfmake playground
Keep in mind you will need to copy and paste all this code on the "playground" to make it work.
var dd = {
pageSize: 'LEGAL',
pageOrientation: 'landscape',
header: {
margin: 8,
columns: [{
table: {
widths: ['50%', '50%'],
body: [
[{
image: 'sampleImage.jpg',
width: 80,
height: 26,
}, {
image: 'sampleImage.jpg',
width: 80,
height: 26,
alignment: 'right'
}]
]
},
layout: 'noBorders'
}]
},
content: [
'First paragraph',
'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
]
}
You need to add a pageMargins and adjust the second parameter (top margin) to your total header size. You can try values until you get all header content visible.
For example:
In this case, I use 80 (pageMargin: [40,80,40,60]) to get the image with height 60
var dd = {
pageSize: 'LEGAL',
pageOrientation: 'landscape',
pageMargins: [40, 80, 40, 60],
header: {
margin: 8,
columns: [
{
table: {
widths: [ '50%','50%'],
body: [
[
{ image: 'sampleImage.jpg',
width: 80, height: 60,
},
{ image: 'sampleImage.jpg',
width: 80, height: 60,
alignment:'right'}
]
]
},
layout: 'noBorders'
}
]
},
content: [
'First paragraph',
'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
]
}
The accepted answer for this is a good one, but I thought since I found one I believe might work better for others, especially if header content length may vary, I would share.
Tables in pdfmake have a nifty feature where the header row(s) are repeated on each page the table spans. So, you can create a table that wraps your entire document, and add as many header rows as you would like, and they will be sticky throughout all pages. Here's an example doc def.
var docDefinition = {
pageSize : 'LETTER',
pageMargins : [25, 25, 25, 35],
defaultStyle : {
fontSize : 12,
columnGap : 20
},
// Page Layout
content : {
// This table will contain ALL content
table : {
// Defining the top 2 rows as the "sticky" header rows
headerRows: 2,
// One column, full width
widths: ['*'],
body: [
// Header Row One
// An array with just one "cell"
[
// Just because I only have one cell, doesn't mean I can't have
// multiple columns!
{
columns : [
{
width : '*',
text : 'Delivery Company, Inc.',
fontSize : 12,
bold : true
},
{
width : '*',
text : [
{ text: 'Delivery Slip\n', fontSize: 12 },
{ text: 'Date ', bold: true },
'2/16/2015 ',
{ text: 'Arrived ', bold: true },
'11:05 AM ',
{ text: 'Left ', bold: true },
'11:21 AM'
],
fontSize : 10,
alignment : 'right'
}
]
}
],
// Second Header Row
[
{
columns: [
{
width: 'auto',
margin: [0,0,10,0],
text: [
{ text: 'CUSTOMER\n', fontSize: 8, bold: true, color: '#bbbbbb' },
{ text: 'John Doe', fontSize: 12 }
]
},
{
width: 'auto',
margin: [0,0,10,0],
text: [
{ text: 'INVOICE #\n', fontSize: 8, bold: true, color: '#bbbbbb' },
{ text: '123456', fontSize: 12 }
]
}
]
}
],
// Now you can break your content out into the remaining rows.
// Or you could have one row with one cell that contains
// all of your content
// Content Row(s)
[{
fontSize: 10,
stack: [
// Content
{ text:'this is content', pageBreak: 'after' },
{ text:'this is more content', pageBreak: 'after' },
{ text:'this is third page content' }
]
}],
[{
fontSize: 10,
stack: [
// Content
{ text:'this is content', pageBreak: 'after' },
{ text:'this is more content', pageBreak: 'after' },
{ text:'this is third page content' }
]
}]
]
},
// Table Styles
layout: {
hLineWidth: function(i, node) { return (i === 1 || i === 2) ? 1 : 0; },
vLineWidth: function(i, node) { return 0; },
hLineColor: function(i, node) { return (i === 1 || i === 2) ? '#eeeeee' : 'white'; },
vLineColor: function(i, node) { return 'white' },
paddingBottom: function(i, node) {
switch (i) {
case 0:
return 5;
case 1:
return 2;
default:
return 0;
}
},
paddingTop: function(i, node) {
switch (i) {
case 0:
return 0;
case 1:
return 2;
default:
return 10;
}
}
}
},
// Page Footer
footer : function(currentPage, pageCount) {
return {
alignment : 'center',
text : currentPage.toString() + ' of ' + pageCount,
fontSize : 8
}
},
};