|
| 1 | +--- |
| 2 | +title: Vega-Lite Chart |
| 3 | +sidebar_position: 15 |
| 4 | +description: Vega-Lite Chart |
| 5 | +keywords: |
| 6 | +- vega |
| 7 | +- vega-lite |
| 8 | +- charts |
| 9 | +- visualization |
| 10 | +--- |
| 11 | + |
| 12 | +import HeadTitle from '@site/src/components/General/HeadTitle.tsx'; |
| 13 | + |
| 14 | +<HeadTitle title="Vega-Lite Chart | OpenBB Workspace Docs" /> |
| 15 | + |
| 16 | +A widget that demonstrates how to use [Vega-Lite](https://vega.github.io/vega-lite/) to render a chart. Vega-Lite is a high-level grammar of interactive graphics — you describe the chart declaratively as JSON, and the renderer handles the rest. |
| 17 | + |
| 18 | +For Vega-Lite, your endpoint simply needs to return a Vega-Lite JSON specification. No extra Python package is required to build the spec — but if you'd like helpers, you can install `altair`: |
| 19 | + |
| 20 | +```bash |
| 21 | +pip install altair |
| 22 | +``` |
| 23 | + |
| 24 | +<img className="pro-border-gradient" width="800" alt="Vega-Lite Chart Example" src="https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/chart-vegalite.png" /> |
| 25 | + |
| 26 | +```python |
| 27 | +from fastapi import FastAPI, Query |
| 28 | + |
| 29 | +app = FastAPI() |
| 30 | + |
| 31 | + |
| 32 | +def _vega_theme(theme: str) -> dict: |
| 33 | + """Return mark color + base config for the given theme.""" |
| 34 | + if theme == "light": |
| 35 | + colors = {"fg": "#1a1a1a", "grid": "#e5e5e5", "mark": "#2563eb"} |
| 36 | + else: |
| 37 | + colors = {"fg": "#e5e7eb", "grid": "#2a2a2a", "mark": "#60a5fa"} |
| 38 | + return { |
| 39 | + "mark_color": colors["mark"], |
| 40 | + "config": { |
| 41 | + "background": "transparent", |
| 42 | + "axis": { |
| 43 | + "labelColor": colors["fg"], |
| 44 | + "titleColor": colors["fg"], |
| 45 | + "gridColor": colors["grid"], |
| 46 | + "domainColor": colors["grid"], |
| 47 | + "tickColor": colors["grid"], |
| 48 | + }, |
| 49 | + "legend": {"labelColor": colors["fg"], "titleColor": colors["fg"]}, |
| 50 | + "title": {"color": colors["fg"]}, |
| 51 | + "view": {"stroke": "transparent"}, |
| 52 | + }, |
| 53 | + } |
| 54 | + |
| 55 | + |
| 56 | +@register_widget({ |
| 57 | + "name": "Population by Era (Vega-Lite)", |
| 58 | + "description": "Vega-Lite bar chart of population by era", |
| 59 | + "type": "chart-vegalite", |
| 60 | + "endpoint": "era_population_vega", |
| 61 | + "gridData": {"w": 20, "h": 12} |
| 62 | +}) |
| 63 | +@app.get("/era_population_vega") |
| 64 | +def get_era_population_vega(theme: str = Query("dark")): |
| 65 | + """Vega-Lite bar chart of total population by era.""" |
| 66 | + values = [ |
| 67 | + {"era": "Pre-WWII", "total": 8_500_000}, |
| 68 | + {"era": "WWII", "total": 12_300_000}, |
| 69 | + {"era": "Post-WWII", "total": 18_700_000}, |
| 70 | + {"era": "Modern", "total": 24_500_000}, |
| 71 | + {"era": "Contemporary", "total": 31_200_000}, |
| 72 | + ] |
| 73 | + t = _vega_theme(theme) |
| 74 | + |
| 75 | + return { |
| 76 | + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", |
| 77 | + "title": "Population by Era (Vega-Lite)", |
| 78 | + "width": "container", |
| 79 | + "height": "container", |
| 80 | + "autosize": {"type": "fit", "contains": "padding"}, |
| 81 | + "config": t["config"], |
| 82 | + "data": {"values": values}, |
| 83 | + "mark": {"type": "bar", "color": t["mark_color"], "tooltip": True}, |
| 84 | + "encoding": { |
| 85 | + "x": {"field": "era", "type": "nominal", "sort": "-y", "title": "Era"}, |
| 86 | + "y": {"field": "total", "type": "quantitative", "title": "Total"}, |
| 87 | + }, |
| 88 | + } |
| 89 | +``` |
| 90 | + |
| 91 | +Note that for Vega-Lite, the `type` field is set to `"chart-vegalite"` instead of `"chart"` (Plotly) or `"chart-highcharts"` (Highcharts). |
| 92 | + |
| 93 | +The endpoint must return a valid Vega-Lite JSON spec. The two most important pieces are: |
| 94 | + |
| 95 | +- **`data.values`** — an inline array of records to plot. You can also use `data.url` to point at a remote dataset. |
| 96 | +- **`encoding`** — maps fields in your data to visual channels (`x`, `y`, `color`, `size`, etc.). |
| 97 | + |
| 98 | +### Theme Support |
| 99 | + |
| 100 | +The example includes full theme support for both dark and light modes. The theme parameter is automatically provided by OpenBB Workspace based on the user's current display mode (dark/light). The `_vega_theme` helper returns a `config` block that styles axes, legends, titles, and the view background to match the workspace. |
| 101 | + |
| 102 | +- **Dark mode**: light text (`#e5e7eb`), dark grid lines (`#2a2a2a`), light blue mark (`#60a5fa`) |
| 103 | +- **Light mode**: dark text (`#1a1a1a`), light grid lines (`#e5e5e5`), darker blue mark (`#2563eb`) |
| 104 | + |
| 105 | +The `background` is set to `"transparent"` so the chart blends into the widget canvas regardless of theme. |
| 106 | + |
| 107 | +## Additional Resources |
| 108 | + |
| 109 | +For more information on Vega-Lite specifications, visit the [Vega-Lite Documentation](https://vega.github.io/vega-lite/docs/) and the [example gallery](https://vega.github.io/vega-lite/examples/). |
| 110 | + |
| 111 | +You can find more examples of how to set up your own backend in the [Backend for OpenBB Workspace GitHub](https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace). |
0 commit comments