Rotate table?

Rotate table?

nikoniko Posts: 5Questions: 0Answers: 0
edited August 2011 in DataTables 1.8
I'd like to alter the table so that rows become columns and vice versa. So headers are displayed up and down the left side of the table and sorting happens from left to right.

Replies

  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    This is not currently supported with DataTables, since the idea of columns being vertical rather than horizontal in quite deeply baked into the current DataTables code. This is something that ultimately I'd like to make possible, but likely I won't get a chance to do so for quite a long time to come.

    Allan
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    I think someone could write a plug-in for this. Basically all it needs making the existing table display: none and taking the data and writing it to a new visible table that is rotated, and listening for draw refreshes.

    A lingering question will be what the meaning of a column header is, and what you'd sort/filter by. Perhaps there should be an init-time indicator that tells the code to re-write the data (rotate it) before any initial table is made.

    I was going to write a highlight plug-in but others have already taken care of that. Maybe I'll take this project.
  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    That's an interesting idea! Through the combination of setting up another DataTable, based on the original, with x-scrolling and FixedColumns (if the table is too big horizontally for the space) you could indeed set up a pivoting table with DataTables as it stands. Let us know if you have a bash at this!

    Next blog post will be about creating first class plug-ins for DataTables, which you might be interested in (a couple of days before I can post it I think). It won't present anything hugely complex, but it might be of interest as a basic grounding for it.

    Regards,
    Allan
  • tedkalawtedkalaw Posts: 12Questions: 0Answers: 0
    Awesome, I'm excited for that blog post! I am planning on writing a plug-in to add and remove columns dynamically soon.
  • nikoniko Posts: 5Questions: 0Answers: 0
    Thanks everyone for responding quickly! fbas, sorting should originate from the cells in the leftmost column so the arrows will point left and right instead of up and down. The header, or top row, should then serve no special purpose. Naming might pose a problem, a column header cam be the left most column or the top cell of a given column.

    tedkalaw, I look forward to your plug-in.
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    So in otherwords, the TH should be rotated into column 0, right?
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    edited August 2011
    This is actually pretty promising:
    note: i've left the original table visible for comparisons.

    more work needs to be done, like applying strip classes, etc.
    [code]



    pivot a data table





    <!--
    var oTable;
    var draw = 0;

    $(document).ready(function() {

    oTable = $('#properties_table').dataTable({
    sDom: 't',
    bUseRendered: false,
    bLengthChange: true,
    aaSorting: [[ 1, "asc" ]],
    asStripClasses: [ "pt_odd", "pt_even" ],
    aoColumns: [
    { // property column
    sClass: "pt_property"
    },
    { // value column
    sClass: "pt_value default_value",
    },
    { bVisible: true }, // category column
    { bVisible: false } // description column
    ],
    oLanguage: {
    sSearch: "Filter:"
    },
    "fnDrawCallback": function () {

    var table_id = $(this).attr('id');
    var oTable = $(this).dataTable({ bRetrieve: true });
    var oSettings = oTable.fnSettings();

    // get any previous pivot tables, to destroy after creating a new one
    var pivot_id = table_id + "_pivot";
    var old_pivot = $('#'+pivot_id);

    // create new pivot table from original table
    var pivot = $(this).clone(true);
    var $pivot = $(pivot);

    $pivot.attr('id', pivot_id);
    $pivot.find('tr').remove(); // remove all rows
    $tbody = $($pivot.find('tbody')[0]);

    // rebuild table row by row by reading a column header and all column data from the original table
    draw += 1; // using this in cell TITLE attribute to be sure I got a refresh
    for (i = 0; i < oSettings.aoColumns.length; i++) {
    // start a new row
    var $nTr = $('');

    // get header from original table, add to new row
    //var nTh = $(this).find('th').eq(i).clone(true);
    //$nTr.append(nTh);

    // get columns from original table, add to new row
    $('tr th:nth-child('+i+'), tr td:nth-child('+i+')', this).each( function() { $nTr.append($(this).clone(true).attr('title', "draw: " + draw)); });

    $tbody.append($nTr[0]);
    }

    if (old_pivot.length) old_pivot.remove();
    $pivot.append($tbody[0]);

    $('#'+table_id+'_wrapper').append($pivot[0]);


    }
    });



    });

    // -->



    <!--

    #properties_table {
    border-collapse: collapse;
    border-spacing: 0;
    border: solid black 1px;
    }

    #properties_table th, #properties_table td {
    _text-wrap:supress;
    padding-left: 2px;
    border: solid #bbb 1px;
    }


    #properties_table_pivot {
    border-collapse: collapse;
    border-spacing: 0;
    border: solid black 1px;
    }

    #properties_table_pivot th, #properties_table_pivot td {
    _text-wrap:supress;
    padding-left: 2px;
    border: solid #bbb 1px;
    }

    .left {
    text-align: left;
    }

    -->










    A
    B
    C
    D




    a1
    b4
    c7
    d1


    a2
    b1
    c6
    d2


    a3
    b5
    c5
    d3


    a4
    b2
    c4
    d4


    a5
    b6
    c3
    d5


    a6
    b3
    c2
    d6


    a7
    b7
    c1
    d7










    [/code]
  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    That looks like an excellent start - nice one!
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    This is pretty much it. just added one line to apply strip classes.

    I'm not sure how to wrap this up into a more modular plug-in form factor.

    Also, I'm unsure if this meets anyone's needs. If you need it tweaked, let me know.

    [code]
    $(document).ready(function() {
    $('#example').dataTable({
    "fnDrawCallback": function () {
    $(this).hide(); // you could move this somewhere else because original table only needs to hide once
    var table_id = $(this).attr('id');
    var oTable = $(this).dataTable({ bRetrieve: true });
    var oSettings = oTable.fnSettings();

    // get any previous pivot tables, to destroy after creating a new one
    var pivot_id = table_id + "_pivot";
    var old_pivot = $('#'+pivot_id);

    // create new pivot table from original table
    var pivot = $(this).clone(true);
    var $pivot = $(pivot);

    $pivot.attr('id', pivot_id);
    $pivot.find('tr').remove(); // remove all rows
    $tbody = $($pivot.find('tbody')[0]);

    // rebuild table row by row by reading a column header and all column data from the original table
    for (i = 1; i <= oSettings.aoColumns.length; i++) { // nodes are 1-indexed in :nth-child
    // start a new row
    var $nTr = $('');
    $nTr.addClass(oSettings.asStripClasses[i % oSettings.asStripClasses.length]);

    // get columns from original table, add to new row
    $('tr th:nth-child('+i+'), tr td:nth-child('+i+')', this).each( function() {
    $nTr.append($(this).clone(true));
    });

    $tbody.append($nTr[0]);
    }

    if (old_pivot.length) old_pivot.remove(); // remove any old versions of pivot table, from old draws
    $pivot.append($tbody[0]);

    $(this).after($pivot[0]); // add the newly created table
    $pivot.show(); //show, because it inherited from hidden table.
    }
    });

    });
    [/code]
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    line 28 includes tfoot elements. can be changed to only look in thead and tbody
    [code]
    $('thead tr th:nth-child('+i+'), tbody tr td:nth-child('+i+')', this)
    [/code]
  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    Very nice indeed - love it! A very clever way of approaching the problem that :-)

    I've just put up the blog post I adulated to earlier: http://datatables.net/blog/Creating_feature_plug-ins . Might be of interest for wrapping it up into a feature plug-in.

    Regards,
    Allan
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    Thanks, I've been waiting for that blog post. I'll look forward to it.
  • nikoniko Posts: 5Questions: 0Answers: 0
    Thank you fbas this is perfect! I'll let you know if I need it tweaked.
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    Allan, is there something similar to dataTableExt.oApi where I can add variables to DataTables

    for instance, I will implement a function fnPivot(boolean) that turns on and off the pivoting, and want to set a variable bPivot somewhere to keep this state (and maybe let the value be specified at init time?).
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    Digging in more code, I believe I found good examples in ColReorder, using instance variables as well as pulling init values from the DT object.

    thanks.
  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    Generally what I do with plug-ins is to attach with the instance of the plug-in (if it is a "class"), or the settings object for the plug-in if it isn't an instance, to the DataTables settings object as "o{pluginName}". For example oSettings.oFixedColumns = this;

    Not all of my "extras" follow this pattern yet, but the new ones do and I'm slowly converting the old ones over.

    If it is just one parameter then you could just attach it to the settings object as something like oSettings.__var = whatever;

    Regards,
    Allan
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    edited January 2012
    Here's an update on the plug in.

    It was written in August 2011. You can download it at http://www.beg.utexas.edu/_work/dt/Transpose.zip . There's a demo page in the zip file.

    It adds 3 functions to the DataTable object:
    [quote]
    fnTranspose(bTranspose) - transpose (or untranspose) the current table

    fnTransposeState([bTranspose]) - get/set the internal bTranspose value without redrawing the table

    fnTransposeVersion([sVersion]) - get the version of the Transpose plugin, or compare sVersion to the current version and return true or false if version is equal to or greater than sVersion
    [/quote]

    example usage (from the demo page):
    [code]
    /* Add feature 'Z' to sDom to enable Transpose */
    /* Initialise the table */
    var oTable; // keep a global handle for convenience

    $(document).ready(function() {
    // intialize table to use Transpose (letter 'Z').
    oTable = $('#example').dataTable({sDom: 'Zlfrtip'});

    sTransposeVersion = oTable.fnTransposeVersion(); // get version
    bVersionCheck = oTable.fnTransposeVersion('1.0.5'); // compare version
    } );


    /* Add a button handler to alternate between transposed and un-transposed table */
    function transpose_table() {
    var bTranspose = oTable.fnTransposeState();
    oTable.fnTranspose(!bTranspose); // alternate the rotation of the table and redraw

    }

    /* add handler to button */

    [/code]
  • jfobeljfobel Posts: 3Questions: 0Answers: 0
    The download link no longer works. Can I please have access to this plugin?

    Thanks!
  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    Unfortunately I don't have the zip file - we'll need to see if fbas still has it somewhere.

    Allan
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    edited May 2012
    edit: [sorry. I posted a link, but it was an old version I found. will check my computer at work for the January updated version and will post a link]
  • allanallan Posts: 63,381Questions: 1Answers: 10,449 Site admin
    Super thanks :-). And this time I'll put a copy in my archive :-)

    Allan
  • fbasfbas Posts: 1,094Questions: 4Answers: 0
    edited May 2012
    ok, the link should be available now

    http://www.beg.utexas.edu/_work/dt/Transpose.zip


    note: I haven't tested this on anything but DT 1.8x
  • arungarung Posts: 2Questions: 0Answers: 0
    its not wowrking for me....got error here ... please help me ... am getting data from server side

    function transpose_table() {

    $('#properties_table').dataTable({ sDom: 'Zlfrtip' });
    var oTable = $('#properties_table').dataTable({ bRetrieve: true });
    var bTranspose = oTable.fnTransposeState();
    oTable.fnTranspose(!bTranspose); // alternate the rotation of the table and redraw

    }
This discussion has been closed.