From 8321e14dfbf212810abd95d6176befad4c9de5f3 Mon Sep 17 00:00:00 2001
From: MarcosPierasNL <pieras.marcos@gmail.com>
Date: Fri, 1 Nov 2024 15:32:01 +0100
Subject: [PATCH] fix: adds count computation and count on other types

---
 libs/shared/lib/statistics/graphStatistics.ts          |  4 ++--
 libs/shared/lib/statistics/statistics.types.ts         |  2 ++
 .../shared/lib/statistics/tests/attributeStats.spec.ts | 10 ++++++----
 .../lib/statistics/utils/attributeStats/array.ts       |  1 +
 .../lib/statistics/utils/attributeStats/categorical.ts |  1 +
 .../lib/statistics/utils/attributeStats/initialize.ts  |  3 +++
 6 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libs/shared/lib/statistics/graphStatistics.ts b/libs/shared/lib/statistics/graphStatistics.ts
index 7f2db7998..8e1d79c18 100644
--- a/libs/shared/lib/statistics/graphStatistics.ts
+++ b/libs/shared/lib/statistics/graphStatistics.ts
@@ -10,12 +10,14 @@ const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics
 
   const density = n_nodes < 2 ? 0 : (n_edges * 2) / (n_nodes * (n_nodes - 1));
 
+  // general nodes and edges statistics
   const metaData: GraphStatistics = {
     topological: { density, self_loops: 0 },
     nodes: { labels: [], count: n_nodes, types: {} },
     edges: { labels: [], count: n_edges, types: {} },
   };
 
+  // attributes based statistics
   nodes.forEach((node) => {
     const nodeType = getNodeLabel(node);
     if (!metaData.nodes.labels.includes(nodeType)) {
@@ -25,7 +27,6 @@ const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics
     if (!metaData.nodes.types[nodeType]) {
       metaData.nodes.types[nodeType] = { count: 0, attributes: {} };
     }
-
     metaData.nodes.types[nodeType].count++;
 
     Object.entries(node.attributes).forEach(([attributeId, attributeValue]) => {
@@ -34,7 +35,6 @@ const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics
       if (!metaData.nodes.types[nodeType].attributes[attributeId]) {
         metaData.nodes.types[nodeType].attributes[attributeId] = { attributeType, statistics: initializeStatistics(attributeType) };
       }
-
       updateStatistics(metaData.nodes.types[nodeType].attributes[attributeId], attributeValue);
     });
   });
diff --git a/libs/shared/lib/statistics/statistics.types.ts b/libs/shared/lib/statistics/statistics.types.ts
index 78a0ee339..49d9274af 100644
--- a/libs/shared/lib/statistics/statistics.types.ts
+++ b/libs/shared/lib/statistics/statistics.types.ts
@@ -67,6 +67,7 @@ type CategoricalStats = {
   uniqueItems: number;
   values: string[];
   mode: string;
+  count: number;
 };
 
 type TemporalStats = {
@@ -77,6 +78,7 @@ type TemporalStats = {
 
 type ArrayStats = {
   length: number;
+  count: number;
 };
 
 type ObjectStats = {
diff --git a/libs/shared/lib/statistics/tests/attributeStats.spec.ts b/libs/shared/lib/statistics/tests/attributeStats.spec.ts
index da290a2d8..fc95f0f61 100644
--- a/libs/shared/lib/statistics/tests/attributeStats.spec.ts
+++ b/libs/shared/lib/statistics/tests/attributeStats.spec.ts
@@ -12,10 +12,11 @@ import type { ArrayStats, BooleanStats, CategoricalStats, NumericalStats, Tempor
 
 describe('updateArrayStats', () => {
   it('should update the length of the array', () => {
-    const stats: ArrayStats = { length: 0 };
+    const stats: ArrayStats = { length: 0, count: 0 };
     const value = [1, 2, 3];
     updateArrayStats(stats, value);
     expect(stats.length).toBe(3);
+    expect(stats.count).toBe(1);
   });
 });
 
@@ -37,7 +38,7 @@ describe('updateBooleanStats', () => {
 
 describe('updateCategoricalStats', () => {
   it('should update mode and unique items count', () => {
-    const stats: CategoricalStats = { uniqueItems: 0, values: [], mode: '' };
+    const stats: CategoricalStats = { uniqueItems: 0, values: [], mode: '', count: 0 };
     updateCategoricalStats(stats, 'apple');
     updateCategoricalStats(stats, 'banana');
     updateCategoricalStats(stats, 'apple');
@@ -45,6 +46,7 @@ describe('updateCategoricalStats', () => {
     expect(stats.values).toEqual(['apple', 'banana', 'apple']);
     expect(stats.uniqueItems).toBe(2);
     expect(stats.mode).toBe('apple');
+    expect(stats.count).toBe(3);
   });
 });
 
@@ -86,7 +88,7 @@ describe('updateObjectStats', () => {
 describe('initializeStatistics', () => {
   it('should initialize statistics for string type', () => {
     const stats = initializeStatistics('string');
-    expect(stats).toEqual({ uniqueItems: 0, values: [], mode: '' });
+    expect(stats).toEqual({ uniqueItems: 0, values: [], mode: '', count: 0 });
   });
 
   it('should initialize statistics for boolean type', () => {
@@ -96,7 +98,7 @@ describe('initializeStatistics', () => {
 
   it('should initialize statistics for number type', () => {
     const stats = initializeStatistics('number');
-    expect(stats).toEqual({ min: Infinity, max: -Infinity, average: 0 });
+    expect(stats).toEqual({ min: Infinity, max: -Infinity, average: 0, count: 0 });
   });
 
   it('should throw an error for an unknown type', () => {
diff --git a/libs/shared/lib/statistics/utils/attributeStats/array.ts b/libs/shared/lib/statistics/utils/attributeStats/array.ts
index c6a7dc55d..0cbea69b8 100644
--- a/libs/shared/lib/statistics/utils/attributeStats/array.ts
+++ b/libs/shared/lib/statistics/utils/attributeStats/array.ts
@@ -2,6 +2,7 @@ import { ArrayStats } from '../../statistics.types';
 
 const updateArrayStats = (stats: ArrayStats, value: any[]) => {
   stats.length = value.length;
+  stats.count++;
 };
 
 export { updateArrayStats };
diff --git a/libs/shared/lib/statistics/utils/attributeStats/categorical.ts b/libs/shared/lib/statistics/utils/attributeStats/categorical.ts
index fc9b128ce..e28b91aa6 100644
--- a/libs/shared/lib/statistics/utils/attributeStats/categorical.ts
+++ b/libs/shared/lib/statistics/utils/attributeStats/categorical.ts
@@ -11,6 +11,7 @@ const updateCategoricalStats = (stats: CategoricalStats, value: string | boolean
     frequencyMap[val] = (frequencyMap[val] || 0) + 1;
   });
   stats.mode = Object.keys(frequencyMap).reduce((a, b) => (frequencyMap[a] > frequencyMap[b] ? a : b));
+  stats.count++;
 };
 
 export { updateCategoricalStats };
diff --git a/libs/shared/lib/statistics/utils/attributeStats/initialize.ts b/libs/shared/lib/statistics/utils/attributeStats/initialize.ts
index 4f93930d5..c9b018646 100644
--- a/libs/shared/lib/statistics/utils/attributeStats/initialize.ts
+++ b/libs/shared/lib/statistics/utils/attributeStats/initialize.ts
@@ -7,6 +7,7 @@ const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeSt
         uniqueItems: 0,
         values: [],
         mode: '',
+        count: 0,
       } as unknown as AttributeTypeStats<T>;
     case 'boolean':
       return {
@@ -18,6 +19,7 @@ const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeSt
         min: Infinity,
         max: -Infinity,
         average: 0,
+        count: 0,
       } as unknown as AttributeTypeStats<T>;
     case 'date':
     case 'time':
@@ -31,6 +33,7 @@ const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeSt
     case 'array':
       return {
         length: 0,
+        count: 0,
       } as unknown as AttributeTypeStats<T>;
     case 'object':
       return {
-- 
GitLab