/// <summary> /// Copies from another instance. /// </summary> /// <param name="obj">The object to copy from.</param> /// <returns><c>True</c> if anything could be copied from the object, otherwise <c>false</c>.</returns> public bool CopyFrom(object obj) { if (object.ReferenceEquals(this, obj)) { return(true); } var from = obj as DataTableTransposeDataSource; if (null != from) { using (var token = SuspendGetToken()) { DataTableTransposeOptions dataSourceOptions = null; DataTableProxy inputData = null; IDataSourceImportOptions importOptions = null; CopyHelper.Copy(ref importOptions, from._importOptions); CopyHelper.Copy(ref dataSourceOptions, from._processOptions); CopyHelper.Copy(ref inputData, from._processData); TransposeOptions = dataSourceOptions; ImportOptions = importOptions; InputData = inputData; return(true); } } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="DataTableTransposeDataSource"/> class. /// </summary> /// <param name="inputData">The input data designates the original source of data (used then for the processing).</param> /// <param name="dataSourceOptions">The Fourier transformation options.</param> /// <param name="importOptions">The data source import options.</param> /// <exception cref="System.ArgumentNullException"> /// inputData /// or /// transformationOptions /// or /// importOptions /// </exception> public DataTableTransposeDataSource(DataTableProxy inputData, DataTableTransposeOptions dataSourceOptions, IDataSourceImportOptions importOptions) { if (null == inputData) { throw new ArgumentNullException(nameof(inputData)); } if (null == dataSourceOptions) { throw new ArgumentNullException(nameof(dataSourceOptions)); } if (null == importOptions) { throw new ArgumentNullException(nameof(importOptions)); } using (var token = SuspendGetToken()) { TransposeOptions = dataSourceOptions; ImportOptions = importOptions; InputData = inputData; } }
/// <summary> /// Transpose transpose the table, i.e. exchange columns and rows /// this can only work if all columns in the table are of the same type /// </summary> /// <param name="srcTable">Table to transpose.</param> /// <param name="options">Options that control the transpose process.</param> /// <param name="destTable">Table in which the transposed table should be stored.</param> /// <exception cref="ArgumentNullException"> /// </exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="InvalidOperationException">The data columns to transpose are not of the same type. The first column that has a deviating type is column number + firstDifferentColumnIndex.ToString()</exception> public static void Transpose(this DataTable srcTable, DataTableTransposeOptions options, DataTable destTable) { if (null == srcTable) { throw new ArgumentNullException(nameof(srcTable)); } if (null == destTable) { throw new ArgumentNullException(nameof(destTable)); } if (object.ReferenceEquals(srcTable, destTable)) { throw new ArgumentException(nameof(srcTable) + " and " + nameof(destTable) + " are identical. This inline transpose operation is not supported."); } int numberOfDataColumnsChangeToPropertyColumns = Math.Min(options.DataColumnsMoveToPropertyColumns, srcTable.DataColumnCount); int numberOfPropertyColumnsChangeToDataColumns = Math.Min(options.PropertyColumnsMoveToDataColumns, srcTable.PropertyColumnCount); // number of data columns in the destination table that originates either from converted property columns or from the label column which contains the column names int numberOfPriorDestDataColumns = numberOfPropertyColumnsChangeToDataColumns + (options.StoreDataColumnNamesInFirstDataColumn ? 1 : 0); var dataColumnsToTransposeIndices = ContiguousIntegerRange.FromStartAndEndExclusive(numberOfDataColumnsChangeToPropertyColumns, srcTable.DataColumnCount); if (!AreAllColumnsOfTheSameType(srcTable.DataColumns, dataColumnsToTransposeIndices, out var firstDifferentColumnIndex)) { throw new InvalidOperationException("The data columns to transpose are not of the same type. The first column that has a deviating type is column number " + firstDifferentColumnIndex.ToString()); } using (var suspendToken = destTable.SuspendGetToken()) { destTable.DataColumns.ClearData(); destTable.PropCols.ClearData(); // 0th, store the data column names in the first column if (options.StoreDataColumnNamesInFirstDataColumn) { var destCol = destTable.DataColumns.EnsureExistenceAtPositionStrictly(0, "DataColumnNames", typeof(TextColumn), ColumnKind.Label, 0); for (int j = numberOfDataColumnsChangeToPropertyColumns, k = 0; j < srcTable.DataColumnCount; ++j, ++k) { destCol[k] = srcTable.DataColumns.GetColumnName(j); } } int numberOfExtraPriorDestColumns = (options.StoreDataColumnNamesInFirstDataColumn ? 1 : 0); // 1st, copy the property columns to data columns for (int i = 0; i < numberOfPropertyColumnsChangeToDataColumns; ++i) { var destCol = destTable.DataColumns.EnsureExistenceAtPositionStrictly(i + numberOfExtraPriorDestColumns, srcTable.PropertyColumns.GetColumnName(i), srcTable.PropertyColumns[i].GetType(), srcTable.PropertyColumns.GetColumnKind(i), srcTable.PropertyColumns.GetColumnGroup(i)); var srcCol = srcTable.PropertyColumns[i]; for (int j = numberOfDataColumnsChangeToPropertyColumns, k = 0; j < srcCol.Count; ++j, ++k) { destCol[k] = srcCol[j]; } } // 2rd, transpose the data columns int srcRows = 0; foreach (int i in dataColumnsToTransposeIndices) { srcRows = Math.Max(srcRows, srcTable.DataColumns[i].Count); } // create as many columns in destTable as srcRows and fill them with data Type columnType = dataColumnsToTransposeIndices.Count > 0 ? srcTable.DataColumns[dataColumnsToTransposeIndices[0]].GetType() : null; for (int i = 0; i < srcRows; ++i) { string destColName = string.Format("{0}{1}", options.ColumnNamingPreString, i); if (options.UseFirstDataColumnForColumnNaming) { destColName = string.Format("{0}{1}", options.ColumnNamingPreString, srcTable.DataColumns[0][i]); } var destCol = destTable.DataColumns.EnsureExistenceAtPositionStrictly(numberOfPriorDestDataColumns + i, destColName, false, columnType, ColumnKind.V, 0); int k = 0; foreach (int j in dataColumnsToTransposeIndices) { destCol[k++] = srcTable.DataColumns[j][i]; } } // 3rd, copy the first data columns to property columns for (int i = 0; i < numberOfDataColumnsChangeToPropertyColumns; ++i) { var destCol = destTable.PropertyColumns.EnsureExistenceAtPositionStrictly(i, srcTable.DataColumns.GetColumnName(i), srcTable.DataColumns[i].GetType(), srcTable.DataColumns.GetColumnKind(i), srcTable.DataColumns.GetColumnGroup(i)); var srcCol = srcTable.DataColumns[i]; for (int j = numberOfPriorDestDataColumns, k = 0; k < srcCol.Count; ++j, ++k) { destCol[j] = srcCol[k]; } } // 4th, fill the rest of the property columns with the rest of the data columns for (int i = 0; i < numberOfDataColumnsChangeToPropertyColumns; ++i) { for (int j = 0; j < numberOfPropertyColumnsChangeToDataColumns; ++j) { try { destTable.PropertyColumns[i][j + numberOfExtraPriorDestColumns] = srcTable.PropertyColumns[j][i]; } catch { } } } // and 5th, copy the remaining property columns to property columns for (int i = numberOfPropertyColumnsChangeToDataColumns, j = numberOfDataColumnsChangeToPropertyColumns; i < srcTable.PropertyColumns.ColumnCount; ++i, ++j) { var destCol = destTable.PropertyColumns.EnsureExistenceAtPositionStrictly(j, srcTable.PropertyColumns.GetColumnName(i), false, srcTable.PropertyColumns[i].GetType(), srcTable.PropertyColumns.GetColumnKind(i), srcTable.DataColumns.GetColumnGroup(i)); destCol.Data = srcTable.PropertyColumns[i]; } suspendToken.Resume(); } }