From 996409dc5775d7efa0d43e2735f3b8ceb654b96c Mon Sep 17 00:00:00 2001 From: trbKnl Date: Thu, 31 Oct 2024 13:21:33 +0100 Subject: [PATCH] pd.DataFrame serialization and deserialization is too slow and is not needed, allow for dict objects directly without getting in the way of the existing solution example --- src/framework/processing/py/port/api/props.py | 40 +++++++++++++++++-- .../react/ui/prompts/consent_form.tsx | 9 ++++- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/framework/processing/py/port/api/props.py b/src/framework/processing/py/port/api/props.py index 4b586c0b..fca1e1f1 100644 --- a/src/framework/processing/py/port/api/props.py +++ b/src/framework/processing/py/port/api/props.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Optional, TypedDict +from typing import Optional, TypedDict, Dict, Any import pandas as pd @@ -107,20 +107,52 @@ class PropsUIPromptConsentFormTable: Attributes: id (str): A unique string to identify the table after donation. title (Translatable): Title of the table. - data_frame (pd.DataFrame): Table to be shown. + data_frame (pd.DataFrame | Dict[str, Dict[str, Any]]): Table to be shown can be a pandas data frame or a dictionary description (Optional[Translatable]): Optional description of the table. visualizations (Optional[list]): Optional visualizations to be shown. folded (Optional[bool]): Whether the table should be initially folded. delete_option (Optional[bool]): Whether to show a delete option for the table. + + Examples: + # Using a pandas DataFrame for data_frame + data_frame_df = pd.DataFrame([ + {"column1": 1, "column2": 4}, + {"column1": 2, "column2": 5}, + {"column1": 3, "column2": 6} + ]) + + example1 = PropsUIPromptConsentFormTable( + id="example1", + title=Translatable("Table as DataFrame"), + data_frame=data_frame_df, + ) + + # Using a dictionary for data_frame + data_frame_dict = { + "column1": {"0": 1, "1": 4}, + "column2": {"0": 2, "1": 5}, + "column3": {"0": 3, "1": 6} + } + example2 = PropsUIPromptConsentFormTable( + id="example2", + title=Translatable("Table as Dictionary"), + data_frame=data_frame_dict, + ) """ id: str title: Translatable - data_frame: pd.DataFrame + data_frame: pd.DataFrame | Dict[str, Dict[str, Any]] description: Optional[Translatable] = None visualizations: Optional[list] = None folded: Optional[bool] = False delete_option: Optional[bool] = True + def translate_data_frame(self): + if isinstance(self.data_frame, pd.DataFrame): + return self.data_frame.to_json() + else: + return self.data_frame + def toDict(self): """ Convert the object to a dictionary. @@ -132,7 +164,7 @@ def toDict(self): dict["__type__"] = "PropsUIPromptConsentFormTable" dict["id"] = self.id dict["title"] = self.title.toDict() - dict["data_frame"] = self.data_frame.to_json() + dict["data_frame"] = self.translate_data_frame() dict["description"] = self.description.toDict() if self.description else None dict["visualizations"] = self.visualizations if self.visualizations else None dict["folded"] = self.folded diff --git a/src/framework/visualisation/react/ui/prompts/consent_form.tsx b/src/framework/visualisation/react/ui/prompts/consent_form.tsx index 8be0a412..60b7ddf1 100644 --- a/src/framework/visualisation/react/ui/prompts/consent_form.tsx +++ b/src/framework/visualisation/react/ui/prompts/consent_form.tsx @@ -89,7 +89,7 @@ export const ConsentForm = (props: Props): JSX.Element => { const description = tableData.description !== undefined ? Translator.translate(tableData.description, props.locale) : "" const deletedRowCount = 0 - const dataFrame = JSON.parse(tableData.data_frame) + const dataFrame = loadDataFrame(tableData.data_frame) const headCells = columnNames(dataFrame).map((column: string) => column) const head: PropsUITableHead = { __type__: "PropsUITableHead", @@ -216,6 +216,13 @@ function prepareCopy({ donateQuestion, donateButton, description, locale }: Prop } } +function loadDataFrame(dataFrame: any) { + if (typeof dataFrame === "string") { + return JSON.parse(dataFrame) + } + return dataFrame; +} + const defaultDonateQuestionLabel = new TextBundle() .add('en', 'Do you want to share the above data?') .add('de', 'Möchten Sie die oben genannten Daten teilen?')