
# Total and Subtotal

You can print totals and subtotals in rows and columns.

You can print values ​​such as minimum, maximum, average, and total in the footer area.

```js
const fields = [
  { fieldName: 'Type' },
  { fieldName: 'Survey Year' },
  { fieldName: 'Affiliated Institution' },
  { fieldName: 'Facility Name' },
  { fieldName: 'Fuel Name' },
  { fieldName: 'AJan', dataType: 'number' },
  { fieldName: 'AFeb', dataType: 'number' },
  { fieldName: 'AMar', dataType: 'number' },
  { fieldName: 'AApr', dataType: 'number' },
  { fieldName: 'AMay', dataType: 'number' },
  { fieldName: 'AJun', dataType: 'number' },
  { fieldName: 'AJul', dataType: 'number' },
  { fieldName: 'AAug', dataType: 'number' },
  { fieldName: 'ASep', dataType: 'number' },
  { fieldName: 'AOct', dataType: 'number' },
  { fieldName: 'ANov', dataType: 'number' },
  { fieldName: 'ADec', dataType: 'number' },
  { 
    fieldName: 'Total', 
    dataType: 'number', 
    valueExpression: "values['AJan'] + values['AFeb'] + values['AMar'] + values['AApr']+ values['AMay']+ values['AJun']+ values['AJul']+ values['AAug']+ values['ASep']+ values['AOct']+ values['ANov']+ values['ADec']"
  }
];

const headerSummaryCallback = [{
  numberFormat: '#,##0.0',
  valueCallback: function (grid, column, childIndex, summary, value) {
    if (dataProvider.getRowCount() > 0) {
      let fuel = 0;
      for (let i = 0; i < dataProvider.getRowCount(); i++) {
        if (dataProvider.getValue(i, 'Fuel Name') == 'Gas/Diesel Oil (Diesel)') {
          if (fuel < dataProvider.getValue(i, summary.column.fieldName)) {
            fuel = dataProvider.getValue(i, summary.column.fieldName);
          }
        }
      }
      return fuel;
    }
  }
}, {
  numberFormat: '#,##0.0',
  valueCallback: function (grid, column, childIndex, summary, value) {
    if (dataProvider.getRowCount() > 0) {
      let fuel = 0;
      for (let i = 0; i < dataProvider.getRowCount(); i++) {
        if (dataProvider.getValue(i, 'Fuel Name') == 'Gasoline') {
          if (fuel < dataProvider.getValue(i, summary.column.fieldName)) {
            fuel = dataProvider.getValue(i, summary.column.fieldName);
          }
        }
      }
      return fuel;
    }
  }
}];

const footersValueCallback = [{
  valueCallback: function (grid, column, footerIndex, columnFooter, value) {
    let sum = 0;
    for (let i = 0; i < dataProvider.getRowCount(); i++) {
      if (dataProvider.getValue(i, 'Fuel Name') == 'City Gas (LNG)') {
        sum += dataProvider.getValue(i, columnFooter.column.fieldName);
      }
    }
    return sum;
  },
  numberFormat: '#,##0.0'
}, {
  valueCallback: function (grid, column, footerIndex, columnFooter, value) {
    let sum = 0;
    for (let i = 0; i < dataProvider.getRowCount(); i++) {
      if (dataProvider.getValue(i, 'Fuel Name') == 'Electricity') {
        sum += dataProvider.getValue(i, columnFooter.column.fieldName);
      }
    }
    return sum;
  },
  numberFormat: '#,##0.0'
}, {
  valueCallback: function (grid, column, footerIndex, columnFooter, value) {
    let sum = 0;
    for (let i = 0; i < dataProvider.getRowCount(); i++) {
      if (dataProvider.getValue(i, 'Fuel Name') == 'Gas/Diesel Oil (Diesel)') {
        sum += dataProvider.getValue(i, columnFooter.column.fieldName);
      }
    }
    return sum;
  },
  numberFormat: '#,##0.0'
}, {
  valueCallback: function (grid, column, footerIndex, columnFooter, value) {
    let sum = 0;
    for (let i = 0; i < dataProvider.getRowCount(); i++) {
      if (dataProvider.getValue(i, 'Fuel Name') == 'Gasoline') {
        sum += dataProvider.getValue(i, columnFooter.column.fieldName);
      }
    }
    return sum;
  },
  numberFormat: '#,##0.0'
}];

const columns = [
  { name: 'Type', fieldName: 'Type', width: 85 },
  { name: 'Survey Year', fieldName: 'Survey Year', width: 60 },
  { name: 'Affiliated Institution', fieldName: 'Affiliated Institution', width: 85 },
  { name: 'Facility Name', fieldName: 'Facility Name', width: 106, footer: { text: 'Total' } },
  { 
    name: 'Fuel Name', 
    fieldName: 'Fuel Name', 
    width: 109,
    headerSummary: [{ text: 'Max Diesel Usage' }, { text: 'Max Gasoline Usage' }],
    footers: [{ text: 'City Gas (LNG)' }, { text: 'Electricity' }, { text: 'Gas/Diesel Oil' }, { text: 'Gasoline' }]
  },
  { name: 'AJan', fieldName: 'AJan', header: { text: 'Jan' }, width: 73, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AFeb', fieldName: 'AFeb', header: { text: 'Feb' }, width: 73, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AMar', fieldName: 'AMar', header: { text: 'Mar' }, width: 73, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AApr', fieldName: 'AApr', header: { text: 'Apr' }, width: 73, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AMay', fieldName: 'AMay', header: { text: 'May' }, width: 73, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AJun', fieldName: 'AJun', header: { text: 'Jun' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AJul', fieldName: 'AJul', header: { text: 'Jul' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AAug', fieldName: 'AAug', header: { text: 'Aug' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'ASep', fieldName: 'ASep', header: { text: 'Sep' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'AOct', fieldName: 'AOct', header: { text: 'Oct' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'ANov', fieldName: 'ANov', header: { text: 'Nov' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  { name: 'ADec', fieldName: 'ADec', header: { text: 'Dec' }, width: 75, styleName: 'right-column', headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: '#,##0.0' },
  {
    name: 'colLine',
    type: 'series',
    fieldNames: 'AJan..ADec',
    width: 120,
    renderer: {
      type: 'sparkcolumn',
      highFill: '#ff008800',
      lowFill: '#ffff0000',
      lastFill: '#ff888888'
    },
    header: { text: 'Graph' }
  },
  { 
    name: 'Total', 
    fieldName: 'Total', 
    width: 75, 
    styleName: 'right-column',
    headerSummary: [{
      valueCallback: function (grid, column, childIndex, summary, value) {
      }
    }, {
      valueCallback: function (grid, column, childIndex, summary, value) {
      }
    }],
    footers: footersValueCallback
  }
];

const layout = [
  { column: 'Facility Name', footerUserSpans: [{ rowspan: 4 }], summaryUserSpans: [{ rowspan: 2 }] },
  { column: 'Fuel Name' },
  { column: 'AJan' },
  { column: 'AFeb' },
  { column: 'AMar' },
  { column: 'AApr' },
  { column: 'AMay' },
  { column: 'AJun' },
  { column: 'AJul' },
  { column: 'AAug' },
  { column: 'ASep' },
  { column: 'AOct' },
  { column: 'ANov' },
  { column: 'ADec' },
  { column: 'colLine' },
  'Total'
];

function strToFloat(numText) {
  if (!numText) {
    return 0;
  }
  return parseFloat(numText.replace(/,/g, ''));
}

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: 40
  },
  headerSummaries: {
    visible: true,
    items: [
      {
        styleName: 'multiline-cell',
        height: 30
      },
      {
        styleName: 'multiline-cell',
        height: 30
      }
    ]
  },
  footers: {
    visible: true,
    items: [
      {
        height: 30
      },
      {
        height: 30
      },
      {
        height: 30
      },
      {
        height: 30
      }
    ]
  },
  display: {
    rowHeight: 30,
    emptyMessage: 'No data to display.'
  },
  edit: {
    commitByCell: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  fixedOptions: {
    resizable: true,
    rightCount: 1,
    colCount: 2,
    colBarWidth: 0,
    rightBarWidth: 1
  },
  rowIndicator: {
    footText: '',
    sumText: ''
  },
  onInitialized: (grid) => {
    fetch('/data/en/co2data.json')
      .then(response => response.json())
      .then(jsonData => {
        let data = jsonData;
        if (typeof data != 'object') {
          data = JSON.parse(data);
        }
        for (let i = 0; i <= data.records.length - 1; i++) {
          if (!data.records[i]['Target Institution']) {
            data.records[i]['Unit'] = data.records[i]['AJan'];
            data.records[i]['AJan'] = data.records[i]['AFeb'];
            data.records[i]['AFeb'] = data.records[i]['AMar'];
            data.records[i]['AMar'] = data.records[i]['AApr'];
            data.records[i]['AApr'] = data.records[i]['AMay'];
            data.records[i]['AMay'] = data.records[i]['AJun'];
            data.records[i]['AJun'] = data.records[i]['AJul'];
            data.records[i]['AJul'] = data.records[i]['AAug'];
            data.records[i]['AAug'] = data.records[i]['ASep'];
            data.records[i]['ASep'] = data.records[i]['AOct'];
            data.records[i]['AOct'] = data.records[i]['ANov'];
            data.records[i]['ANov'] = data.records[i]['ADec'];
            data.records[i]['ADec'] = data.records[i]['Org Code'];
            data.records[i]['Org Code'] = '';
          }
          data.records[i]['AJan'] = strToFloat(data.records[i]['AJan']);
          data.records[i]['AFeb'] = strToFloat(data.records[i]['AFeb']);
          data.records[i]['AMar'] = strToFloat(data.records[i]['AMar']);
          data.records[i]['AApr'] = strToFloat(data.records[i]['AApr']);
          data.records[i]['AMay'] = strToFloat(data.records[i]['AMay']);
          data.records[i]['AJun'] = strToFloat(data.records[i]['AJun']);
          data.records[i]['AJul'] = strToFloat(data.records[i]['AJul']);
          data.records[i]['AAug'] = strToFloat(data.records[i]['AAug']);
          data.records[i]['ASep'] = strToFloat(data.records[i]['ASep']);
          data.records[i]['AOct'] = strToFloat(data.records[i]['AOct']);
          data.records[i]['ANov'] = strToFloat(data.records[i]['ANov']);
          data.records[i]['ADec'] = strToFloat(data.records[i]['ADec']);
        }
        grid.getDataSource().setRows(data.records);
        gridView.setColumnLayout(layout);
        gridView.refresh();
      });
  }
}, {
  fields
});

window.gridView = gridView;
window.dataProvider = dataProvider;
```


Calculate required values ​​and output maximum values ​​using valueCallback in summary and footer areas.

```js
//summary 영역 최고사용량
var headerSummaryCallback = [{
  numberFormat: "#,##0.0",
  valueCallback: function (grid, column, childIndex, summary, value) {
    if(dataProvider.getRowCount() > 0){
      var fuel = 0;
      for(var i = 0; i < dataProvider.getRowCount(); i++){
        if(dataProvider.getValue(i, "연료명") == "가스/디젤 오일(경유)"){
          if(fuel < dataProvider.getValue(i, summary.column.fieldName)){
            fuel = dataProvider.getValue(i, summary.column.fieldName)
          }
        }
      }
      return fuel;
    }
  }
},{
  numberFormat: "#,##0.0",
  valueCallback: function (grid, column, childIndex, summary, value) {
    if(dataProvider.getRowCount() > 0){
      var fuel = 0;
      for(var i = 0; i < dataProvider.getRowCount(); i++){
        if(dataProvider.getValue(i, "연료명") == "휘발유"){
          if(fuel < dataProvider.getValue(i, summary.column.fieldName)){
            fuel = dataProvider.getValue(i, summary.column.fieldName)
          }
        }
      }
      return fuel;
    }
  }
}];

//footerCallback 공통
var footersValueCallback = [
  { 
  valueCallback: function (grid, column, footerIndex, columnFooter, value) {
    var sum = 0;
    for(var i = 0; i < dataProvider.getRowCount(); i++){
      if(dataProvider.getValue(i, "연료명") == "도시가스(LNG)"){
        sum += dataProvider.getValue(i, columnFooter.column.fieldName);
      }
    }
    return sum;
  }, numberFormat: "#,##0.0" },
  { 
    valueCallback: function (grid, column, footerIndex, columnFooter, value) {
      var sum = 0;
    for(var i = 0; i < dataProvider.getRowCount(); i++){
      if(dataProvider.getValue(i, "연료명") == "전기"){
        sum += dataProvider.getValue(i, columnFooter.column.fieldName);
      }
    }
    return sum;
    }, numberFormat: "#,##0.0" 
  },
  { 
    valueCallback: function (grid, column, footerIndex, columnFooter, value) {
      var sum = 0;
      for(var i = 0; i < dataProvider.getRowCount(); i++){
        if(dataProvider.getValue(i, "연료명") == "가스/디젤 오일(경유)"){
          sum += dataProvider.getValue(i, columnFooter.column.fieldName);
        }
      }
      return sum;
      }, numberFormat: "#,##0.0" 
  },
  { 
    valueCallback: function (grid, column, footerIndex, columnFooter, value) {
      var sum = 0;
      for(var i = 0; i < dataProvider.getRowCount(); i++){
        if(dataProvider.getValue(i, "연료명") == "휘발유"){
          sum += dataProvider.getValue(i, columnFooter.column.fieldName);
        }
      }
      return sum;
    }, numberFormat: "#,##0.0" 
  }
]

//컬럼 설정
var columns = [{ name: "구분", fieldName: "구분", "width": 85 },
  { name: "조사년도", fieldName: "조사년도", "width": 60 },
  { name: "소속기관명", fieldName: "소속기관명", "width": 85 },
  { name: "시설명", fieldName: "시설명", wdith: 85 },
  { name: "연료명", fieldName: "연료명", "width": 90 },
  {
      name: "colLine", "type": "series", "fieldNames": "A01월..A12월", "width": 120,
      renderer: {
          "type": "sparkcolumn",
          "highFill": "#ff008800",
          "lowFill": "#ffff0000",
          "lastFill": "#ff888888"
      },
      header: { "text": "그래프" },
      headerSummary:[{ text: "경유 최고 사용량"},{text: "휘발유 최고 사용량"}],
      footers: [{text:"도시가스(LNG)"},{text:"전기"},{text:"가스/디젤 오일(경유)"},{text:"휘발유"}]
  },
  { name: "A01월", fieldName: "A01월",  header: { text: "01월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A02월", fieldName: "A02월",  header: { text: "02월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A03월", fieldName: "A03월",  header: { text: "03월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A04월", fieldName: "A04월",  header: { text: "04월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A05월", fieldName: "A05월",  header: { text: "05월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A06월", fieldName: "A06월",  header: { text: "06월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A07월", fieldName: "A07월",  header: { text: "07월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A08월", fieldName: "A08월",  header: { text: "08월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A09월", fieldName: "A09월",  header: { text: "09월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A10월", fieldName: "A10월",  header: { text: "10월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A11월", fieldName: "A11월",  header: { text: "11월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "A12월", fieldName: "A12월",  header: { text: "12월" }, "width": 70,  styleName: "right-column", headerSummary: headerSummaryCallback, footers: footersValueCallback, numberFormat: "#,##0.0" },
  { name: "합계", fieldName: "합계", width: 75, styleName: "right-column", footers: footersValueCallback }
];
```
