From 8010f17bb05a66771d521303d29729ffc5db7fbf Mon Sep 17 00:00:00 2001 From: Michael L Perry Date: Sun, 12 Jan 2025 20:36:23 -0600 Subject: [PATCH 1/2] Notebook extension to render a collection as a table --- Jinaga.Notebooks/DataFrameExtensions.cs | 57 ++++++++++++++++++++++++ Jinaga.Notebooks/Jinaga.Notebooks.csproj | 1 + 2 files changed, 58 insertions(+) create mode 100644 Jinaga.Notebooks/DataFrameExtensions.cs diff --git a/Jinaga.Notebooks/DataFrameExtensions.cs b/Jinaga.Notebooks/DataFrameExtensions.cs new file mode 100644 index 0000000..0aac959 --- /dev/null +++ b/Jinaga.Notebooks/DataFrameExtensions.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Microsoft.Data.Analysis; + +// Extension method to convert a list of objects into a DataFrame that the Notebook will display as a table. +public static class DataFrameExtensions +{ + public static DataFrame AsTable(this IEnumerable source) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + + var dataFrame = new DataFrame(); + var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); + + if (!properties.Any()) + throw new InvalidOperationException($"Type {typeof(T).Name} has no public instance properties."); + + // Create columns for each property + foreach (var prop in properties) + { + var propertyType = prop.PropertyType; + if (propertyType == typeof(string)) + { + var values = source.Select(item => (string)prop.GetValue(item)).ToList(); + dataFrame.Columns.Add(new StringDataFrameColumn(prop.Name, values)); + } + else if (propertyType == typeof(int) || propertyType == typeof(int?)) + { + var values = source.Select(item => (int?)prop.GetValue(item)).ToList(); + dataFrame.Columns.Add(new Int32DataFrameColumn(prop.Name, values)); + } + else if (propertyType == typeof(double) || propertyType == typeof(double?)) + { + var values = source.Select(item => (double?)prop.GetValue(item)).ToList(); + dataFrame.Columns.Add(new DoubleDataFrameColumn(prop.Name, values)); + } + else if (propertyType == typeof(bool) || propertyType == typeof(bool?)) + { + var values = source.Select(item => (bool?)prop.GetValue(item)).ToList(); + dataFrame.Columns.Add(new BooleanDataFrameColumn(prop.Name, values)); + } + else if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?)) + { + var values = source.Select(item => (DateTime?)prop.GetValue(item)).ToList(); + dataFrame.Columns.Add(new PrimitiveDataFrameColumn(prop.Name, values)); + } + else + throw new NotSupportedException($"Property type {propertyType.Name} is not supported."); + } + + return dataFrame; + } +} \ No newline at end of file diff --git a/Jinaga.Notebooks/Jinaga.Notebooks.csproj b/Jinaga.Notebooks/Jinaga.Notebooks.csproj index dd563f1..dbecca9 100644 --- a/Jinaga.Notebooks/Jinaga.Notebooks.csproj +++ b/Jinaga.Notebooks/Jinaga.Notebooks.csproj @@ -6,6 +6,7 @@ + From a1ee235468ae4cb8b2a3fa366d4ed233d09dec77 Mon Sep 17 00:00:00 2001 From: Michael L Perry Date: Sun, 12 Jan 2025 21:52:45 -0600 Subject: [PATCH 2/2] Move the extension to the Notebooks namespace --- Jinaga.Notebooks/DataFrameExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jinaga.Notebooks/DataFrameExtensions.cs b/Jinaga.Notebooks/DataFrameExtensions.cs index 0aac959..8c7924c 100644 --- a/Jinaga.Notebooks/DataFrameExtensions.cs +++ b/Jinaga.Notebooks/DataFrameExtensions.cs @@ -5,6 +5,8 @@ using Microsoft.Data.Analysis; +namespace Jinaga.Notebooks; + // Extension method to convert a list of objects into a DataFrame that the Notebook will display as a table. public static class DataFrameExtensions {