nicolaskruchten / pivottable

Open-source Javascript Pivot Table (aka Pivot Grid, Pivot Chart, Cross-Tab) implementation with drag'n'drop.
https://pivottable.js.org/
MIT License
4.34k stars 1.08k forks source link

Freeze headers #1178

Open maxkuester opened 4 years ago

maxkuester commented 4 years ago

Can anyone suggest if there is a way to freeze the headers, such that when scrolling larger tables the column names can remain visible to the user?

VitaliyMF commented 4 years ago

@maxkuester this is easily possible with NReco addon, however it displays "powered by notice" which can be removed only with commercial version of addon.

Erik-2019 commented 4 years ago

You can try using CSS. .pvtTable thead th { position: -webkit-sticky; / for Safari / position: sticky; top: 0; }

adimon91 commented 4 years ago

Amazing, thank you for posting that @Erik-2019 I was really struggling with that. Any suggestion on how to fix the th columns when scrolling left/right?

jacobSpitzer commented 3 years ago

the solution from Erik-2019 is great. However, it's working for me only for the last thead row - if there is more than one thead rows.

nic86 commented 2 years ago

the solution from Erik-2019 is great. However, it's working for me only for the last thead row - if there is more than one thead rows.

try removing the th from the css rule

.pvtTable thead {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
}
nic86 commented 2 years ago

To fix the row and column header in the table, assign this function to the onRefresh option:

options.onRefresh = function(config) {
    const numRows = config.rows.length;
    const numCols = config.cols.length;

    const startLeft = 0;

    const pvtAxisLabelSticky = $('.pvtTable thead tr:last-child .pvtAxisLabel');
    let leftRowHeader = [];
    let progLeft = startLeft;
    pvtAxisLabelSticky.each(function(index) {
        leftRowHeader[index] =  progLeft;
        $(this).css('left', progLeft);
        progLeft += $(this).outerWidth( true ); 
    })
    const leftRowHeaderLength = leftRowHeader.length;

    const pvtRowsSticky = $('.pvtTable tbody tr');
    pvtRowsSticky.each(function(index) {
        let pvtRowLabel = $(this).find('.pvtRowLabel');

        let pvtRowLabelLength = pvtRowLabel.length;
        let j = pvtRowLabelLength - 1;
        for(let i = leftRowHeaderLength - 1; i >= (leftRowHeaderLength - pvtRowLabelLength) ; i--) {
            $(pvtRowLabel[j]).css('left', leftRowHeader[i]);
            j--;
        }
    });

    const pvtFirstW = $('.pvtTable thead tr:first-child th:first-child').outerWidth( true ) + startLeft;
    for(let i = 1;i <= numCols;i++) {
        $('.pvtTable thead tr:nth-child(' + i + ') .pvtAxisLabel').css('left', pvtFirstW);
    }
    $('.pvtTable thead tr:last-child th:last-child').css('left', pvtFirstW);
};

and add this css:

.pvtTable {
  border-collapse: collapse;
}
.pvtTable th{
   border: none;
   outline: 1px solid #ddd;
   outline-offset: -1px;
}
.pvtTable td{
   border: none;
   outline: 1px solid #ddd;
   outline-offset: -1px;
}

.pvtTable thead {
  position: -webkit-sticky;
  position: sticky;
  z-index:2;
  top: 0px;
}

.pvtTable thead .pvtAxisLabel {
  position: -webkit-sticky;
  position: sticky;
  z-index:3;
  top:0px;
}

.pvtTable tbody tr .pvtRowLabel {
 position: -webkit-sticky;
  position: sticky;
  z-index:1;
}

.pvtTable tbody tr .pvtColTotalLabel {
  position: -webkit-sticky;
  position: sticky;
  z-index:3;
  left:0px;
}

.pvtTable thead tr:first-child th:first-child {
  position: -webkit-sticky;
  position: sticky;
  z-index:3;
  left:0px;
  top:0px;
}

.pvtTable thead tr:last-child th:last-child {
  position: -webkit-sticky;
  position: sticky;
  z-index:3;
}
jazo2212 commented 10 months ago

Hola. Los códigos que enviaste no logran fijar las áreas donde están los campos al inicio y las áreas hacia donde se arrastran los campos para armar la tabla dinámica. La idea que el scroll solo tenga el ancho y actúe en el interior de la tabla dinámica. Por ejemplo:

El Scroll no debe abarcar todo el ancho y alto de la tabla dinámica. malo

Así debe quedar el scroll, solo debe abarcar y actuar al interior (registros) de la tabla dinámica para que las areas donde se arrastran los campos queden fijas. Bueno

jazo2212 commented 10 months ago

Puedes intentar usar CSS. .pvtTable thead th { posición: -webkit-sticky; / para Safari / posición: pegajoso; arriba: 0; }

El css solo fija el encabezado de la tabla. La idea es que también fije el área donde se arrastran los campos que están en la parte superior e izquierda de la tabla dinámica. Para ello el scroll solo debe de actuar al interior de la tabla dinámica asi como se muestra en la imagen.

Bueno