<div class="container-fluid">
   
  
      <button id="expand" class="btn btn-primary">
        확장
      </button>
      <button id="collapse" class="btn btn-primary">
        축소
      </button>
      <div id="theGrid" class="animated"></div>
    </div>
label {
    display: block;
}
.wj-flexgrid {
    margin: 10px 0;
}

/* highlight the main column in the group */
.wj-flexgrid .wj-cells .wj-cell.main-column {
    background: #e3f4ff;
}

/* some conditional formatting */
.big-val {
    font-weight: bold;
    color: darkgreen;
}
.small-val {
    font-style: italic;
    color: rgb(202, 0, 0);
}

/* some animation when collapsing/expanding the groups */
.wj-flexgrid.animated .wj-colheaders .wj-header.wj-cell.wj-colgroup {
    transition: all .2s;
}
document.readyState === 'complete' ? init() : window.onload = init;
function init() {

  let colGroups1 = getColumnGroups()

  let theGrid = new wijmo.grid.FlexGrid('#theGrid', {
    headersVisibility: 'Column',
    alternatingRowStep: 0,
    showMarquee: true,
    showSelectedHeaders: 'All',
    autoGenerateColumns: false,
    columnGroups: colGroups1,
    itemsSource: getData()
  });

  
   document.getElementById("expand").addEventListener("click", (e) => {
    colGroups1.map((group) => {
      console.log(group);
      if (group.collapseTo) {
        group.isCollapsed = false;
      }
    });
 
    theGrid.columnGroups = colGroups1;
  });
  document.getElementById("collapse").addEventListener("click", (e) => {
    colGroups1.map((group) => {
      if (group.collapseTo) {
        group.isCollapsed = true;
      }
    });
    theGrid.columnGroups = colGroups1;
  });

}

function getColumnGroups() {
  const allocTemplate = '<span class=${value > .2 ? "big-val" : "small-val"}>${value}:${col.format}</span>';
  const amountTemplate = '<span class=${value > 50000 ? "big-val" : "small-val"}>${value}:${col.format}</span>';
  return [
    { binding: 'name', header: 'Name', width: 150 },
    { binding: 'currency', header: 'Curr', width: 80, align: 'center' },
    { header: 'Perf', align: 'center', collapseTo: 'perf.ytd', columns: [
      { binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClass: 'main-column' },
      { binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 },
      { binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 },
      { binding: 'perf.m12', header: '12 M', format: 'p2', width: 80 },
    ] },
    { header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: [
      { binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80, cellTemplate: allocTemplate },
      { binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80, cellTemplate: allocTemplate },
      { binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80, cellTemplate: allocTemplate },
      { binding: 'alloc.other', header: 'Other', format: 'p0', width: 80, cellTemplate: allocTemplate },
      { binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 100, cssClass: 'main-column', cellTemplate: amountTemplate }
    ] }
  ];
}
// slightly different column groups
// function getDeeperColumnGroups() {
//   return [
//     { binding: 'name', header: 'Name', width: 150 },
//     { binding: 'currency', header: 'Curr', width: 80, align: 'center' },
//     { header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: [
//       { binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80 },
//       { binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80 },
//       {
//         header: 'Detail', align: 'center', columns: [
//           { binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80 },
//           { binding: 'alloc.other', header: 'Other', format: 'p0', width: 80 },
//         ]
//       },
//       { binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 100, cssClassAll: 'highlight' },
//     ] },
//     { header: 'Perf', align: 'center', columns: [
//       { header: 'Short', align: 'center', collapseTo: 'perf.ytd', isCollapsed: true, columns: [
//         { binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClassAll: 'highlight' },
//         { binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 },
//       ] },
//       { header: 'Long', align: 'center', collapseTo: 'perf.m12', isCollapsed: true, columns: [
//         { binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 },
//         { binding: 'perf.m12', header: '12 M', format: 'p2', width: 100, cssClassAll: 'highlight' }
//       ] },
//     ] },
//   ];
// }
// get some sample data
function getData() {
  return [{
    name: 'Constant Growth',
    currency: 'USD',
    perf: {
      ytd: .0523,
      m1: 0.0142,
      m6: 0.0443,
      m12: 0.0743
    },
    alloc: {
      stock: 0.17,
      bond: 0.32,
      cash: 0.36,
      other: 0.15,
      amount: 23432
    }
  }, {
    name: 'Optimus Prime',
    currency: 'EUR',
    perf: {
      ytd: .0343,
      m1: 0.043,
      m6: 0.0244,
      m12: 0.0543
    },
    alloc: {
      stock: 0.61,
      bond: 0.8,
      cash: 0.9,
      other: 0.22,
      amount: 43223
    }
  }, {
    name: 'Crypto Planet',
    currency: 'BTC',
    perf: {
      ytd: .0343,
      m1: 0.014,
      m6: 0.034,
      m12: 0.01243
    },
    alloc: {
      stock: 0.1,
      bond: 0,
      cash: 0,
      other: 0.9,
      amount: 2234
    }
  }, {
    name: 'MegaZone',
    currency: 'EUR',
    perf: {
      ytd: .0443,
      m1: 0.034,
      m6: 0.0424,
      m12: 0.0343
    },
    alloc: {
      stock: 0.51,
      bond: 0.9,
      cash: 0.8,
      other: 0.12,
      amount: 32234
    }
  }, {
    name: 'Serenity',
    currency: 'YEN',
    perf: {
      ytd: .0522,
      m1: 0.0143,
      m6: 0.0458,
      m12: 0.0732
    },
    alloc: {
      stock: 0.66,
      bond: 0.09,
      cash: 0.19,
      other: 0.06,
      amount: 65624
    }
  }];
}

External CSS

  1. https://cdn.grapecity.com/wijmo/5.latest/styles/wijmo.min.css
  2. https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.1/css/bulma.min.css
  3. https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css

External JavaScript

  1. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.min.js
  2. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.input.min.js
  3. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.min.js
  4. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.filter.min.js
  5. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.sheet.min.js
  6. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.xlsx.min.js
  7. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.xlsx.min.js
  8. https://www.grapecity.co.kr/files/license/Wijmo/CodePen_License.js
  9. https://cdnjs.cloudflare.com/ajax/libs/jszip/3.5.0/jszip.min.js
  10. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.search.min.js
  11. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.grouppanel.min.js
  12. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.cellmaker.min.js
  13. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.pdf.min.js
  14. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.pdf.min.js
  15. https://code.jquery.com/jquery-3.5.1.slim.min.js
  16. https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js
  17. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.odata.min.js
  18. https://cdn.grapecity.com/wijmo/5.latest/controls/wijmo.grid.detail.min.js