Spaces:
Sleeping
Sleeping
Deepa Shalini commited on
Commit ·
290ebbb
1
Parent(s): f96cd4b
explore dataset feature with filtering & sorting
Browse files- app.py +39 -7
- utils/helpers.py +37 -1
app.py
CHANGED
|
@@ -131,6 +131,7 @@ app.layout = dmc.MantineProvider(
|
|
| 131 |
target="_blank",
|
| 132 |
style={"display": "none", "marginTop": "20px", "textAlign": "right"}
|
| 133 |
),
|
|
|
|
| 134 |
html.Div(id="chartbot-output", style={"marginTop": "10px"}),
|
| 135 |
html.Div(id="python-content-output", style={"marginTop": "10px"}),
|
| 136 |
|
|
@@ -158,13 +159,14 @@ app.layout = dmc.MantineProvider(
|
|
| 158 |
Output("stored-data", "data"),
|
| 159 |
Output("stored-file-name", "data"),
|
| 160 |
Output("file-name-display", "children"),
|
|
|
|
| 161 |
Input("upload-data", "contents"),
|
| 162 |
State("upload-data", "filename")
|
| 163 |
)
|
| 164 |
def upload_file(contents, filename):
|
| 165 |
"""Handle CSV file upload and store the data."""
|
| 166 |
if contents is None:
|
| 167 |
-
return None, None, None
|
| 168 |
|
| 169 |
try:
|
| 170 |
# Parse the uploaded file
|
|
@@ -175,15 +177,45 @@ def upload_file(contents, filename):
|
|
| 175 |
|
| 176 |
# Only accept CSV files
|
| 177 |
if not filename.endswith('.csv'):
|
| 178 |
-
return None, None, html.Div("Only CSV files are allowed", style={"color": "red"})
|
| 179 |
|
| 180 |
# Read CSV file
|
| 181 |
df = pd.read_csv(io.StringIO(decoded.decode('utf-8')))
|
| 182 |
|
| 183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
| 185 |
except Exception as e:
|
| 186 |
-
return None, None, html.Div(f"Error: {str(e)}", style={"color": "red"})
|
| 187 |
|
| 188 |
# Callback to enable/disable submit button based on inputs
|
| 189 |
@callback(
|
|
@@ -263,8 +295,7 @@ def create_graph(n_clicks, user_prompt, stored_data, filename):
|
|
| 263 |
[
|
| 264 |
dmc.AccordionControl(
|
| 265 |
html.Div([
|
| 266 |
-
html.Span("Code Generated", style={"fontWeight": "600", "fontSize": "15px"})
|
| 267 |
-
html.Span(" (Click to expand)", style={"fontSize": "13px", "color": "#667085", "marginLeft": "8px"})
|
| 268 |
])
|
| 269 |
),
|
| 270 |
dmc.AccordionPanel(
|
|
@@ -326,6 +357,7 @@ def download_html(encoded):
|
|
| 326 |
Output("stored-data", "data", allow_duplicate=True),
|
| 327 |
Output("stored-file-name", "data", allow_duplicate=True),
|
| 328 |
Output("file-name-display", "children", allow_duplicate=True),
|
|
|
|
| 329 |
Output("chartbot-output", "children", allow_duplicate=True),
|
| 330 |
Output("python-content-output", "children", allow_duplicate=True),
|
| 331 |
Output("download-html", "style", allow_duplicate=True),
|
|
@@ -338,7 +370,7 @@ def download_html(encoded):
|
|
| 338 |
def reset_chat(n_clicks):
|
| 339 |
"""Reset all inputs and outputs to start a new chat."""
|
| 340 |
if n_clicks > 0:
|
| 341 |
-
return "", None, None, None, None, None, {"display": "none"}, None, True, None
|
| 342 |
return dash.no_update
|
| 343 |
|
| 344 |
if __name__ == "__main__":
|
|
|
|
| 131 |
target="_blank",
|
| 132 |
style={"display": "none", "marginTop": "20px", "textAlign": "right"}
|
| 133 |
),
|
| 134 |
+
html.Div(id="dataset-explorer", style={"marginTop": "10px"}), # Add this line
|
| 135 |
html.Div(id="chartbot-output", style={"marginTop": "10px"}),
|
| 136 |
html.Div(id="python-content-output", style={"marginTop": "10px"}),
|
| 137 |
|
|
|
|
| 159 |
Output("stored-data", "data"),
|
| 160 |
Output("stored-file-name", "data"),
|
| 161 |
Output("file-name-display", "children"),
|
| 162 |
+
Output("dataset-explorer", "children"), # Add this output
|
| 163 |
Input("upload-data", "contents"),
|
| 164 |
State("upload-data", "filename")
|
| 165 |
)
|
| 166 |
def upload_file(contents, filename):
|
| 167 |
"""Handle CSV file upload and store the data."""
|
| 168 |
if contents is None:
|
| 169 |
+
return None, None, None, None # Add None for dataset-explorer
|
| 170 |
|
| 171 |
try:
|
| 172 |
# Parse the uploaded file
|
|
|
|
| 177 |
|
| 178 |
# Only accept CSV files
|
| 179 |
if not filename.endswith('.csv'):
|
| 180 |
+
return None, None, html.Div("Only CSV files are allowed", style={"color": "red"}), None
|
| 181 |
|
| 182 |
# Read CSV file
|
| 183 |
df = pd.read_csv(io.StringIO(decoded.decode('utf-8')))
|
| 184 |
|
| 185 |
+
# Create AG Grid accordion
|
| 186 |
+
grid_accordion = html.Div([
|
| 187 |
+
dmc.Accordion(
|
| 188 |
+
children=[
|
| 189 |
+
dmc.AccordionItem(
|
| 190 |
+
[
|
| 191 |
+
dmc.AccordionControl(
|
| 192 |
+
html.Div([
|
| 193 |
+
html.Span("Explore Dataset", style={"fontWeight": "600", "fontSize": "15px"}),
|
| 194 |
+
html.Span(f" ({len(df)} rows, {len(df.columns)} columns)",
|
| 195 |
+
style={"fontSize": "13px", "color": "#667085", "marginLeft": "8px"})
|
| 196 |
+
])
|
| 197 |
+
),
|
| 198 |
+
dmc.AccordionPanel(
|
| 199 |
+
helpers.create_ag_grid(df)
|
| 200 |
+
)
|
| 201 |
+
],
|
| 202 |
+
value="dataset"
|
| 203 |
+
)
|
| 204 |
+
],
|
| 205 |
+
chevronPosition="right",
|
| 206 |
+
variant="filled",
|
| 207 |
+
style={
|
| 208 |
+
"border": "2px solid #E4E7EC",
|
| 209 |
+
"borderRadius": "8px",
|
| 210 |
+
"boxShadow": "0 1px 3px rgba(0, 0, 0, 0.1)"
|
| 211 |
+
}
|
| 212 |
+
)
|
| 213 |
+
], style={"marginTop": "20px"})
|
| 214 |
+
|
| 215 |
+
return df.to_dict("records"), filename, html.Div(f"✓ {filename}", style={"color": "#067A55", "fontWeight": "600"}), grid_accordion
|
| 216 |
|
| 217 |
except Exception as e:
|
| 218 |
+
return None, None, html.Div(f"Error: {str(e)}", style={"color": "red"}), None
|
| 219 |
|
| 220 |
# Callback to enable/disable submit button based on inputs
|
| 221 |
@callback(
|
|
|
|
| 295 |
[
|
| 296 |
dmc.AccordionControl(
|
| 297 |
html.Div([
|
| 298 |
+
html.Span("Code Generated", style={"fontWeight": "600", "fontSize": "15px"})
|
|
|
|
| 299 |
])
|
| 300 |
),
|
| 301 |
dmc.AccordionPanel(
|
|
|
|
| 357 |
Output("stored-data", "data", allow_duplicate=True),
|
| 358 |
Output("stored-file-name", "data", allow_duplicate=True),
|
| 359 |
Output("file-name-display", "children", allow_duplicate=True),
|
| 360 |
+
Output("dataset-explorer", "children", allow_duplicate=True), # Add this output
|
| 361 |
Output("chartbot-output", "children", allow_duplicate=True),
|
| 362 |
Output("python-content-output", "children", allow_duplicate=True),
|
| 363 |
Output("download-html", "style", allow_duplicate=True),
|
|
|
|
| 370 |
def reset_chat(n_clicks):
|
| 371 |
"""Reset all inputs and outputs to start a new chat."""
|
| 372 |
if n_clicks > 0:
|
| 373 |
+
return "", None, None, None, None, None, None, {"display": "none"}, None, True, None # Added None for dataset-explorer
|
| 374 |
return dash.no_update
|
| 375 |
|
| 376 |
if __name__ == "__main__":
|
utils/helpers.py
CHANGED
|
@@ -167,4 +167,40 @@ def save_dataframe_to_current_path(df: pd.DataFrame, filename: str) -> None:
|
|
| 167 |
df.to_csv(filename, index=False)
|
| 168 |
|
| 169 |
elif 'xls' in filename:
|
| 170 |
-
df.to_excel(filename, index=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
df.to_csv(filename, index=False)
|
| 168 |
|
| 169 |
elif 'xls' in filename:
|
| 170 |
+
df.to_excel(filename, index=False)
|
| 171 |
+
|
| 172 |
+
def create_ag_grid(df):
|
| 173 |
+
"""
|
| 174 |
+
Create a Dash AG Grid component for data exploration.
|
| 175 |
+
|
| 176 |
+
Args:
|
| 177 |
+
df: pandas DataFrame
|
| 178 |
+
|
| 179 |
+
Returns:
|
| 180 |
+
dag.AgGrid component
|
| 181 |
+
"""
|
| 182 |
+
return dag.AgGrid(
|
| 183 |
+
id="data-explorer-grid",
|
| 184 |
+
rowData=df.to_dict("records"),
|
| 185 |
+
columnDefs=[{
|
| 186 |
+
"field": col,
|
| 187 |
+
"filter": True,
|
| 188 |
+
"sortable": True,
|
| 189 |
+
"resizable": True,
|
| 190 |
+
"floatingFilter": True
|
| 191 |
+
} for col in df.columns],
|
| 192 |
+
defaultColDef={
|
| 193 |
+
"filter": True,
|
| 194 |
+
"sortable": True,
|
| 195 |
+
"resizable": True,
|
| 196 |
+
"minWidth": 100
|
| 197 |
+
},
|
| 198 |
+
dashGridOptions={
|
| 199 |
+
"pagination": True,
|
| 200 |
+
"paginationPageSize": 10,
|
| 201 |
+
"paginationPageSizeSelector": [10, 20, 50, 100],
|
| 202 |
+
"animateRows": True
|
| 203 |
+
},
|
| 204 |
+
style={"height": "400px", "width": "100%"},
|
| 205 |
+
className="ag-theme-alpine"
|
| 206 |
+
)
|