From 185fb14b7a0d8b3c28dcd674c26ebc215610df5a Mon Sep 17 00:00:00 2001
From: MarcosPierasNL <pieras.marcos@gmail.com>
Date: Mon, 8 Jul 2024 12:29:11 +0200
Subject: [PATCH] feat: add hatching Nodata and correct text truncating

---
 .../paohvis/components/HyperRangeBlock.tsx    | 56 +++++++++++--------
 .../paohvis/components/RowLabels.tsx          | 54 +++++++++++-------
 .../paohvis/paohvis.stories.tsx               | 11 ++--
 .../vis/visualizations/paohvis/paohvis.tsx    | 12 +++-
 .../paohvis/utils/AttributesFilterUseCase.tsx |  1 +
 .../utils/CalcEntitiesFromQueryResult.tsx     | 22 --------
 6 files changed, 83 insertions(+), 73 deletions(-)
 delete mode 100644 libs/shared/lib/vis/visualizations/paohvis/utils/CalcEntitiesFromQueryResult.tsx

diff --git a/libs/shared/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx b/libs/shared/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx
index 04d1df800..330f79fc8 100644
--- a/libs/shared/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx
+++ b/libs/shared/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx
@@ -157,25 +157,35 @@ export const HyperEdgeRangesBlock: React.FC<HyperEdgeRangesBlockProps> = ({
               <g
                 key={'colsLabel col-' + indexRows}
                 className={'colsLabel col-' + indexRows}
-                transform={'translate(' + indexRows * rowHeight + ',' + 0 + ')rotate(-90,0,0)'}
+                transform={'translate(' + indexRows * rowHeight + ',0)rotate(-90,0,0)'}
               >
                 {columnHeaderInformation.map((row, index) => (
-                  <g key={'text-col-' + index} transform={'translate(' + (accumulatedWidthHeaders[index] + rowHeight) + ',' + 0 + ')'}>
-                    <rect
-                      width={0 === index ? row.width + rowHeight : row.width}
-                      height={rowHeight}
-                      fill={'hsl(var(--clr-sec--0))'}
-                      strokeWidth={0}
-                    ></rect>
-
-                    <foreignObject x="0" y="0" width={row.width} height={rowHeight}>
-                      <span className={`${classTopTextColumns}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
-                        {row.data[indexRows] !== undefined &&
-                        (typeof row.data[indexRows] !== 'object' || Array.isArray(row.data[indexRows]))
-                          ? (row.data[indexRows] as any).toString()
-                          : ' '}{' '}
-                      </span>
-                    </foreignObject>
+                  <g key={'text-col-' + index} transform={'translate(' + (accumulatedWidthHeaders[index] + rowHeight) + ',0)'}>
+                    {row.data[indexRows] !== undefined &&
+                    row.data[indexRows] !== '' &&
+                    (typeof row.data[indexRows] !== 'object' || Array.isArray(row.data[indexRows])) ? (
+                      <>
+                        <foreignObject x="0" y="0" width={0 === index ? row.width + rowHeight : row.width} height={rowHeight}>
+                          <div className="w-full h-full flex justify-center items-start">
+                            <span
+                              className={`${classTopTextColumns}`}
+                              style={{
+                                fontSize: `${adjustedFontSize}rem`,
+                              }}
+                            >
+                              {row.data[indexRows].toString()}
+                            </span>
+                          </div>
+                        </foreignObject>
+                      </>
+                    ) : (
+                      <rect
+                        width={0 === index ? row.width + rowHeight : row.width}
+                        height={rowHeight}
+                        fill={'url(#diagonal-lines)'}
+                        strokeWidth={0}
+                      ></rect>
+                    )}
                   </g>
                 ))}
               </g>
@@ -215,11 +225,13 @@ export const HyperEdgeRangesBlock: React.FC<HyperEdgeRangesBlockProps> = ({
               ></rect>
 
               <foreignObject x="0" y="0" width={headerData.width} height={rowHeight}>
-                <span className={`${classTopTextColumns}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
-                  {headerData.header !== undefined && (typeof headerData.header !== 'object' || Array.isArray(headerData.header))
-                    ? (headerData.header as any).toString()
-                    : ' '}
-                </span>
+                <div className="w-full h-full flex justify-left">
+                  <span className={`${classTopTextColumns}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
+                    {headerData.header !== undefined && (typeof headerData.header !== 'object' || Array.isArray(headerData.header))
+                      ? (headerData.header as any).toString()
+                      : ' '}
+                  </span>
+                </div>
               </foreignObject>
               {iconComponents[headerIndex] && isHovered && (
                 <svg
diff --git a/libs/shared/lib/vis/visualizations/paohvis/components/RowLabels.tsx b/libs/shared/lib/vis/visualizations/paohvis/components/RowLabels.tsx
index ca90d000c..dfa417fbc 100644
--- a/libs/shared/lib/vis/visualizations/paohvis/components/RowLabels.tsx
+++ b/libs/shared/lib/vis/visualizations/paohvis/components/RowLabels.tsx
@@ -95,21 +95,33 @@ export const RowLabels = ({
                 onMouseLeave={onMouseLeaveRowLabels}
               >
                 {dataRows.map((row, index) => (
-                  <g key={'´gRowTable-' + index} transform={'translate(' + accumulatedWidthHeaders[index] + ',' + 0 + ')'}>
-                    <rect
-                      width={dataRows.length - 1 === index ? row.width + rowHeight : row.width}
-                      height={rowHeight}
-                      fill={indexRows % 2 === 0 ? 'hsl(var(--clr-sec--50))' : 'hsl(var(--clr-sec--0))'}
-                      strokeWidth={0}
-                    ></rect>
-                    <foreignObject x="0" y="0" width={row.width} height={rowHeight}>
-                      <span className={`${classTopTextColums}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
-                        {row.data[indexRows] !== undefined &&
-                        (typeof row.data[indexRows] !== 'object' || Array.isArray(row.data[indexRows]))
-                          ? (row.data[indexRows] as any).toString()
-                          : ' '}
-                      </span>
-                    </foreignObject>
+                  <g key={'gRowTable-' + index} transform={'translate(' + accumulatedWidthHeaders[index] + ',0)'}>
+                    {row.data[indexRows] !== undefined &&
+                    row.data[indexRows] !== '' &&
+                    (typeof row.data[indexRows] !== 'object' || Array.isArray(row.data[indexRows])) ? (
+                      <>
+                        <rect
+                          width={dataRows.length - 1 === index ? row.width + rowHeight : row.width}
+                          height={rowHeight}
+                          fill={indexRows % 2 === 0 ? 'hsl(var(--clr-sec--50))' : 'hsl(var(--clr-sec--0))'}
+                          strokeWidth={0}
+                        ></rect>
+                        <foreignObject x="0" y="0" width={row.width} height={rowHeight}>
+                          <div className="w-full h-full flex justify-center items-start">
+                            <span className={`${classTopTextColums}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
+                              {row.data[indexRows].toString()}
+                            </span>
+                          </div>
+                        </foreignObject>
+                      </>
+                    ) : (
+                      <rect
+                        width={dataRows.length - 1 === index ? row.width + rowHeight : row.width}
+                        height={rowHeight}
+                        fill={'url(#diagonal-lines)'}
+                        strokeWidth={0}
+                      ></rect>
+                    )}
                   </g>
                 ))}
               </g>
@@ -174,11 +186,13 @@ export const RowLabels = ({
                   strokeWidth={0}
                 ></rect>
                 <foreignObject x="0" y="0" width={row.width} height={rowHeight}>
-                  <span className={`${classTopTextColums}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
-                    {row.header !== undefined && (typeof row.header !== 'object' || Array.isArray(row.header))
-                      ? (row.header as any).toString()
-                      : ' '}
-                  </span>
+                  <div className="w-full h-full flex justify-left">
+                    <span className={`${classTopTextColums}`} style={{ fontSize: `${adjustedFontSize}rem` }}>
+                      {row.header !== undefined && (typeof row.header !== 'object' || Array.isArray(row.header))
+                        ? (row.header as any).toString()
+                        : ' '}
+                    </span>
+                  </div>
                 </foreignObject>
                 {iconComponents[indexRows] && isHovered && (
                   <svg
diff --git a/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx b/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx
index 698e99865..c19a13caa 100644
--- a/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx
+++ b/libs/shared/lib/vis/visualizations/paohvis/paohvis.stories.tsx
@@ -39,8 +39,7 @@ export const TestWithMarieBoucherSample = {
     ...(await mockData.marieBoucherSample()),
     updateSettings: () => {},
     schema: marieBoucherSampleSchemaRaw,
-    //configuration: PaohVisComponent.configuration,
-    configuration: {
+    settings: {
       ...PaohVisComponent.settings,
       rowNode: 'merchant',
       columnNode: 'merchant',
@@ -53,10 +52,10 @@ export const TestWithBig2ndChamber = {
     ...(await mockData.big2ndChamberQueryResult()),
     updateSettings: () => {},
     schema: big2ndChamberSchemaRaw,
-    configuration: {
+    settings: {
       ...PaohVisComponent.settings,
-      rowNode: 'kamerleden',
-      columnNode: 'commissies',
+      rowNode: 'commissies',
+      columnNode: 'kamerleden',
     },
   },
 };
@@ -66,7 +65,7 @@ export const TestWithAirport = {
     ...(await mockData.bigMockQueryResults()),
     updateSettings: () => {},
     schema: simpleSchemaAirportRaw,
-    configuration: {
+    settings: {
       ...PaohVisComponent.settings,
       rowNode: 'airports',
       columnNode: 'airports',
diff --git a/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx b/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx
index 101103889..f9b08dadc 100644
--- a/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx
+++ b/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx
@@ -114,8 +114,7 @@ export const PaohVis = ({ data, graphMetadata, schema, settings, updateSettings
   const [widthTotalRowInformation, setWidthTotalRowInformation] = useState<number>(0);
   const [widthTotalColumnInformation, setWidthTotalColumnInformation] = useState<number>(0);
 
-  // text text-sm, font-semibold
-  const classTopTextColumns = 'font-inter font-medium stroke-none text-secondary-800 mx-1 flex items-center truncate';
+  const classTopTextColumns = 'text-secondary-800 mx-1 overflow-hidden whitespace-nowrap text-ellipsis';
 
   const configStyle = {
     colorText: 'hsl(var(--clr-sec--800))',
@@ -515,7 +514,6 @@ export const PaohVis = ({ data, graphMetadata, schema, settings, updateSettings
 
     let columnNodeAttributes;
     let rowNodeAttributes;
-
     if (graphMetadata != undefined) {
       labelEdge = graphMetadata.edges.labels[0];
       edgeSchema = schema.edges.find((obj) => String(obj.key).includes(labelEdge));
@@ -538,6 +536,7 @@ export const PaohVis = ({ data, graphMetadata, schema, settings, updateSettings
     }
 
     const newData = parseQueryResult(data, settings as PaohVisProps, toNode, settings.mergeData);
+
     // original data without slicing
     setNumRowsVisible(Math.min(configPaohvis.rowsMaxPerPage, newData.rowLabels.length));
 
@@ -848,6 +847,13 @@ export const PaohVis = ({ data, graphMetadata, schema, settings, updateSettings
         }}
         onWheel={onWheel}
       >
+        <defs>
+          <pattern id="diagonal-lines" patternUnits="userSpaceOnUse" width="8" height="8">
+            <rect width="8" height="8" fill="#eaeaea" />
+            <path d="M0,0 L8,8 M-2,2 L2,-2 M6,10 L10,6" stroke="lightgray" strokeWidth="1" />
+          </pattern>
+        </defs>
+
         <RowLabels
           dataRows={informationRow}
           rowHeight={settings.rowHeight}
diff --git a/libs/shared/lib/vis/visualizations/paohvis/utils/AttributesFilterUseCase.tsx b/libs/shared/lib/vis/visualizations/paohvis/utils/AttributesFilterUseCase.tsx
index 4c0abd1e3..0b824f9b5 100644
--- a/libs/shared/lib/vis/visualizations/paohvis/utils/AttributesFilterUseCase.tsx
+++ b/libs/shared/lib/vis/visualizations/paohvis/utils/AttributesFilterUseCase.tsx
@@ -53,6 +53,7 @@ export default class AttributeFilterUsecase {
 }
 
 /** Filters the given array on the designated boolean attribute with the given predicate. */
+
 function filterBoolAttributes<T extends Node | Edge>(axisNodesOrEdges: T[], filter: FilterInfo): T[] {
   const predicate = boolPredicates[filter.predicateName];
   if (predicate == undefined) throw new Error('Predicate does not exist');
diff --git a/libs/shared/lib/vis/visualizations/paohvis/utils/CalcEntitiesFromQueryResult.tsx b/libs/shared/lib/vis/visualizations/paohvis/utils/CalcEntitiesFromQueryResult.tsx
deleted file mode 100644
index ff160f5c0..000000000
--- a/libs/shared/lib/vis/visualizations/paohvis/utils/CalcEntitiesFromQueryResult.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * This program has been developed by students from the bachelor Computer Science at
- * Utrecht University within the Software Project course.
- * © Copyright Utrecht University (Department of Information and Computing Sciences)
- */
-
-import { GraphQueryResult } from '@graphpolaris/shared/lib/data-access';
-import { getGroupName } from './ResultNodeLinkParserUseCase';
-
-/**
- * This calculates all entities from the query result.
- * @param {NodeLinkResultType} message This is the message with all the information about the entities and relations.
- * @returns {string[]} All names of the entities which are in the query result.
- */
-export function calcEntitiesFromQueryResult(message: GraphQueryResult): string[] {
-  const entityTypesFromQueryResult: string[] = [];
-  message.nodes.forEach((node) => {
-    const group = getGroupName(node);
-    if (!entityTypesFromQueryResult.includes(group)) entityTypesFromQueryResult.push(group);
-  });
-  return entityTypesFromQueryResult;
-}
-- 
GitLab