I am trying to dynamically get the height of a table in a PDF that I created using jsPDF and js Autotable. I want to add a line of text under the table, but since the table height changes, I can't put a specific Y value for the text line.
My current table script:
let col = ['Header 1', 'Header 2', 'Header 3']
let rows = arrayForTable;
let getTableWidth = 150;
let pageWidth = doc.internal.pageSize.width;
let tableMargin = (pageWidth - getTableWidth) / 2;
let height = 0;
doc.autoTable(col, rows, {
margin: {top: 20, right: tableMargin, left: tableMargin},
startY: 70,
styles: {
halign: 'center',
overflow: 'linebreak',
cellWidth: 'wrap',
valign: 'middle'
},
columnStyles: {
0: {cellWidth: 50},
1: {cellWidth: 50},
2: {cellWidth: 50},
},
headStyles: {
fillColor: [163, 32, 32]
},
didParseCell: function(data) {
if (data.row.index === rows.length - 1) {
data.cell.styles.fillColor = [63, 63, 64];
data.cell.styles.fontStyle = 'bold';
data.cell.styles.textColor = [255, 255, 255];
}
height = data.table.height
}
});
console.log(height)
The console prints undefined. Anyone know how to dynamically add a line of text under this table without having to designate a static Y value like this:
doc.text(25, 40, exampleText);
The table height changes every time because of different data being shown.
I am using jsPDF AutoTable plugin v3.5.6.
Get the cursor position on Y axis using
didDrawPage
which will be precisely after the table.
This worked for me in Angular 2:
let yPos = 0;
pdf.autoTable({
...
didDrawPage: function(data) {
yPos = data.cursor.y;
}
}
jspdf version:
"jspdf": "^2.3.1",
"jspdf-autotable": "^3.5.14",
Source:
Table height is always 0 #604
From what I understood, you want to add the text under the table. Instead of trying to read the table height, you can read the last cell Y position. What you need to do is like this
let height = 0;
....
didParseCell: function(data) {
...
height = data.cursor.y + data.row.height;
}
....
then you can adjust the position of the text you want to add, for the example I want to add 10 gap between the table and the text
doc.text("exampleText", 25, height + 10);
Related
I have a chart with some indicators below it. Each indicator area consists
of a svg renderer button. so when I use resize property to drag and resize
the panes, the series resized perfectly but the button remains in its same
position, Can we move the button with the resizer?
Here I created a sample link to regenerate
https://jsfiddle.net/q0ybpnvx/2/
Any help will be appreciated. I am having great trouble. Thank you
You can add and position the custom button in render event:
chart: {
events: {
render: function() {
var chart = this;
if (chart.customBtn) {
chart.customBtn.attr({
y: chart.yAxis[1].top,
});
} else {
chart.customBtn = chart.renderer.button(
'sometext',
5,
chart.yAxis[1].top,
function() {
console.log('some task')
}).add()
}
}
}
},
Live demo: https://jsfiddle.net/BlackLabel/b7vq4ecy/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I was able to do something by manually changing the x/y attributes of my svgRenderer label, the same should apply to buttons.
I'm in angular and have a listener for screen resizing:
Also Note that you can change the entire SVGRenderer label with the attr.text property.
this.chart = Highcharts.chart(.....);
// I used a helper method to create the label
this.chart.myLabel = this.labelCreationHelperMethod(this.chart, data);
this.windowEventService.resize$.subscribe(dimensions => {
if(dimensions.x < 500) { //this would be your charts resize breakpoint
// here I was using a specific chart series property to tell where to put my x coordinate,
// you can traverse through the chart object to find a similar number,
// or just use a hardcoded number
this.chart.myLabel.attr({ y: 15, x: this.chart.series[0].points[0].plotX + 20 });
} else {
this.chart.myLabel.attr({ y: 100, x: this.chart.series[0].points[0].plotX + 50 });
}
}
//Returns the label object that we keep a reference to in the chart object.
labelCreationHelperMethod() {
const y = screen.width > 500 ? 100 : 15;
const x = screen.width > 500 ? this.chart.series[0].points[0].plotX + 50 :
this.chart.series[0].points[0].plotX + 20
// your label
const label = `<div style="color: blue"...> My Label Stuff</div>`
return chart.renderer.label(label, x, y, 'callout', offset + chart.plotLeft, chart.plotTop + 80, true)
.attr({
fill: '#e8e8e8',
padding: 15,
r: 5,
zIndex: 6
})
.add();
}
I create some custom SVGElement labels in my chart.. but they loose positioning on zooming the chart.. See this fiddle https://jsfiddle.net/bz6vyedL/
chart:{zoomType: 'xy'},
Labels should not remain stuck when zooming in and behave appropriately
You need to reposition the label after every zoom, for example by using render event function:
chart: {
zoomType: 'xy',
events: {
render: function() {
var chart = this,
point = chart.series[0].points[8],
label = this.customLabel,
xPos,
labelWidth,
newLabelPos;
if (!label) {
this.customLabel = label = chart.renderer.label(
'Label',
null,
null,
'callout',
null,
null,
true, false, 'my-label'
)
.attr({
padding: 0,
zIndex: 10
})
.add();
}
label.attr({
x: point.plotX + chart.plotLeft,
y: point.plotY + chart.plotTop
});
xPos = label.x;
labelWidth = label.width;
newLabelPos = xPos - labelWidth;
label.attr('x', newLabelPos);
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/5v7xo2ky/
API Reference: https://api.highcharts.com/highcharts/chart.events.render
is there a way to change color of the plotline label when the movement goes up and change it again in different font color when movement goes down?
yAxis.addPlotLine({
value: 66,
color: 'red',
width: 2,
id: 'plot-line-1',
label: {
text: 66,
align: 'right',
style: {
color: 'red',
fontWeight: 'bold'
},
y: newY,
x: 0
}
});
Here is a working file http://jsfiddle.net/kttfv1h3/9/
thanks for the help
You can add css style options to your plotLabel like to a simple object; docs
var prev_val = 0; // global
plotlabel = yAxis.plotLinesAndBands[0].label;
if(prev_val <= y) {
plotlabel.css({'color':'blue'});
} else {
plotlabel.css({'color':'green'});
}
prev_val = y;
My jsFiddle: http://jsfiddle.net/kttfv1h3/12/
After playing around a bit with the different settings I found a way to achieve what you are seeking.
By delcaring a new variable oldY
And doing the following in setInterval, the label color changes depending on if the value is increasing or decreasing:
if(y < oldY) {
yAxis.plotLinesAndBands["0"].label.element.style.fill = 'red';
} else {
yAxis.plotLinesAndBands["0"].label.element.style.fill = 'green';
}
oldY = y;
See jsfiddle for a working example based on the one you supplied.
I want the grid lines of highchart to appear only till 75% of the chart height and rest of the chart should not show the grid lines. Is there a way to set the height of grid line?
xAxis: {
gridLineWidth: 1,
gridLineDashStyle: 'longdash',
gridLineColor: '#B3BABB',
}
In general, it is not supported, but simple change will allow you that: http://jsfiddle.net/ngk6vtbh/
(function(H) {
H.wrap(H.Tick.prototype, 'render', function(p, index, old, opacity) {
var tick = this,
d,
size = 0.25; // = 75%, 0.5 = 50%, 0.75 = 25% etc.
p.call(this, index, old, opacity);
if(tick.gridLine && this.axis.isXAxis) {
d = tick.gridLine.d.split(' '); // get default path
d[2] = ( d[5] - d[2] ) * size + tick.axis.chart.plotTop; // modify path - don't forget about plotTop
tick.gridLine.attr({
d: d // apply new path
});
}
});
})(Highcharts)
I have a problem with getting labels within a TableView to display correctly, and I hope someone can help.
Here is a screenshot of the problem:
The labels with the (...) behind them are cut off.
This problem does not occur when I set a fixed height to my rows, but since the text is of varying lengths, that's not a good solution for me.
I've tried the answers in this question, but to no avail.
Here is my code to generate the table:
var aSection = Ti.UI.createTableViewSection({
rows: [],
headerView: header
});
for (var p = 0; p < answers.length; p++){
var currentAnswer = answers[p];
var arow = Ti.UI.createTableViewRow({
selectedBackgroundColor:'#f5f5f5',
answID: currentAnswer['aId'],
map: currentAnswer['aMap'],
isSelected: false,
height: 'auto',
rightImage: '/images/icons/radio-unselected.png'
});
var atext = Ti.UI.createLabel({
font:{fontSize:gui.defaultFontSize+2, fontFamily: gui.defaultFont},
color: '#333',
text: currentAnswer['aText'],
left:10, top: 10, bottom: 10, right: 10,
width:'auto',
height: 'auto',
borderWidth: 0,
borderColor: "#000",
});
arow.add(atext);
aSection.add(arow);
}
var sections = [];
sections[0] = aSection;
var answView = Ti.UI.createTableView({
backgroundColor:'white',
data: sections,
bottom: 1,
minRowHeight: 40,
});
I'm really at a loss with this. Any pointers are appreciated.
If your text is too long then it overlaps the right side button but still you want to show full text then you should either set left & right or set width to Ti.UI.SIZE so If you want to overlaps right button then you should use Ti.UI.SIZE or not then you can set left & right
so in short, set width to Ti.UI.SIZE or set left and right property.
Use Ti.UI.SIZE for both height and width instead of auto, auto has been deprecated a long time ago. Something like this would help you
var aSection = Ti.UI.createTableViewSection({
rows: [],
headerView: header
});
for (var p = 0; p < answers.length; p++){
var currentAnswer = answers[p];
var arow = Ti.UI.createTableViewRow({
selectedBackgroundColor:'#f5f5f5',
answID: currentAnswer['aId'],
map: currentAnswer['aMap'],
isSelected: false,
height:Ti.UI.SIZE,
rightImage: '/images/icons/radio-unselected.png'
});
var atext = Ti.UI.createLabel({
font:{fontSize:gui.defaultFontSize+2, fontFamily: gui.defaultFont},
color: '#333',
text: currentAnswer['aText'],
left:10, right: 10,
width:Ti.UI.SIZE,
height:Ti.UI.SIZE,
borderWidth: 0,
borderColor: "#000",
});
arow.add(atext);
aSection.add(arow);
}
var sections = [];
sections[0] = aSection;
var answView = Ti.UI.createTableView({
backgroundColor:'white',
data: sections,
bottom: 1,
minRowHeight: 40,
});
Try using: minimumFontSize:'18sp'
Or some size that suits your display needs. This will shrink the font down to the minimum size to fit everything.