or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdconfiguration.mdindex.mdmodels-database.mdrest-api.mdsecurity-auth.mdvisualization.md
VALIDATION_REPORT.md

visualization.mddocs/

0

# Visualization System

1

2

Extensible visualization system supporting 40+ chart types with custom plugin architecture and data processing pipeline.

3

4

## Capabilities

5

6

### Base Visualization Classes

7

8

Core visualization framework for creating chart types.

9

10

```python { .api }

11

class BaseViz:

12

"""Base class for all visualizations."""

13

14

viz_type: str # Unique chart type identifier

15

verbose_name: str # Display name for chart type

16

is_timeseries: bool = False # Whether chart supports time series

17

default_are_zeros: bool = True # How to handle missing data

18

credits: str = "" # Attribution for chart type

19

20

def __init__(self, datasource: BaseDatasource, form_data: Dict[str, Any],

21

force: bool = False):

22

"""

23

Initialize visualization.

24

25

Args:

26

datasource: Data source for chart

27

form_data: Chart configuration from UI

28

force: Force refresh of cached data

29

"""

30

31

def get_query_object(self) -> QueryObject:

32

"""

33

Build query object from form data.

34

35

Returns:

36

Query object for data retrieval

37

"""

38

39

def get_data(self, df: pd.DataFrame) -> VizData:

40

"""

41

Process DataFrame into visualization-ready format.

42

43

Args:

44

df: Raw query results

45

46

Returns:

47

Processed data for frontend rendering

48

"""

49

50

def get_csv(self) -> str:

51

"""

52

Export chart data as CSV.

53

54

Returns:

55

CSV-formatted chart data

56

"""

57

58

def get_json_data(self, force: bool = False) -> Dict[str, Any]:

59

"""

60

Get chart data as JSON.

61

62

Args:

63

force: Force refresh of cached data

64

65

Returns:

66

Chart data and metadata

67

"""

68

69

class TimeSeriesViz(BaseViz):

70

"""Base class for time series visualizations."""

71

72

is_timeseries: bool = True

73

74

def process_data(self, df: pd.DataFrame,

75

aggregate: bool = False) -> Dict[str, Any]:

76

"""

77

Process time series data.

78

79

Args:

80

df: Time series DataFrame

81

aggregate: Whether to aggregate data

82

83

Returns:

84

Processed time series data

85

"""

86

87

def to_series(self, df: pd.DataFrame, classed: str = "",

88

title_suffix: str = "") -> List[Dict[str, Any]]:

89

"""

90

Convert DataFrame to time series format.

91

92

Args:

93

df: Source DataFrame

94

classed: CSS class for series

95

title_suffix: Suffix for series titles

96

97

Returns:

98

List of time series objects

99

"""

100

```

101

102

### Chart Type Registry

103

104

Registry system for available chart types and their implementations.

105

106

```python { .api }

107

# Chart Type Registry

108

viz_types: Dict[str, Type[BaseViz]] = {

109

'table': TableViz,

110

'bar': DistributionBarViz,

111

'line': LineViz,

112

'area': AreaViz,

113

'pie': PieViz,

114

'scatter': ScatterViz,

115

'bubble': BubbleViz,

116

'histogram': HistogramViz,

117

'box_plot': BoxPlotViz,

118

'sunburst': SunburstViz,

119

'treemap': TreemapViz,

120

'heatmap': HeatmapViz,

121

'deck_scatter': DeckScatterViz,

122

'deck_arc': DeckArcViz,

123

'deck_hex': DeckHexViz,

124

'deck_grid': DeckGridViz,

125

'deck_polygon': DeckPolygonViz,

126

'deck_geojson': DeckGeoJsonViz,

127

'pivot_table': PivotTableViz,

128

'paired_ttest': PairedTTestViz,

129

'rose': RoseViz,

130

'partition': PartitionViz,

131

'event_flow': EventFlowViz,

132

'parallel_coordinates': ParallelCoordinatesViz,

133

'sankey': SankeyViz,

134

'chord': ChordViz,

135

'country_map': CountryMapViz,

136

'world_map': WorldMapViz,

137

'filter_box': FilterBoxViz,

138

'iframe': IFrameViz,

139

'para': ParaViz,

140

'markup': MarkupViz,

141

'separator': SeparatorViz,

142

'word_cloud': WordCloudViz,

143

'mapbox': MapboxViz,

144

}

145

146

def get_viz(viz_type: str, datasource: BaseDatasource,

147

form_data: Dict[str, Any] = None, **kwargs) -> BaseViz:

148

"""

149

Get visualization instance by type.

150

151

Args:

152

viz_type: Chart type identifier

153

datasource: Data source

154

form_data: Chart configuration

155

156

Returns:

157

Visualization instance

158

159

Raises:

160

Exception: If viz_type not found

161

"""

162

163

def get_all_viz_types() -> List[Dict[str, Any]]:

164

"""

165

Get metadata for all available chart types.

166

167

Returns:

168

List of chart type metadata

169

"""

170

```

171

172

### Common Chart Types

173

174

Implementation of popular chart types.

175

176

```python { .api }

177

class TableViz(BaseViz):

178

"""Tabular data visualization."""

179

180

viz_type = "table"

181

verbose_name = "Table View"

182

is_timeseries = False

183

184

def get_data(self, df: pd.DataFrame) -> VizData:

185

"""

186

Process data for table display.

187

188

Args:

189

df: Query results DataFrame

190

191

Returns:

192

Table data with formatting and pagination

193

"""

194

195

class LineViz(TimeSeriesViz):

196

"""Line chart visualization."""

197

198

viz_type = "line"

199

verbose_name = "Time Series - Line Chart"

200

default_are_zeros = False

201

202

def get_data(self, df: pd.DataFrame) -> VizData:

203

"""

204

Process data for line chart.

205

206

Args:

207

df: Time series DataFrame

208

209

Returns:

210

Line chart data with series and formatting

211

"""

212

213

class BarViz(BaseViz):

214

"""Bar chart visualization."""

215

216

viz_type = "bar"

217

verbose_name = "Bar Chart"

218

219

def get_data(self, df: pd.DataFrame) -> VizData:

220

"""

221

Process data for bar chart.

222

223

Args:

224

df: Grouped DataFrame

225

226

Returns:

227

Bar chart data with categories and values

228

"""

229

230

class PieViz(BaseViz):

231

"""Pie chart visualization."""

232

233

viz_type = "pie"

234

verbose_name = "Pie Chart"

235

236

def get_data(self, df: pd.DataFrame) -> VizData:

237

"""

238

Process data for pie chart.

239

240

Args:

241

df: Aggregated DataFrame

242

243

Returns:

244

Pie chart data with segments and percentages

245

"""

246

247

class ScatterViz(BaseViz):

248

"""Scatter plot visualization."""

249

250

viz_type = "scatter"

251

verbose_name = "Scatter Plot"

252

253

def get_data(self, df: pd.DataFrame) -> VizData:

254

"""

255

Process data for scatter plot.

256

257

Args:

258

df: Point data DataFrame

259

260

Returns:

261

Scatter plot data with coordinates and metadata

262

"""

263

```

264

265

### Query Object System

266

267

System for translating UI form data into database queries.

268

269

```python { .api }

270

class QueryObject:

271

"""Query specification for data retrieval."""

272

273

def __init__(self,

274

datasource: BaseDatasource,

275

metrics: List[str] = None,

276

groupby: List[str] = None,

277

columns: List[str] = None,

278

granularity: str = None,

279

since: str = None,

280

until: str = None,

281

filters: List[Dict[str, Any]] = None,

282

row_limit: int = None,

283

row_offset: int = None,

284

order_desc: bool = True,

285

extras: Dict[str, Any] = None):

286

"""

287

Initialize query object.

288

289

Args:

290

datasource: Target datasource

291

metrics: List of metrics to calculate

292

groupby: Columns to group by

293

columns: Specific columns to include

294

granularity: Time granularity for time series

295

since: Start time for time range

296

until: End time for time range

297

filters: List of filter conditions

298

row_limit: Maximum rows to return

299

row_offset: Number of rows to skip

300

order_desc: Sort order (descending if True)

301

extras: Additional query parameters

302

"""

303

self.datasource = datasource

304

self.metrics = metrics or []

305

self.groupby = groupby or []

306

self.columns = columns or []

307

self.granularity = granularity

308

self.since = since

309

self.until = until

310

self.filters = filters or []

311

self.row_limit = row_limit

312

self.row_offset = row_offset

313

self.order_desc = order_desc

314

self.extras = extras or {}

315

316

def to_dict(self) -> Dict[str, Any]:

317

"""Convert query object to dictionary."""

318

319

@classmethod

320

def from_dict(cls, obj_dict: Dict[str, Any]) -> 'QueryObject':

321

"""Create query object from dictionary."""

322

323

def get_query_results(query_obj: QueryObject,

324

force_cached: bool = False) -> Dict[str, Any]:

325

"""

326

Execute query and return results.

327

328

Args:

329

query_obj: Query specification

330

force_cached: Use cached results if available

331

332

Returns:

333

Query results with data and metadata

334

"""

335

```

336

337

### Data Processing Pipeline

338

339

System for processing raw query results into visualization formats.

340

341

```python { .api }

342

class DataProcessor:

343

"""Data processing utilities for visualizations."""

344

345

@staticmethod

346

def pivot_df(df: pd.DataFrame, rows: List[str], cols: List[str],

347

metric: str, aggfunc: str = 'sum',

348

fill_value: Any = 0) -> pd.DataFrame:

349

"""

350

Pivot DataFrame for cross-tabulation.

351

352

Args:

353

df: Source DataFrame

354

rows: Row dimension columns

355

cols: Column dimension columns

356

metric: Value column to aggregate

357

aggfunc: Aggregation function

358

fill_value: Value for missing cells

359

360

Returns:

361

Pivoted DataFrame

362

"""

363

364

@staticmethod

365

def flatten_df(df: pd.DataFrame) -> pd.DataFrame:

366

"""

367

Flatten DataFrame with MultiIndex columns.

368

369

Args:

370

df: DataFrame to flatten

371

372

Returns:

373

DataFrame with single-level column index

374

"""

375

376

@staticmethod

377

def apply_time_grain(df: pd.DataFrame, time_grain: str,

378

time_col: str) -> pd.DataFrame:

379

"""

380

Apply time granularity to DataFrame.

381

382

Args:

383

df: Time series DataFrame

384

time_grain: Granularity (P1D, PT1H, etc.)

385

time_col: Datetime column name

386

387

Returns:

388

DataFrame aggregated to specified granularity

389

"""

390

391

@staticmethod

392

def post_process(df: pd.DataFrame,

393

form_data: Dict[str, Any]) -> pd.DataFrame:

394

"""

395

Apply post-processing operations to DataFrame.

396

397

Args:

398

df: Processed DataFrame

399

form_data: Chart configuration

400

401

Returns:

402

Post-processed DataFrame

403

"""

404

405

def df_to_records(df: pd.DataFrame) -> List[Dict[str, Any]]:

406

"""Convert DataFrame to list of records."""

407

408

def apply_row_limit(df: pd.DataFrame, limit: int) -> pd.DataFrame:

409

"""Apply row limit to DataFrame."""

410

411

def apply_filters(df: pd.DataFrame,

412

filters: List[Dict[str, Any]]) -> pd.DataFrame:

413

"""Apply filter conditions to DataFrame."""

414

```

415

416

### Plugin System

417

418

Architecture for creating custom chart types and visualizations.

419

420

```python { .api }

421

class VizPlugin:

422

"""Base class for visualization plugins."""

423

424

viz_type: str # Unique identifier

425

verbose_name: str # Display name

426

category: str = "Other" # Plugin category

427

428

@classmethod

429

def get_viz_class(cls) -> Type[BaseViz]:

430

"""

431

Get visualization class for this plugin.

432

433

Returns:

434

BaseViz subclass

435

"""

436

437

@classmethod

438

def get_form_data_spec(cls) -> Dict[str, Any]:

439

"""

440

Get form specification for chart configuration.

441

442

Returns:

443

Form field specifications

444

"""

445

446

@classmethod

447

def register(cls) -> None:

448

"""Register plugin with visualization system."""

449

450

def load_viz_plugins(plugin_dir: str) -> None:

451

"""

452

Load visualization plugins from directory.

453

454

Args:

455

plugin_dir: Directory containing plugin modules

456

"""

457

458

def register_viz_type(viz_type: str, viz_class: Type[BaseViz]) -> None:

459

"""

460

Register new visualization type.

461

462

Args:

463

viz_type: Unique chart type identifier

464

viz_class: Visualization implementation class

465

"""

466

```

467

468

**Usage Examples:**

469

470

```python

471

# Create custom visualization

472

class MyCustomViz(BaseViz):

473

viz_type = "my_custom"

474

verbose_name = "My Custom Chart"

475

476

def get_data(self, df):

477

# Custom data processing logic

478

return {'data': df.to_dict('records')}

479

480

# Register custom visualization

481

register_viz_type("my_custom", MyCustomViz)

482

483

# Use visualization in chart

484

viz = get_viz("my_custom", datasource, form_data)

485

chart_data = viz.get_json_data()

486

```

487

488

## Visualization Configuration

489

490

### Chart Form Data

491

492

```python { .api }

493

# Common form data fields across chart types

494

FormData = {

495

'datasource': str, # Datasource identifier

496

'viz_type': str, # Chart type

497

'metrics': List[str], # Metrics to display

498

'groupby': List[str], # Grouping columns

499

'time_grain_sqla': str, # Time granularity

500

'since': str, # Start time

501

'until': str, # End time

502

'filters': List[Dict], # Filter conditions

503

'row_limit': int, # Row limit

504

'order_desc': bool, # Sort order

505

'color_scheme': str, # Color palette

506

'show_legend': bool, # Show/hide legend

507

'rich_tooltip': bool, # Enhanced tooltips

508

'y_axis_format': str, # Y-axis number format

509

}

510

```