Is there a scrollIntoView technique for kendoGrid - kendo-ui

I have a kendoGrid displaying a data source that has 200 rows and 50 columns. There are vertical and horizontal scrollbars, which is desired.
How can I cause the grid to scroll into view a specific column, row or row&column ?
Two use cases are:
Column name Z selected from a menu, jump to column Z (scroll it into view)
Grid with data source is FOO is scrolled about until Column X is left most column in view. The grid then replaced with a new one whose data source is BAR. If BAR contains a column X then I want to scroll it into view.
Thanks,
Richard

The very first thing that you need is finding the position of the cell. If you know the number of the row and the column you can do:
var col = 30;
var row = 100;
var pos = $("tr:nth(" + (row - 1) + ")", grid.tbody).find("td:nth(" + (col - 1) + ")").position();
Then you have to scroll and you can go directly using:
$(grid.tbody).closest(".k-grid-content").scrollTop(pos.top).scrollLeft(pos.left);
or animate it using:
$(grid.tbody).closest(".k-grid-content").animate({
scrollTop : pos.top,
scrollLeft: pos.left
}, 2000);

Related

Strange behavior with Grid definition auto height and stacklayout inside the row

I am using a grid with autoheight for row definition (I have a Editor inside, so my row can update it's height depending of the text).
My issue is, in another cell, there is a stack layout
StackLayout stackEspeceVariete = new StackLayout()
{
Children = { autoCompleteEspece, autoCompleteVariete }
};
stackEspeceVariete.Orientation = StackOrientation.Horizontal;
gridLignes.Children.Add(stackEspeceVariete);
Grid.SetRow(stackEspeceVariete, gridLignes.RowDefinitions.Count - 1);
Grid.SetColumn(stackEspeceVariete, 2);
Adding the stacklayout cause my row to take all the screen size. I want the stacklayout to take the size it's needed, not all screen size.
I tried changing the vertical option but no success.
I also tried to fix the stacklayout height to 130, it's was "working" but, the row height was no longer changing, depending on the editor text.
It's like the row is fixed to the stacklayout child
Do you have any idea ?
Thanks

Adjusting small multiples sparklines

I have an heatmap that show some data and a sparkline for each line of the heatmap.
If the user click on a row label, then the data are ordered in decreasing order, so each rect is placed in the right position.
Viceversa, if the user click on a column label.
Each react is placed in the right way but I'm not able to place the sparkline.
Here the code.
When the user click on a row label, also the path inside the svg containing the sparkline should be updated.
And then, when the user click on a column label, the svg containing the sparkline should be placed in the correct line.
To place the svg in the right place, I try to use the x and y attributes of svg. They are updated but the svg doesn't change its position. Why?
Here is a piece of code related to that:
var t = svg.transition().duration(1000);
var values = [];
var sorted;
sorted = d3.range(numRegions).sort(function(a, b) {
if(sortOrder) {
return values[b] - values[a];
}
else {
return values[a] - values[b];
}
});
t.selectAll('.rowLabel')
.attr('y', function(d, k) {
return sorted.indexOf(k) * cellSize;
});
Also, I don't know how to change the path of every sparkline svg. I could take the data and order them manually, but this is only good for the row on which the user has clicked and not for all the others.
How can I do?
The vertical and horizontal re-positioning/redrawing of those sparklines require different approaches:
Vertical adjustment
For this solution I'm using selection.sort, which:
Returns a new selection that contains a copy of each group in this selection sorted according to the compare function. After sorting, re-inserts elements to match the resulting order.
So, first, we set our selection:
var sortedSVG = d3.selectAll(".data-svg")
Then, since selection.sort deals with data, we bind the datum, which is the index of the SVG regarding your sorted array:
.datum(function(d){
return sorted.indexOf(+this.dataset.r)
})
Finally, we compare them in ascending order:
.sort(function(a,b){
return d3.ascending(a,b)
});
Have in mind that the change is immediate, not a slow and nice transition. This is because the elements are re-positioned in the DOM, and the new structure is painted immediately. For having a slow transition, you'll have to deal with HTML and CSS inside the container div (which may be worth a new specific question).
Horizontal adjustment
The issue here is getting all the relevant data from the selection:
var sel = d3.selectAll('rect[data-r=\'' + k + '\']')
.each(function() {
arr.push({value:+d3.select(this).attr('data-value'),
pos: +d3.select(this).attr('data-c')});
});
And sorting it according to data-c. After that, we map the result to a simple array:
var result = arr.sort(function(a,b){
return sorted.indexOf(a.pos) - sorted.indexOf(b.pos)
}).map(function(d){
return d.value
});
Conclusion
Here is the updated Plunker: http://next.plnkr.co/edit/85fIXWxmX0l42cHx or http://plnkr.co/edit/85fIXWxmX0l42cHx
PS: You'll need to re-position the circles as well.

"page x of y" in a table, how to allign the text within a table instead of the page border?

I was able to create page x of y using the Building Blocks example of Chapter 7: Handling events; setting viewer preferences and writer properties Solving the "Page X of Y" problem. In the example, the texts of "page x of y" are alligned via a Canvas with the page border. But very often is that the "x of y" shall be put into a table like this:
In such cases, the text shall be alligned within the table, how to do this?
In my application, the table which includes the page x of y shall be shown on each page and still at a fixed position, i.e. at the right upper position of a page. And the table format and size will not change for the whole document.
First of all, in order to fit the whole table, you would want to increase the bottom margin of the Document:
Document document = new Document(pdf);
document.setBottomMargin(100);
After that, you can still use Canvas to add a table instead of a paragraph. I will base the answer on the PageXofY example you refer to.
First of all, create a usual Table:
Table table = new Table(UnitValue.createPercentArray(new float[] {50, 50}));
table.addCell(new Cell(4, 1));
table.addCell(new Cell().add("Filename: "));
table.addCell(new Cell().add("Issue date: "));
Paragraph pageXofY = new Paragraph().
add("Page " + String.valueOf(pageNumber) + " of ").
add(new Image(placeholder));
table.addCell(new Cell().add(pageXofY));
table.addCell(new Cell().add("Location: "));
Note that we still use a placeholder FormXObject to store the total number of pages.
Change the side to font size, it is 12 in our case. Create placeholder like this:
placeholder = new PdfFormXObject(new Rectangle(0, 0, 2 * side, side));
Make a slight change to the writeTotal() method. The y position of the text has been changed to -descent:
public void writeTotal(PdfDocument pdf) {
Canvas canvas = new Canvas(placeholder, pdf);
canvas.showTextAligned(String.valueOf(pdf.getNumberOfPages()),
0, -descent, TextAlignment.LEFT);
}
Now all you need to to is add this table to the proper place on the page:
float marginX = 36;
Canvas canvas = new Canvas(pdfCanvas, pdf, new Rectangle(marginX, 10, pageSize.getWidth() - marginX * 2, 100));
canvas.add(table);
pdfCanvas.release();
The result looks like this:

Fit columns to content in handsontable

I am new to handsontable, and I can not achieve a goal as simple as to have the columns width as long as the content of the cells. Even if I have space enough in handsontable parent to display the full content of the table, some columns overlap the content of some cells.
I do not want to stretch the table to its parent. Just to show the full table contents (as I have space enough).
Update
The answer of fap is right.
I have realized the problem does not come from the basic definition of the table but for the definition of a renderer do on cells.
cells: function (row, col, prop) {
var cellProperties = {};
if (row === 0) {
cellProperties.renderer = firstRowRenderer;
}
return cellProperties;
}
function firstRowRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.fontWeight = 'bold';
td.style.color = 'green';
td.style.background = '#CEC';
}
It is after the renderer is applied when the content does not fit into handsontable cells and it does not resize. This is the real problem I am facing.
Just don't specify any width for the table and/or columns. Handsontable will size the columns depending of the longest value there is in their respective cells.
See this simple example.
Note that if you edit the values, the column resize dynamically.
But what if you have a value that expand the column width so much that your table is wider than your screen ? Well, if you don't really want that (and I assume that you don't otherwise what's the point of delimiting your columns and/or your table in the first place ?), you can use the option preventOverflow :
preventOverflow: 'horizontal',
As you can see in this example, it will automatically create a navigate bar that prevent your table to go off screen but still size the columns in order to see all your data.

Is there any way to start subgrid with particular column of main grid or can we shift subgrid icon column postion?

Please see my below jqgrid subgrid image,
Question 1 : By default, my sub grid start with parent grid column "ID" (first column of parent grid), Can we start my sub grid from 3rd column of my parent grid (Contact Name)?
Question 2 : Or, Is there any chance to move sub grid icon (+) column after 2nd column of my parent grid, hence my sub grid will start with 3rd column of my parent grid?
Please suggest, Thanks!
The row with the standard subgrid like on the picture below
consist from three parts which I marked in different colors. The corresponding HTML structure looks like on the next picture
jqGrid creates an empty <div> (see <div class="tablediv" id="list_1"></div> marked in red) and calls subGridRowExpanded callback with the id of the div ("list_1" on the picture above) as the value of the first parameter. One places an empty <table> with some unique id attribute in the div with and creates grid from the <table>. The typical code looks like
subGridRowExpanded: function (subgridId, rowid) {
var $table = $("<table id='" + subgridId + "_t'></table>");
$("#" + subgridId).append($table);
$table.jqGrid({
// ...
});
}
What you can to do is to set some CSS attributes on the <div> to place the table on the place where you need it. For example I have the column "sequence" in the parent grid of the demo used on the pictures. The header of the column of the header have gridId + "_sequence" id. So one can use the following code to set padding-left to skip the first column:
subGridRowExpanded: function (subgridId, rowid) {
var $table = $("<table id='" + subgridId + "_t'></table>");
$("#" + subgridId).append($table)
// set padding-left to the outer width of the first column "sequence"
// of the parent grid
.css("padding-left", $("#" + this.id + "_sequence").outerWidth() + "px");
$table.jqGrid({
// ...
autowidth: true
});
}
The advantage of the usage padding-left: one can use autowidth: true in the subgrid to resize the subgrid to fill the right part of the row of subgrid.
The demo uses the code. The results looks like on the picture below
You can change other attributes of subgrid row inside of subGridRowExpanded to achieve your exact goals.

Resources