/**
  * Apply default settings to rowFields and dataFields if needed
  * @throws NoDataFieldsException If there are no row fields
  * @throws Exception if the DataTable cannot answer this pivot request
  */
 protected function fixupFields()
 {
     $this->isFixed = true;
     // If they didn't give us any column fields, there is nothing to pivot!
     if (empty($this->columnFields)) {
         return;
     }
     // If they didn't give us any row fields, by default the first field is the row field
     if ($this->rowFields === null) {
         $this->rowFields = array($this->dataTable->getColumnDescription(0)->getId());
     }
     // If they didn't give us any data fields, by default ALL fields that are neither
     // column fields nor row fields are data fields
     if ($this->dataFields === null) {
         $dataFields = array();
         $allColumnIds = $this->getAllColumnIds($this->dataTable->getColumnDescriptions());
         foreach ($allColumnIds as $fieldId) {
             if (!in_array($fieldId, $this->columnFields) && !in_array($fieldId, $this->rowFields)) {
                 $dataFields[] = $fieldId;
             }
         }
         $this->dataFields = $dataFields;
     }
     if (count($this->dataFields) === 0) {
         throw new NoDataFieldsException();
     }
     // Verify that the same field is not specified in multiple types
     $this->verifyNoDuplicateFields($this->columnFields, $this->rowFields, 'column', 'row');
     $this->verifyNoDuplicateFields($this->columnFields, $this->dataFields, 'column', 'data');
     $this->verifyNoDuplicateFields($this->rowFields, $this->dataFields, 'row', 'data');
     // Verify the minimum number of fields exist in this DataTable to perform this pivot
     $numColumns = $this->dataTable->getNumberOfColumns();
     $minimumNumColumns = count($this->columnFields) + count($this->rowFields) + count($this->dataFields);
     if ($numColumns < $minimumNumColumns) {
         throw new Exception("Not enough columns in this DataTable to pivot (you have " . $numColumns . ", minimum is " . $minimumNumColumns . ")");
     }
 }
 public function addOutputRows(DataTable &$dataOut)
 {
     $dataIn =& $this->pivotDescription->getDataTable();
     $columns = $dataOut->getColumnDescriptions();
     foreach ($this->table as $rk => $rowTable) {
         $row = new TableRow();
         foreach ($columns as $column) {
             $ck = $column->getCustomProperty('columnKeyId');
             if ($ck === null) {
                 $rowKey = $this->rowKeyIndex->getKeyRefByHash($rk);
                 $firstRowIndex = $rowKey->getFirstRowIndex();
                 $rowFieldIndex = $column->getCustomProperty('rowFieldIndex');
                 $cell = $dataIn->getRow($firstRowIndex)->getCell($rowFieldIndex);
                 $row->addCell($cell);
             } else {
                 // This is a computed data field
                 $di = $column->getCustomProperty('dataFieldIndex');
                 if (isset($this->table[$rk][$ck][$di])) {
                     $dataContainer = $this->table[$rk][$ck][$di];
                     $value = $dataContainer->getComputedValue();
                 } else {
                     $value = ValueFactory::constructNull($column->getType());
                 }
                 $row->addCell($value);
             }
         }
         $dataOut->addRow($row);
     }
 }
 public function testGetColumnDescriptions()
 {
     $data = new DataTable();
     $col0 = new ColumnDescription('foo', ValueType::STRING);
     $col1 = new ColumnDescription('bar', ValueType::NUMBER);
     $data->addColumns(array($col0, $col1));
     $columns = $data->getColumnDescriptions();
     $this->assertSame(2, count($columns), "data must contain 2 columns");
     $this->assertEquals($col0, $columns[0], "first column id must match");
     $this->assertEquals($col1, $columns[1], "first column id must match");
 }
 /**
  * @param DataTable $dataTable
  * @param bool $includeValues [optional]
  * @param bool $includeFormatting [optional]
  * @param bool $renderDateAsDateConstructor [optional]
  * @return string JSON encoded string describing $dataTable
  */
 public function renderDataTable(DataTable $dataTable, $includeValues = true, $includeFormatting = true, $renderDateAsDateConstructor = true)
 {
     $numColumns = $dataTable->getNumberOfColumns();
     $columns = $dataTable->getColumnDescriptions();
     $output = "{";
     $output .= "\"cols\":[";
     for ($i = 0; $i < $numColumns; $i++) {
         $column = $columns[$i];
         $output .= $this->renderColumnDescriptionJson($column);
         if ($i + 1 < $numColumns) {
             $output .= ",";
         }
     }
     $output .= "]";
     if ($includeValues) {
         $numRows = $dataTable->getNumberOfRows();
         $output .= ",\"rows\":[";
         for ($ri = 0; $ri < $numRows; $ri++) {
             $row = $dataTable->getRow($ri);
             $numCells = $row->getNumberOfCells();
             $output .= "{\"c\":[";
             for ($ci = 0; $ci < $numCells; $ci++) {
                 $cell = $row->getCell($ci);
                 if ($ci + 1 < $numCells) {
                     // For fields that are NOT the last field, renderCellJson() may return
                     // an empty string if the value is NULL
                     // @see https://code.google.com/p/google-visualization-java/source/browse/trunk/src/main/java/com/google/visualization/datasource/render/JsonRenderer.java
                     $cellOutput = $this->renderCellJson($cell, $includeFormatting, $this->optimizeNullValues, $renderDateAsDateConstructor);
                     $cellOutput .= ",";
                 } else {
                     // For fields that ARE the last field, a JSON string is returned
                     // even for NULL values
                     $cellOutput = $this->renderCellJson($cell, $includeFormatting, false, $renderDateAsDateConstructor);
                 }
                 $output .= $cellOutput;
             }
             $output .= "]";
             // Row properties
             $customProperties = $this->renderCustomPropertiesString($row->getCustomProperties());
             if ($customProperties !== null) {
                 $output .= ",\"p\":" . $customProperties;
             }
             $output .= "}";
             if ($ri + 1 < $numRows) {
                 $output .= ",";
             }
         }
         $output .= "]";
     }
     // Table properties
     $customProperties = $this->renderCustomPropertiesString($dataTable->getCustomProperties());
     if ($customProperties !== null) {
         $output .= ",\"p\":" . $customProperties;
     }
     $output .= "}";
     return $output;
 }
 public function testVerifyFieldNamesDoesNotThrowForValidNames()
 {
     $pivot = new PivotDescription($this->dataTable);
     $allColumnIds = $pivot->getAllColumnIds($this->dataTable->getColumnDescriptions());
     $pivot->verifyTheseFieldsExist($allColumnIds, 'test');
 }