Hey Devs! π
Ever wished your terminal-based applications could have interactive, dynamic charts? Well, we just made it happen by integrating a custom charting library into a Textual custom widget! π¨β¨
Why This Matters?
Textual is an incredible framework for building rich, interactive terminal applications, but charting support is limited out of the box. So, we built a custom widget that seamlessly integrates with an external charting library to bring smooth, interactive financial & technical charts directly inside a TUI.
π How We Did It
β
Built a Custom ChartWidget inside Textual
β
Integrated Plotly (or any other charting library) for rendering dynamic charts
β
Used asyncio for smooth updates without UI freezing
β
Enabled multiple chart types (Line, Bar, Candlestick, etc.)
β
Created a Switch & Collapsible UI to toggle charts on demand
from textual.widget import Widget
from textual.containers import Horizontal, Container
from textual.widgets import Button, Static, Switch
import asyncio
import plotly.graph_objects as go
class ChartWidget(Widget):
"""A custom Textual widget to display dynamic charts."""
def __init__(self, chart_type="line", title="Chart", widget_id="chart_widget", **kwargs):
super().__init__(id=widget_id, **kwargs)
self.chart_type = chart_type
self.title = title
self.chart_path = None # Stores chart file path
def compose(self):
with Container():
yield Static(f"π {self.title}", classes="chart-title")
yield Switch(value=True, id=f"{self.id}_toggle", label="Show Chart", classes="toggle-switch")
with Horizontal():
yield Button("Open", id=f"{self.id}_open_chart")
yield Button("Close", id=f"{self.id}_close_chart")
async def generate_chart(self, data):
"""Generates an interactive chart asynchronously."""
self.chart_path = await asyncio.to_thread(self._render_chart, data)
def _render_chart(self, data):
"""Handles chart rendering using Plotly."""
fig = go.Figure()
fig.add_trace(go.Scatter(x=data["x"], y=data["y"], mode="lines", name="Line Chart"))
chart_path = f"{self.title}.html"
fig.write_html(chart_path)
return chart_path
π What's Next?
We are expanding this to support real-time streaming charts inside Textual! Drop a π₯ in the comments if you're excited! Would love to hear your thoughts! π¬π
π Check out the full implementation & contribute to the repo:Fincept Terminal
Top comments (0)