public function render()
    {
        /** @var Grid $grid */
        $grid = $this->root;
        $this->isTotalsCalculationFinished = true;
        $tr = $grid->getRecordView();
        // set total_row as current grid row
        $lastRow = $grid->getCurrentRow();
        $grid->setCurrentRow($this->totalData);

        // modify columns, prepare it for rendering totals row
        $valueCalculators = [];
        $valueFormatters = [];
        foreach ($grid->getColumns() as $column) {
            $valueCalculators[$column->getId()] = $column->getValueCalculator();
            $valueFormatters[$column->getId()] = $prevFormatter = $column->getValueFormatter();
            $column->setValueCalculator(null);
            $column->setValueFormatter(function ($value) use ($prevFormatter, $column) {
                $operation = $this->getOperation($column->getId());
                if ($prevFormatter && !($operation === static::OPERATION_IGNORE || $operation instanceof Closure)) {
                    $value = call_user_func($prevFormatter, $value);
                }
                // Add value prefix if specified for operation
                if ($value !== null && is_string($operation) && array_key_exists($operation, $this->valuePrefixes)) {
                    $value = $this->valuePrefixes[$operation] . '&nbsp;' . $value;
                }
                return $value;
            });
        }

        $output = $tr->render();

        // restore column value calculators & formatters
        foreach ($grid->getColumns() as $column) {
            $column->setValueCalculator($valueCalculators[$column->getId()]);
            $column->setValueFormatter($valueFormatters[$column->getId()]);
        }
        // restore last data row
        $grid->setCurrentRow($lastRow);
        return $output;
    }