bidviz 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bidviz/__init__.py +14 -0
- bidviz/core/__init__.py +5 -0
- bidviz/core/base.py +43 -0
- bidviz/exceptions.py +69 -0
- bidviz/transformer.py +312 -0
- bidviz/transformers/__init__.py +22 -0
- bidviz/transformers/bar.py +68 -0
- bidviz/transformers/heatmap.py +116 -0
- bidviz/transformers/kpi.py +60 -0
- bidviz/transformers/line.py +126 -0
- bidviz/transformers/other.py +108 -0
- bidviz/transformers/pie.py +48 -0
- bidviz/transformers/table.py +48 -0
- bidviz/utils.py +187 -0
- bidviz-1.0.0.dist-info/METADATA +425 -0
- bidviz-1.0.0.dist-info/RECORD +19 -0
- bidviz-1.0.0.dist-info/WHEEL +5 -0
- bidviz-1.0.0.dist-info/licenses/LICENSE +21 -0
- bidviz-1.0.0.dist-info/top_level.txt +1 -0
bidviz/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BidViz - Backend Visualization Data Transformation Library
|
|
3
|
+
|
|
4
|
+
A powerful, configurable backend visualization data transformation library designed to bridge
|
|
5
|
+
the gap between raw data and frontend charting libraries.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "1.0.0"
|
|
9
|
+
__author__ = "Mohammad Amin Khara"
|
|
10
|
+
|
|
11
|
+
from bidviz.exceptions import TransformationError, ValidationError
|
|
12
|
+
from bidviz.transformer import ChartTransformer
|
|
13
|
+
|
|
14
|
+
__all__ = ["ChartTransformer", "TransformationError", "ValidationError"]
|
bidviz/core/__init__.py
ADDED
bidviz/core/base.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Base transformer class for all chart transformations."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseChartTransformer:
|
|
9
|
+
"""
|
|
10
|
+
Base class for chart transformers.
|
|
11
|
+
|
|
12
|
+
All specific chart transformers should inherit from this class
|
|
13
|
+
and implement the transform method.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def transform(self, df: pd.DataFrame, **kwargs: Any) -> Dict[str, Any]:
|
|
17
|
+
"""
|
|
18
|
+
Transform a DataFrame into chart-ready format.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
df: Input DataFrame
|
|
22
|
+
**kwargs: Additional transformation parameters
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
Dictionary containing chart data and metadata
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
NotImplementedError: If not implemented by subclass
|
|
29
|
+
"""
|
|
30
|
+
raise NotImplementedError("Subclasses must implement transform method")
|
|
31
|
+
|
|
32
|
+
def _validate_dataframe(self, df: pd.DataFrame) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Validate that DataFrame is not None and has data.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
df: DataFrame to validate
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
ValueError: If DataFrame is None
|
|
41
|
+
"""
|
|
42
|
+
if df is None:
|
|
43
|
+
raise ValueError("DataFrame cannot be None")
|
bidviz/exceptions.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom exceptions for BidViz library.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BidVizError(Exception):
|
|
7
|
+
"""Base exception for all BidViz errors."""
|
|
8
|
+
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TransformationError(BidVizError):
|
|
13
|
+
"""
|
|
14
|
+
Exception raised when data transformation fails.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
message (str): Explanation of the error
|
|
18
|
+
chart_type (str): Type of chart being transformed
|
|
19
|
+
df_shape (tuple): Shape of the DataFrame (rows, columns)
|
|
20
|
+
missing_columns (list): List of missing column names
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
message: str,
|
|
26
|
+
chart_type: str = None,
|
|
27
|
+
df_shape: tuple = None,
|
|
28
|
+
missing_columns: list = None,
|
|
29
|
+
):
|
|
30
|
+
self.message = message
|
|
31
|
+
self.chart_type = chart_type
|
|
32
|
+
self.df_shape = df_shape
|
|
33
|
+
self.missing_columns = missing_columns or []
|
|
34
|
+
super().__init__(self.message)
|
|
35
|
+
|
|
36
|
+
def __str__(self) -> str:
|
|
37
|
+
details = [self.message]
|
|
38
|
+
if self.chart_type:
|
|
39
|
+
details.append(f"Chart Type: {self.chart_type}")
|
|
40
|
+
if self.df_shape:
|
|
41
|
+
details.append(f"DataFrame Shape: {self.df_shape}")
|
|
42
|
+
if self.missing_columns:
|
|
43
|
+
details.append(f"Missing Columns: {', '.join(self.missing_columns)}")
|
|
44
|
+
return " | ".join(details)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ValidationError(BidVizError):
|
|
48
|
+
"""
|
|
49
|
+
Exception raised when data validation fails.
|
|
50
|
+
|
|
51
|
+
Attributes:
|
|
52
|
+
message (str): Explanation of the validation error
|
|
53
|
+
column (str): Column name that failed validation
|
|
54
|
+
validation_type (str): Type of validation that failed
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(self, message: str, column: str = None, validation_type: str = None):
|
|
58
|
+
self.message = message
|
|
59
|
+
self.column = column
|
|
60
|
+
self.validation_type = validation_type
|
|
61
|
+
super().__init__(self.message)
|
|
62
|
+
|
|
63
|
+
def __str__(self) -> str:
|
|
64
|
+
details = [self.message]
|
|
65
|
+
if self.column:
|
|
66
|
+
details.append(f"Column: {self.column}")
|
|
67
|
+
if self.validation_type:
|
|
68
|
+
details.append(f"Validation Type: {self.validation_type}")
|
|
69
|
+
return " | ".join(details)
|
bidviz/transformer.py
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core chart transformation service - facade for all chart transformers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
from bidviz.transformers import (
|
|
10
|
+
BarChartTransformer,
|
|
11
|
+
CorrelationHeatmapTransformer,
|
|
12
|
+
DataTableTransformer,
|
|
13
|
+
FunnelChartTransformer,
|
|
14
|
+
HeatmapTransformer,
|
|
15
|
+
KPICardsTransformer,
|
|
16
|
+
LineChartTransformer,
|
|
17
|
+
MultiLineChartTransformer,
|
|
18
|
+
PieChartTransformer,
|
|
19
|
+
StackedBarChartTransformer,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ChartTransformer:
|
|
24
|
+
"""
|
|
25
|
+
Main facade for transforming pandas DataFrames into chart-ready data structures.
|
|
26
|
+
|
|
27
|
+
This class provides a unified interface to all chart transformers,
|
|
28
|
+
converting raw DataFrames into JSON-serializable formats optimized
|
|
29
|
+
for various charting libraries (Chart.js, D3, Plotly, Recharts, etc.).
|
|
30
|
+
|
|
31
|
+
The actual transformation logic is delegated to specialized transformer
|
|
32
|
+
classes for maintainability and modularity.
|
|
33
|
+
|
|
34
|
+
Supported chart types:
|
|
35
|
+
- KPI Cards
|
|
36
|
+
- Bar Chart
|
|
37
|
+
- Line Chart
|
|
38
|
+
- Multi-Line Chart
|
|
39
|
+
- Pie Chart
|
|
40
|
+
- Heatmap
|
|
41
|
+
- Funnel Chart
|
|
42
|
+
- Stacked Bar Chart
|
|
43
|
+
- Data Table (with pagination)
|
|
44
|
+
- Correlation Heatmap
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
>>> transformer = ChartTransformer()
|
|
48
|
+
>>> df = pd.DataFrame({'vendor': ['A', 'B'], 'revenue': [100, 200]})
|
|
49
|
+
>>> result = transformer.transform_to_bar_chart(df, 'vendor', 'revenue')
|
|
50
|
+
>>> result['chart_type']
|
|
51
|
+
'bar_chart'
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self) -> None:
|
|
55
|
+
"""Initialize the chart transformer with all specialized transformers."""
|
|
56
|
+
self._kpi_transformer = KPICardsTransformer()
|
|
57
|
+
self._bar_transformer = BarChartTransformer()
|
|
58
|
+
self._line_transformer = LineChartTransformer()
|
|
59
|
+
self._multi_line_transformer = MultiLineChartTransformer()
|
|
60
|
+
self._pie_transformer = PieChartTransformer()
|
|
61
|
+
self._heatmap_transformer = HeatmapTransformer()
|
|
62
|
+
self._funnel_transformer = FunnelChartTransformer()
|
|
63
|
+
self._stacked_bar_transformer = StackedBarChartTransformer()
|
|
64
|
+
self._table_transformer = DataTableTransformer()
|
|
65
|
+
self._correlation_transformer = CorrelationHeatmapTransformer()
|
|
66
|
+
|
|
67
|
+
def transform_to_kpi_cards(self, df: pd.DataFrame) -> Dict[str, Any]:
|
|
68
|
+
"""
|
|
69
|
+
Transform a single-row DataFrame into KPI cards for dashboard metrics.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
df: Single-row DataFrame containing metrics
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Dict with chart_type='kpi_cards' and list of card data
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
TransformationError: If DataFrame has more than one row
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
>>> df = pd.DataFrame({'total_orders': [150], 'revenue': [45000.50]})
|
|
82
|
+
>>> result = transformer.transform_to_kpi_cards(df)
|
|
83
|
+
>>> len(result['data'])
|
|
84
|
+
2
|
|
85
|
+
"""
|
|
86
|
+
return self._kpi_transformer.transform(df)
|
|
87
|
+
|
|
88
|
+
def transform_to_bar_chart(
|
|
89
|
+
self,
|
|
90
|
+
df: pd.DataFrame,
|
|
91
|
+
x_column: str,
|
|
92
|
+
y_column: str,
|
|
93
|
+
label_column: Optional[str] = None,
|
|
94
|
+
) -> Dict[str, Any]:
|
|
95
|
+
"""
|
|
96
|
+
Transform DataFrame into bar chart data structure.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
df: DataFrame containing the data
|
|
100
|
+
x_column: Column name for x-axis (categorical)
|
|
101
|
+
y_column: Column name for y-axis (numeric)
|
|
102
|
+
label_column: Optional column for custom labels
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Dict with chart_type='bar_chart', data points, and axis labels
|
|
106
|
+
|
|
107
|
+
Examples:
|
|
108
|
+
>>> df = pd.DataFrame({'vendor': ['A', 'B'], 'revenue': [1000, 1500]})
|
|
109
|
+
>>> result = transformer.transform_to_bar_chart(df, 'vendor', 'revenue')
|
|
110
|
+
>>> result['chart_type']
|
|
111
|
+
'bar_chart'
|
|
112
|
+
"""
|
|
113
|
+
return self._bar_transformer.transform(df, x_column, y_column, label_column)
|
|
114
|
+
|
|
115
|
+
def transform_to_line_chart(
|
|
116
|
+
self,
|
|
117
|
+
df: pd.DataFrame,
|
|
118
|
+
x_column: str,
|
|
119
|
+
y_column: str,
|
|
120
|
+
series_name: Optional[str] = None,
|
|
121
|
+
) -> Dict[str, Any]:
|
|
122
|
+
"""
|
|
123
|
+
Transform DataFrame into line chart data for time series or trends.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
df: DataFrame containing the data
|
|
127
|
+
x_column: Column name for x-axis
|
|
128
|
+
y_column: Column name for y-axis
|
|
129
|
+
series_name: Optional custom name for the data series
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Dict with chart_type='line_chart', data points, and labels
|
|
133
|
+
|
|
134
|
+
Examples:
|
|
135
|
+
>>> df = pd.DataFrame({'date': pd.date_range('2024-01-01', periods=3),
|
|
136
|
+
... 'orders': [10, 15, 12]})
|
|
137
|
+
>>> result = transformer.transform_to_line_chart(df, 'date', 'orders')
|
|
138
|
+
>>> result['series_name']
|
|
139
|
+
'Orders'
|
|
140
|
+
"""
|
|
141
|
+
return self._line_transformer.transform(df, x_column, y_column, series_name)
|
|
142
|
+
|
|
143
|
+
def transform_to_multi_line_chart(
|
|
144
|
+
self,
|
|
145
|
+
df: pd.DataFrame,
|
|
146
|
+
x_column: str,
|
|
147
|
+
y_columns: List[str],
|
|
148
|
+
series_names: Optional[List[str]] = None,
|
|
149
|
+
) -> Dict[str, Any]:
|
|
150
|
+
"""
|
|
151
|
+
Transform DataFrame into multi-line chart for comparing multiple series.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
df: DataFrame containing the data
|
|
155
|
+
x_column: Column name for x-axis
|
|
156
|
+
y_columns: List of column names for y-axis
|
|
157
|
+
series_names: Optional custom names for each series
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Dict with chart_type='multi_line_chart' and series data
|
|
161
|
+
|
|
162
|
+
Examples:
|
|
163
|
+
>>> df = pd.DataFrame({'date': ['2024-01-01', '2024-01-02'],
|
|
164
|
+
... 'vendor_a': [10, 15], 'vendor_b': [12, 18]})
|
|
165
|
+
>>> result = transformer.transform_to_multi_line_chart(
|
|
166
|
+
... df, 'date', ['vendor_a', 'vendor_b'])
|
|
167
|
+
>>> len(result['series'])
|
|
168
|
+
2
|
|
169
|
+
"""
|
|
170
|
+
return self._multi_line_transformer.transform(df, x_column, y_columns, series_names)
|
|
171
|
+
|
|
172
|
+
def transform_to_pie_chart(
|
|
173
|
+
self, df: pd.DataFrame, label_column: str, value_column: str
|
|
174
|
+
) -> Dict[str, Any]:
|
|
175
|
+
"""
|
|
176
|
+
Transform DataFrame into pie chart data for part-to-whole relationships.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
df: DataFrame containing the data
|
|
180
|
+
label_column: Column name for slice labels
|
|
181
|
+
value_column: Column name for slice values
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Dict with chart_type='pie_chart' and data points
|
|
185
|
+
|
|
186
|
+
Examples:
|
|
187
|
+
>>> df = pd.DataFrame({'category': ['A', 'B'], 'sales': [45000, 32000]})
|
|
188
|
+
>>> result = transformer.transform_to_pie_chart(df, 'category', 'sales')
|
|
189
|
+
>>> len(result['data'])
|
|
190
|
+
2
|
|
191
|
+
"""
|
|
192
|
+
return self._pie_transformer.transform(df, label_column, value_column)
|
|
193
|
+
|
|
194
|
+
def transform_to_heatmap(
|
|
195
|
+
self, df: pd.DataFrame, x_column: str, y_column: str, value_column: str
|
|
196
|
+
) -> Dict[str, Any]:
|
|
197
|
+
"""
|
|
198
|
+
Transform DataFrame into heatmap data for 2D intensity visualization.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
df: DataFrame containing the data
|
|
202
|
+
x_column: Column name for x-axis
|
|
203
|
+
y_column: Column name for y-axis
|
|
204
|
+
value_column: Column name for cell values
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Dict with chart_type='heatmap', data points, and labels
|
|
208
|
+
|
|
209
|
+
Examples:
|
|
210
|
+
>>> df = pd.DataFrame({'hour': [0, 1], 'day': ['Mon', 'Mon'],
|
|
211
|
+
... 'count': [12, 8]})
|
|
212
|
+
>>> result = transformer.transform_to_heatmap(df, 'hour', 'day', 'count')
|
|
213
|
+
>>> result['chart_type']
|
|
214
|
+
'heatmap'
|
|
215
|
+
"""
|
|
216
|
+
return self._heatmap_transformer.transform(df, x_column, y_column, value_column)
|
|
217
|
+
|
|
218
|
+
def transform_to_funnel_chart(
|
|
219
|
+
self, df: pd.DataFrame, stage_column: str, value_column: str
|
|
220
|
+
) -> Dict[str, Any]:
|
|
221
|
+
"""
|
|
222
|
+
Transform DataFrame into funnel chart data for conversion pipelines.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
df: DataFrame containing the data
|
|
226
|
+
stage_column: Column name for funnel stages
|
|
227
|
+
value_column: Column name for stage values
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
Dict with chart_type='funnel_chart' and data points
|
|
231
|
+
|
|
232
|
+
Examples:
|
|
233
|
+
>>> df = pd.DataFrame({'stage': ['Visits', 'Sign-ups'],
|
|
234
|
+
... 'count': [1000, 300]})
|
|
235
|
+
>>> result = transformer.transform_to_funnel_chart(df, 'stage', 'count')
|
|
236
|
+
>>> len(result['data'])
|
|
237
|
+
2
|
|
238
|
+
"""
|
|
239
|
+
return self._funnel_transformer.transform(df, stage_column, value_column)
|
|
240
|
+
|
|
241
|
+
def transform_to_stacked_bar_chart(
|
|
242
|
+
self,
|
|
243
|
+
df: pd.DataFrame,
|
|
244
|
+
x_column: str,
|
|
245
|
+
y_columns: List[str],
|
|
246
|
+
category_names: Optional[List[str]] = None,
|
|
247
|
+
) -> Dict[str, Any]:
|
|
248
|
+
"""
|
|
249
|
+
Transform DataFrame into stacked bar chart for composed comparisons.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
df: DataFrame containing the data
|
|
253
|
+
x_column: Column name for x-axis
|
|
254
|
+
y_columns: List of column names for stacked values
|
|
255
|
+
category_names: Optional custom names for each stack
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
Dict with chart_type='stacked_bar_chart' and data
|
|
259
|
+
|
|
260
|
+
Examples:
|
|
261
|
+
>>> df = pd.DataFrame({'month': ['Jan', 'Feb'],
|
|
262
|
+
... 'product_a': [100, 150], 'product_b': [200, 180]})
|
|
263
|
+
>>> result = transformer.transform_to_stacked_bar_chart(
|
|
264
|
+
... df, 'month', ['product_a', 'product_b'])
|
|
265
|
+
>>> len(result['categories'])
|
|
266
|
+
2
|
|
267
|
+
"""
|
|
268
|
+
return self._stacked_bar_transformer.transform(df, x_column, y_columns, category_names)
|
|
269
|
+
|
|
270
|
+
def transform_to_data_table(
|
|
271
|
+
self, df: pd.DataFrame, page: int = 1, page_size: int = 50
|
|
272
|
+
) -> Dict[str, Any]:
|
|
273
|
+
"""
|
|
274
|
+
Transform DataFrame into paginated data table structure.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
df: DataFrame containing the data
|
|
278
|
+
page: Page number (1-indexed)
|
|
279
|
+
page_size: Number of rows per page
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
Dict with chart_type='data_table', columns, rows, and pagination
|
|
283
|
+
|
|
284
|
+
Examples:
|
|
285
|
+
>>> df = pd.DataFrame({'id': [1, 2, 3], 'name': ['A', 'B', 'C']})
|
|
286
|
+
>>> result = transformer.transform_to_data_table(df, page=1, page_size=2)
|
|
287
|
+
>>> len(result['rows'])
|
|
288
|
+
2
|
|
289
|
+
"""
|
|
290
|
+
return self._table_transformer.transform(df, page, page_size)
|
|
291
|
+
|
|
292
|
+
def transform_to_correlation_heatmap(
|
|
293
|
+
self, df: pd.DataFrame, metrics: Optional[List[str]] = None
|
|
294
|
+
) -> Dict[str, Any]:
|
|
295
|
+
"""
|
|
296
|
+
Transform DataFrame into correlation heatmap for statistical analysis.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
df: DataFrame containing numeric columns
|
|
300
|
+
metrics: Optional list of column names to correlate
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
Dict with chart_type='heatmap' and correlation data
|
|
304
|
+
|
|
305
|
+
Examples:
|
|
306
|
+
>>> df = pd.DataFrame({'revenue': [100, 200, 150],
|
|
307
|
+
... 'orders': [10, 20, 15]})
|
|
308
|
+
>>> result = transformer.transform_to_correlation_heatmap(df)
|
|
309
|
+
>>> result['chart_type']
|
|
310
|
+
'heatmap'
|
|
311
|
+
"""
|
|
312
|
+
return self._correlation_transformer.transform(df, metrics)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Transformers module initialization."""
|
|
2
|
+
|
|
3
|
+
from bidviz.transformers.bar import BarChartTransformer
|
|
4
|
+
from bidviz.transformers.heatmap import CorrelationHeatmapTransformer, HeatmapTransformer
|
|
5
|
+
from bidviz.transformers.kpi import KPICardsTransformer
|
|
6
|
+
from bidviz.transformers.line import LineChartTransformer, MultiLineChartTransformer
|
|
7
|
+
from bidviz.transformers.other import FunnelChartTransformer, StackedBarChartTransformer
|
|
8
|
+
from bidviz.transformers.pie import PieChartTransformer
|
|
9
|
+
from bidviz.transformers.table import DataTableTransformer
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"KPICardsTransformer",
|
|
13
|
+
"BarChartTransformer",
|
|
14
|
+
"LineChartTransformer",
|
|
15
|
+
"MultiLineChartTransformer",
|
|
16
|
+
"PieChartTransformer",
|
|
17
|
+
"HeatmapTransformer",
|
|
18
|
+
"FunnelChartTransformer",
|
|
19
|
+
"StackedBarChartTransformer",
|
|
20
|
+
"DataTableTransformer",
|
|
21
|
+
"CorrelationHeatmapTransformer",
|
|
22
|
+
]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Bar chart transformer."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from bidviz.core.base import BaseChartTransformer
|
|
8
|
+
from bidviz.exceptions import TransformationError
|
|
9
|
+
from bidviz.utils import format_label, safe_get_value, validate_columns
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BarChartTransformer(BaseChartTransformer):
|
|
13
|
+
"""Transform DataFrame into bar chart data."""
|
|
14
|
+
|
|
15
|
+
def transform(
|
|
16
|
+
self,
|
|
17
|
+
df: pd.DataFrame,
|
|
18
|
+
x_column: str,
|
|
19
|
+
y_column: str,
|
|
20
|
+
label_column: Optional[str] = None,
|
|
21
|
+
) -> Dict[str, Any]:
|
|
22
|
+
"""
|
|
23
|
+
Transform DataFrame into bar chart data structure.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
df: DataFrame containing the data
|
|
27
|
+
x_column: Column name for x-axis (categorical)
|
|
28
|
+
y_column: Column name for y-axis (numeric)
|
|
29
|
+
label_column: Optional column for custom labels
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Dict with chart_type='bar_chart', data points, and axis labels
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
TransformationError: If required columns are missing
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
validate_columns(df, [x_column, y_column])
|
|
39
|
+
if label_column:
|
|
40
|
+
validate_columns(df, [label_column])
|
|
41
|
+
else:
|
|
42
|
+
label_column = x_column
|
|
43
|
+
|
|
44
|
+
data = []
|
|
45
|
+
for _, row in df.iterrows():
|
|
46
|
+
data.append(
|
|
47
|
+
{
|
|
48
|
+
"x": str(safe_get_value(row[x_column])),
|
|
49
|
+
"y": safe_get_value(row[y_column]),
|
|
50
|
+
"label": str(safe_get_value(row[label_column])),
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
"chart_type": "bar_chart",
|
|
56
|
+
"data": data,
|
|
57
|
+
"x_label": format_label(x_column),
|
|
58
|
+
"y_label": format_label(y_column),
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
except ValueError as e:
|
|
62
|
+
raise TransformationError(str(e), chart_type="bar_chart", df_shape=df.shape)
|
|
63
|
+
except Exception as e:
|
|
64
|
+
raise TransformationError(
|
|
65
|
+
f"Failed to transform bar chart: {str(e)}",
|
|
66
|
+
chart_type="bar_chart",
|
|
67
|
+
df_shape=df.shape,
|
|
68
|
+
)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Heatmap transformers."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from bidviz.core.base import BaseChartTransformer
|
|
8
|
+
from bidviz.exceptions import TransformationError
|
|
9
|
+
from bidviz.utils import format_label, get_numeric_columns, safe_get_value, validate_columns
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class HeatmapTransformer(BaseChartTransformer):
|
|
13
|
+
"""Transform DataFrame into heatmap data."""
|
|
14
|
+
|
|
15
|
+
def transform(
|
|
16
|
+
self, df: pd.DataFrame, x_column: str, y_column: str, value_column: str
|
|
17
|
+
) -> Dict[str, Any]:
|
|
18
|
+
"""
|
|
19
|
+
Transform DataFrame into heatmap data for 2D intensity visualization.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
df: DataFrame containing the data
|
|
23
|
+
x_column: Column name for x-axis
|
|
24
|
+
y_column: Column name for y-axis
|
|
25
|
+
value_column: Column name for cell values
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Dict with chart_type='heatmap', data points, and labels
|
|
29
|
+
"""
|
|
30
|
+
try:
|
|
31
|
+
validate_columns(df, [x_column, y_column, value_column])
|
|
32
|
+
|
|
33
|
+
data = []
|
|
34
|
+
for _, row in df.iterrows():
|
|
35
|
+
data.append(
|
|
36
|
+
{
|
|
37
|
+
"x": str(safe_get_value(row[x_column])),
|
|
38
|
+
"y": str(safe_get_value(row[y_column])),
|
|
39
|
+
"value": safe_get_value(row[value_column]),
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
"chart_type": "heatmap",
|
|
45
|
+
"data": data,
|
|
46
|
+
"x_label": format_label(x_column),
|
|
47
|
+
"y_label": format_label(y_column),
|
|
48
|
+
"value_label": format_label(value_column),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
except ValueError as e:
|
|
52
|
+
raise TransformationError(str(e), chart_type="heatmap", df_shape=df.shape)
|
|
53
|
+
except Exception as e:
|
|
54
|
+
raise TransformationError(
|
|
55
|
+
f"Failed to transform heatmap: {str(e)}",
|
|
56
|
+
chart_type="heatmap",
|
|
57
|
+
df_shape=df.shape,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class CorrelationHeatmapTransformer(BaseChartTransformer):
|
|
62
|
+
"""Transform DataFrame into correlation heatmap."""
|
|
63
|
+
|
|
64
|
+
def transform(self, df: pd.DataFrame, metrics: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
65
|
+
"""
|
|
66
|
+
Transform DataFrame into correlation heatmap for statistical analysis.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
df: DataFrame containing numeric columns
|
|
70
|
+
metrics: Optional list of column names to correlate
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Dict with chart_type='heatmap' and correlation data
|
|
74
|
+
"""
|
|
75
|
+
try:
|
|
76
|
+
if metrics is None:
|
|
77
|
+
metrics = get_numeric_columns(df)
|
|
78
|
+
|
|
79
|
+
if len(metrics) < 2:
|
|
80
|
+
raise TransformationError(
|
|
81
|
+
"Need at least 2 numeric columns for correlation",
|
|
82
|
+
chart_type="correlation_heatmap",
|
|
83
|
+
df_shape=df.shape,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
validate_columns(df, metrics)
|
|
87
|
+
corr_matrix = df[metrics].corr()
|
|
88
|
+
|
|
89
|
+
data = []
|
|
90
|
+
for x_metric in metrics:
|
|
91
|
+
for y_metric in metrics:
|
|
92
|
+
data.append(
|
|
93
|
+
{
|
|
94
|
+
"x": x_metric,
|
|
95
|
+
"y": y_metric,
|
|
96
|
+
"value": safe_get_value(corr_matrix.loc[y_metric, x_metric]),
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
"chart_type": "heatmap",
|
|
102
|
+
"data": data,
|
|
103
|
+
"metrics": metrics,
|
|
104
|
+
"x_label": "Metrics",
|
|
105
|
+
"y_label": "Metrics",
|
|
106
|
+
"value_label": "Correlation Coefficient",
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
except ValueError as e:
|
|
110
|
+
raise TransformationError(str(e), chart_type="correlation_heatmap", df_shape=df.shape)
|
|
111
|
+
except Exception as e:
|
|
112
|
+
raise TransformationError(
|
|
113
|
+
f"Failed to transform correlation heatmap: {str(e)}",
|
|
114
|
+
chart_type="correlation_heatmap",
|
|
115
|
+
df_shape=df.shape,
|
|
116
|
+
)
|