This is in continuation to the question asked in github, Fit a wider table into PDF #261.
I'm reusing the same method(doc.autoTable) to create PDF out of different HTML inputs.
So, If I define the column style of 0th column as columnWidth: 'wrap', then the same style will be applied for all the HTML tables that invoke this particular method.
I'm not sure If I can follow long text example, as both the column names & table body are coming from HTML page directly. Whereas in the long text example, I'm seeing the column names being declared/defined as shown below
var columnsLong = getColumns().concat([
{title: "Title with\nlinebreak", dataKey: "text2"},
{title: "Long text column", dataKey: "text"},
]);
Now there are 2 questions.
1. I dont want to apply 'WRAP' for all the columns, as the table gets cut.
2. Need to apply 'wrap' for certain columns alone by mentioning the column name that comes from HTML/GSP page.
This is my code
var res = doc.autoTableHtmlToJson($(".printReportsCaveat")[0]);
doc.autoTable(res.columns, res.data, {
columnStyles : {'Plant':{columnWidth: 'wrap'},
'Mine':{columnWidth: 'wrap'},
0:{textColor: [0,105,170]}
},
margin: {top: 55, bottom : 110},
headerStyles: {
overflow: 'linebreak',
// columnWidth: 'auto',
halign: 'center'
},
styles : {
overflow: 'linebreak',
halign: 'center',
fontSize: 8
},
createdCell: function(cell, data) {
var group = $('#groupByValue').val();
addColorToCell(group, level3Flag, level2Flag, data, cell);
},
addPageContent : function(data) {
printHeadNFoot(doc, userDtl, data);
},
drawCell: function(cell, data) {
designCell(data,doc);
},
});
Kindly help!
If I understand your issue correctly you can try referencing a specific column by index instead of by key. I.e. columnWidth: {0: columnWidth: 'wrap'}.
Related
I want to have a text s.calculatedQuantity and next to it an icon. But i want them to be always next to each other and not be separated. Sometimes when s.setDescription is long i have a bad result like in the image below. And i dont know why there is sometimes that space between the icon and the text s.calculatedQuantity. Can someone explain to me that ?
.
I Have my code like this :
function generateSetDescription(s, picto) {
return {
columns: [
{
text: `${s.setDescription} - `,
fillColor: '#000',
color: '#FFF'
},
{
text: `${s.calculatedQuantity}`,
fillColor: '#000',
color: '#FFF'
},
{
image: icon,
width: 10,
height: 10,
fillColor: '#000',
},
]
}
}
The problem you're having seems to be caused by too long words (not text) normal text seems to wrap correctly when a blank space is found.
My suggestion is to programmatically break your 'very long words' adding a - in between.
something like this should work in your case
const text = veryLongTextWithLongWords;
const wrappedText = text.split(' ').map(word => {
if(word.length > 80){
return `${word.substr(0, 40)}-${word.substr(41)}
}
return word;
})
const columns = [
{ text: wrappedText }
]
You can test it out here
http://pdfmake.org/playground.html
I am having this code: https://jsfiddle.net/delux123/dk9zbsc1/5/ where I successfully can change the label's related colors and the font.
What I am missing is, I want to be able to update the text of the label itself.
I tried this with the code:
// Update the label
thischart.currentAnnotation.update({
labels: [{
text: fontText, //this line is not working
backgroundColor: fontBackgroundColor,
style: {
fontSize: fontSzie,
color: fontColor
}
}]
});
And also I tried with the code:
thischart.currentAnnotation.labels[0].update({
text: fontText
});
And a few more combinations which I found in similar threads (including the attr property), but none of them were working.
So I wonder, how can I update the text dynamically?
The problem results from the fact that you have used format property in the label creation process and update text property. Text is overwritten by format.
var onclick = function() {
_self.chart.addAnnotation(Highcharts.merge({
langKey: 'label',
labelOptions: {
// format: labelTextForm.querySelector('#labelTextInput').value,
shape: 'rect'
},
labels: [{
text: labelTextForm.querySelector('#labelTextInput').value,
...
}]
}, ...));
};
Live demo: https://jsfiddle.net/BlackLabel/pghrfjsx/
API Reference: https://api.highcharts.com/highcharts/annotations.labelOptions.format
I have a form with some text fields. One of them is a image upload button.
I need to put the image preview box (a div) to the right side of the field (after the field button).
I already do the hard work by creating the div in the afterrender event:
listeners: {
afterrender: function ( cmp ) {
var container = this.body.dom.id;
$("#" + container ).append('<div style="position:absolute;
left:DONTKNOW;top:DONTKNOW" id="myPictureDiv"></div>');
}
}
how can I position elements in a ExtJS form? Can I use position:absolute ? But how to find the button position? What about form resizing?
EDIT: Image to illustrate scebotari's solution alignment problem:
One solution for this is to create the additional div as a component and to place it in a "fieldcontainer" with the main field.
{
xtype: 'fieldcontainer',
layout: 'hbox',
items: [{
xtype: 'textfield',
fieldLabel: 'Picture'
},{
xtype: 'component',
autoEl: 'div',
width: 32,
height: 32,
margin: '0 0 0 5',
style: 'border: 1px solid #d0d0d0; border-radius: 50%'
}]
}
Here is a fiddle illustrating this concept
This is the Form field
fieldLabel: 'My Field',
width: 330,
id: 'displayColumn',
name: 'displayColumn',
allowBlank : false,
value : '#CACACA',
This is the form listener:
listeners: {
afterrender: function ( cmp ) {
// Get the Window Container
var container = this.body.dom.id;
// Get the Component (ExtJS way)
var comp = Ext.getCmp("displayColumn");
// The ExtJS field ID is not the same you gave
var el = comp.getEl();
// Get the real Field ID
var displayColumnId = el.id;
// If you need its value...
var initialColor = comp.getValue();
// If you need to hide the field to make room to your div...
// I mean if you want to replace the field and keep the label...
// <YOUR_FIELD_ID>-triggerWrap
$("#displayColumn-triggerWrap").css("display","none");
// Append your div to the field container
// <YOUR_FIELD_ID>-bodyEl
$("#displayColumn-bodyEl").append(YOUR_DIV);
}
}
Do some style to the div as you wish
I am attempting to update my table view with updated data but whenever I try to clear it using either
tagsTable.setData();
or
tagsTable.setData([]);
or
tagsTable.data = null;
and then re-apply the updated data using
tagsTable.setData(TagsData);
It never clears the table originally so the new data is just added to the end of the table, so I have the old data as well as the new data in the 1 table.
Any one know whats wrong or how to fix it?
Here's a simple (classic Titanium) app that shows clearing and re-filling the table's data property via some buttons. I'd triple-check the validity of your TagsData sections/rows to make sure everything within the array is being set properly.
var
win = Ti.UI.createWindow({
title: "Table Funs",
layout: "vertical",
backgroundColor: "#ffffff"
}),
navwin = Ti.UI.iOS.createNavigationWindow({
window: win
}),
table = Ti.UI.createTableView(),
clearButton = Ti.UI.createButton({
title: "Clear Table",
width: Ti.UI.FILL,
height: 44,
backgroundColor: "#f4f4f4",
color: "red",
bottom: 1
}),
fillButton = Ti.UI.createButton({
title: "Fill Table",
width: Ti.UI.FILL,
height: 44,
backgroundColor: "#f4f4f4",
color: "blue",
bottom: 1
}),
tableData = [];
// Fill up tableData array with rows
tableData.push(Ti.UI.createTableViewRow({ title: "Hey" }));
tableData.push(Ti.UI.createTableViewRow({ title: "this" }));
tableData.push(Ti.UI.createTableViewRow({ title: "is" }));
tableData.push(Ti.UI.createTableViewRow({ title: "a" }));
tableData.push(Ti.UI.createTableViewRow({ title: "table" }));
clearButton.addEventListener("click", function() {
Ti.API.debug("Clicked clear button.");
table.setData(null);
return;
});
fillButton.addEventListener("click", function() {
Ti.API.debug("Clicked fill button.");
table.setData(tableData);
return;
});
// Fill table with our data
table.setData(tableData);
// Build window
win.add(clearButton);
win.add(fillButton);
win.add(table);
navwin.open();
I want to make some tooltips visible in my d3 map. The tooltips are column charts generated by Highcharts regarding the chosen city. The trick is that everything is displaying correctly (axis, labels ...) except that the columns are not visible!
Here my d3 code (only the relevant parts):
var tooltip = d3.select("body")
.append("div")
.attr("id","tooltip")
.style("position", "absolute")
.style("visibility", "hidden");
cities.on("mouseover", function(d, i) {
d3.select(this).style('fill', '#95a5a6');
tooltip.html(zoomCityComm(d))
return tooltip.style("visibility", "visible")})
.on("mousemove", function(d, i){
return tooltip.style("top", (d3.event.pageY - 130) + "px").style("left",(d3.event.pageX - 120) + "px");
})
}
The function zoomCityComm is HighCharts (example of data: [5,10]):
function zoomCityComm(d) {
chart = new Highcharts.Chart({
chart : {
renderTo: 'tooltip',
type: 'column',
width:200,
height:200,
plotBackgroundColor: '#FCFFC5',
zoomType: 'xy'
},
title: {
text: "TOTO"
},
legend: {
enabled: false
},
xAxis: {
categories: ['In','Out']
},
yAxis: {
title: {
text: 'Sum',
style: {
color: '#4572A7'
}
},
labels: {
style: {
color: '#4572A7'
}
},
},
series:[{color: '#4572A7',data: res}]
});
return document.getElementById("tooltip").innerHTML;
}
When the graph is displayed in a "normal" div within the document, it appears correctly.
Sorry if my explanations are not clear but ask me for some details if needed.
Thanks
Cyril
You're setting the HTML content of the div twice, as highcharts renders it itself. In your mouseover handler function, it is enough to do
zoomCityComm(d);
instead of
tooltip.html(zoomCityComm(d));
For the interested, here's what's happening. Setting the HTML of the tooltip div from the return value of the function captures the first animation frame that highchart uses to grow the bars. As it is the first frame, the height of the bars is still 0 -- that is, the bars are there, but not visible because they have essentially no height. Replacing the HTML of the div means that the animation won't work anymore, as the elements that would be animated have been replaced.