在 Handsontable 中汇总家长工作时间

问题描述 投票:0回答:1

我在 Handsontable 中设计了一个表格来计算每个月每个任务和工单的工作时间总和。我想在表格的最后一行显示全年的工作时间总和,但我不知道如何仅将父项相加。

我的代码:https://jsfiddle.net/5pr3cvw9/

const container = document.querySelector('#example');
const hyperformulaInstance = HyperFormula.buildEmpty({
  licenseKey: 'internal-use-in-handsontable',
});

const hot = new Handsontable(container, {
  columnSummary() {
    const endpoints = [];
    const nestedRowsPlugin = this.hot.getPlugin('nestedRows');
    const getRowIndex = nestedRowsPlugin.dataManager.getRowIndex.bind(nestedRowsPlugin.dataManager);
    const resultColumn = 3;

    let tempEndpoint = null;
    let nestedRowsCache = null;

    if (nestedRowsPlugin.isEnabled()) {
      nestedRowsCache = this.hot.getPlugin('nestedRows').dataManager.cache;
    } else {
      return;
    }

    for (let i = 0; i < nestedRowsCache.levels[0].length; i++) {
      tempEndpoint = {};

      if (!nestedRowsCache.levels[0][i].__children || nestedRowsCache.levels[0][i].__children.length === 0) {
        continue;
      }

      tempEndpoint.destinationColumn = resultColumn;
      tempEndpoint.destinationRow = getRowIndex(nestedRowsCache.levels[0][i]);
      tempEndpoint.type = 'sum';
      tempEndpoint.forceNumeric = true;
      tempEndpoint.ranges = [];

      tempEndpoint.ranges.push([
        getRowIndex(nestedRowsCache.levels[0][i].__children[0]),
        getRowIndex(nestedRowsCache.levels[0][i].__children[nestedRowsCache.levels[0][i].__children.length - 1])
      ]);

      endpoints.push(tempEndpoint);
      tempEndpoint = null;
    }

    return endpoints;
  },
  data,
  columns,
  colHeaders: ['Month', 'Tasks', 'Tickets', 'Total hours'],
  columnSorting: {
    indicator: true
  },
  formulas: {
    engine: hyperformulaInstance,
    sheetName: 'Sheet1',
  },
  rowHeaders: false,
  stretchH: 'all',
  autoWrapRow: true,
  licenseKey: 'non-commercial-and-evaluation',
  autoColumnSize: true,
  width: '100%',
  height: 'auto',
  dropdownMenu: true,
  mergeCells: true,
  contextMenu: true,
  manualRowMove: true,
  manualColumnMove: true,
  multiColumnSorting: {
    indicator: true
  },
  filters: true,
  manualRowResize: true,
  manualColumnResize: true,
  comments: true,
  nestedRows: true


});
<script src="https://cdn.jsdelivr.net/npm/handsontable@latest/dist/handsontable.full.js"></script>
<link href="https://cdn.jsdelivr.net/npm/handsontable@latest/dist/handsontable.full.css" rel="stylesheet" />
<div id="example"></div>


<script>
  const data = [{
      month: 'January',
      tasks: '#54, #76',
      tickets: '#546',
      total_hours: 0,
      __children: [{
          tasks: '#54 - test task 1',
          tickets: '#546 - support ticket 1',
          total_hours: 10.03
        },
        {
          tasks: '#76 - test task 2',
          tickets: '#546 - support ticket 1',
          total_hours: 3.40
        },
      ]
    },
    {
      month: 'February',
      tasks: '#65',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '#65 - test task 3',
        tickets: '',
        total_hours: 2.35
      }, ]
    },
    {
      month: 'March',
      tasks: '',
      tickets: '#451',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#451 - support ticket 3',
        total_hours: 12.7
      }, ]
    },
    {
      month: 'April',
      tasks: '#12, #87',
      tickets: '',
      total_hours: 0,
      __children: [{
          tasks: '#12 - test task 5',
          tickets: '',
          total_hours: 2
        },
        {
          tasks: '#87 - test task 8',
          tickets: '',
          total_hours: 4.2
        },
      ]
    },
    {
      month: 'May',
      tasks: '',
      tickets: '#567',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      month: 'June',
      tasks: '#98, #54, #128',
      tickets: '#783, #981',
      total_hours: 0,
      __children: [{
          tasks: '#98 - test task 12',
          tickets: '',
          total_hours: 0.45
        },
        {
          tasks: '#54 - test task 15',
          tickets: '',
          total_hours: 4
        },
        {
          tasks: '#128 - test task 23',
          tickets: '',
          total_hours: 6.4
        },
        {
          tasks: '',
          tickets: '#783 - test support 11',
          total_hours: 3.3
        },
        {
          tasks: '',
          tickets: '#981 - test support 12',
          total_hours: 3.4
        },
      ]
    },
    {
      month: 'July',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      month: 'August',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      month: 'September',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      month: 'October',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      month: 'November',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      month: 'December',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: [{
        tasks: '',
        tickets: '#567 - test support 7',
        total_hours: 10
      }, ]
    },
    {
      // Add a new row for the total hours
      month: 'Year Total',
      tasks: '',
      tickets: '',
      total_hours: 0,
      __children: []
    }
  ]
  const columns = [{
      'data': 'month',
      'type': 'text',
      'readOnly': true
    },
    {
      'data': 'tasks',
      'type': 'text',
      'readOnly': false
    },
    {
      'data': 'tickets',
      'type': 'text',
      'readOnly': false
    },
    {
      'data': 'total_hours',
      'type': 'numeric',
      'numericFormat': {
        'pattern': '0.00'
      },
      'readOnly': false
    },
  ];
</script>

javascript sum rhandsontable
1个回答
0
投票

这不是小事。

https://jsfiddle.net/mplungjan/abzefdhL/

这是一个解决方案,将在加载后和更改后添加行和求和

let hotInstance; // we need this to be global to not get errors when we pass it while creating the instance

const calculateYearlyTotal = (hot) => {
  const data = hot.getSourceData();
  let yearTotalRowIndex = data.findIndex(row => row.month === 'Year Total');
  // Check if 'Year Total' row exists
  if (yearTotalRowIndex === -1) {
    // Create 'Year Total' row and add it to the data
    const yearTotalRow = {
      month: 'Year Total',
      tasks: '',
      tickets: '',
      total_hours: 0
    };
    hot.alter('insert_row', data.length);
    hot.setDataAtRowProp(data.length, 'month', yearTotalRow.month, 'calculateYearlyTotal');
    yearTotalRowIndex = data.length;
  }
  // Use reduce to sum up the total hours, excluding 'Year Total' row
  const yearlyTotal = data.slice(0, yearTotalRowIndex).reduce((total, row) => {
    return total + (row.total_hours || 0);
  }, 0);
  // Update the 'Year Total' row
  hot.setDataAtRowProp(yearTotalRowIndex, 'total_hours', yearlyTotal, 'calculateYearlyTotal');
};


hotInstance = new Handsontable(container, {
  afterChange: (changes, source) => {
    if (source !== 'loadData' && source !== 'calculateYearlyTotal') {
      setTimeout(() => calculateYearlyTotal(hotInstance), 100);
    }
  },
  afterLoadData: function() {
    setTimeout(() => calculateYearlyTotal(hotInstance), 100)
  },
  columnSummary() {
  ....
© www.soinside.com 2019 - 2024. All rights reserved.