Generative AI

How can you design a dashboard that is user-friendly, powerful and dynamic using text?

In this tutorial, we create a custom dashboard – Writtenand we explore how fake UI frameworks can feel as big and powerful as today's web dashes. As we write and run each Snippet, we actively build the interface piece by piece, widgets, layouts, active state, and flow of events, so we can see how the engine behaves like a live UI inside Google Colab. In the end, we see that we can naturally combine trees, forms, and indicators of progress in a cohesive chair that feels fast, clean, and responsive. Look Full codes here.

!pip install textual textual-web nest-asyncio


from textual.app import App, ComposeResult
from textual.containers import Container, Horizontal, Vertical
from textual.widgets import (
   Header, Footer, Button, DataTable, Static, Input,
   Label, ProgressBar, Tree, Select
)
from textual.reactive import reactive
from textual import on
from datetime import datetime
import random


class StatsCard(Static):
   value = reactive(0)
  
   def __init__(self, title: str, *args, **kwargs):
       super().__init__(*args, **kwargs)
       self.title = title
      
   def compose(self) -> ComposeResult:
       yield Label(self.title)
       yield Label(str(self.value), id="stat-value")
  
   def watch_value(self, new_value: int) -> None:
       if self.is_mounted:
           try:
               self.query_one("#stat-value", Label).update(str(new_value))
           except Exception:
               pass

We set up the environment and import all the things needed to build our script. As we define the Statscard Widget, we create a persistent component that responds to changes in value and updates itself automatically. We're starting to see how the operating system allows us to create powerful UI elements with minimal effort. Look Full codes here.

class DataDashboard(App):
   CSS = """
   Screen { background: $surface; }
   #main-container { height: 100%; padding: 1; }
   #stats-row { height: auto; margin-bottom: 1; }
   StatsCard { border: solid $primary; height: 5; padding: 1; margin-right: 1; width: 1fr; }
   #stat-value { text-style: bold; color: $accent; content-align: center middle; }
   #control-panel { height: 12; border: solid $secondary; padding: 1; margin-bottom: 1; }
   #data-section { height: 1fr; }
   #left-panel { width: 30; border: solid $secondary; padding: 1; margin-right: 1; }
   DataTable { height: 100%; border: solid $primary; }
   Input { margin: 1 0; }
   Button { margin: 1 1 1 0; }
   ProgressBar { margin: 1 0; }
   """
  
   BINDINGS = [
       ("d", "toggle_dark", "Toggle Dark Mode"),
       ("q", "quit", "Quit"),
       ("a", "add_row", "Add Row"),
       ("c", "clear_table", "Clear Table"),
   ]
  
   total_rows = reactive(0)
   total_sales = reactive(0)
   avg_rating = reactive(0.0)

We define the data-board category and prepare global trends, important relationships, and functional characteristics. We decide how the app should look and behave from the top down, giving us full control over themes and interactions. This feature helps us to create a custom dashboard without writing any HTML or JS. Look Full codes here.

  def compose(self) -> ComposeResult:
       yield Header(show_clock=True)
      
       with Container(id="main-container"):
           with Horizontal(id="stats-row"):
               yield StatsCard("Total Rows", id="card-rows")
               yield StatsCard("Total Sales", id="card-sales")
               yield StatsCard("Avg Rating", id="card-rating")
          
           with Vertical(id="control-panel"):
               yield Input(placeholder="Product Name", id="input-name")
               yield Select(
                   [("Electronics", "electronics"),
                    ("Books", "books"),
                    ("Clothing", "clothing")],
                   prompt="Select Category",
                   id="select-category"
               )
               with Horizontal():
                   yield Button("Add Row", variant="primary", id="btn-add")
                   yield Button("Clear Table", variant="warning", id="btn-clear")
                   yield Button("Generate Data", variant="success", id="btn-generate")
               yield ProgressBar(total=100, id="progress")
          
           with Horizontal(id="data-section"):
               with Container(id="left-panel"):
                   yield Label("Navigation")
                   tree = Tree("Dashboard")
                   tree.root.expand()
                   products = tree.root.add("Products", expand=True)
                   products.add_leaf("Electronics")
                   products.add_leaf("Books")
                   products.add_leaf("Clothing")
                   tree.root.add_leaf("Reports")
                   tree.root.add_leaf("Settings")
                   yield tree
              
               yield DataTable(id="data-table")
      
       yield Footer()

We design all UI layouts, layout containers, cards, inputs, buttons, ship tree, and data table. As we edit these components, we watch the interface take shape the way we voted. This snippet lets us design the visual bones of the dashboard in a clean, fun way. Look Full codes here.

 def on_mount(self) -> None:
       table = self.query_one(DataTable)
       table.add_columns("ID", "Product", "Category", "Price", "Sales", "Rating")
       table.cursor_type = "row"
       self.generate_sample_data(5)
       self.set_interval(0.1, self.update_progress)
  
   def generate_sample_data(self, count: int = 5) -> None:
       table = self.query_one(DataTable)
       categories = ["Electronics", "Books", "Clothing"]
       products = {
           "Electronics": ["Laptop", "Phone", "Tablet", "Headphones"],
           "Books": ["Novel", "Textbook", "Magazine", "Comic"],
           "Clothing": ["Shirt", "Pants", "Jacket", "Shoes"]
       }
      
       for _ in range(count):
           category = random.choice(categories)
           product = random.choice(productsArtificial Intelligence)
           row_id = self.total_rows + 1
           price = round(random.uniform(10, 500), 2)
           sales = random.randint(1, 100)
           rating = round(random.uniform(1, 5), 1)
          
           table.add_row(
               str(row_id),
               product,
               category,
               f"${price}",
               str(sales),
               str(rating)
           )
          
           self.total_rows += 1
           self.total_sales += sales
      
       self.update_stats()
  
   def update_stats(self) -> None:
       self.query_one("#card-rows", StatsCard).value = self.total_rows
       self.query_one("#card-sales", StatsCard).value = self.total_sales
      
       if self.total_rows > 0:
           table = self.query_one(DataTable)
           total_rating = sum(float(row[5]) for row in table.rows)
           self.avg_rating = round(total_rating / self.total_rows, 2)
           self.query_one("#card-rating", StatsCard).value = self.avg_rating
  
   def update_progress(self) -> None:
       progress = self.query_one(ProgressBar)
       progress.advance(1)
       if progress.progress >= 100:
           progress.progress = 0

We use all data generation logic, computer statistics, update progress, and update cards. We see how we can bind virtual currency to frontend elements using the active text model. This step makes the dashboard feel alive as the numbers update quickly and the progress bars have a nice smooth texture. Look Full codes here.

 @on(Button.Pressed, "#btn-add")
   def handle_add_button(self) -> None:
       name_input = self.query_one("#input-name", Input)
       category = self.query_one("#select-category", Select).value
      
       if name_input.value and category:
           table = self.query_one(DataTable)
           row_id = self.total_rows + 1
           price = round(random.uniform(10, 500), 2)
           sales = random.randint(1, 100)
           rating = round(random.uniform(1, 5), 1)
          
           table.add_row(
               str(row_id),
               name_input.value,
               str(category),
               f"${price}",
               str(sales),
               str(rating)
           )
          
           self.total_rows += 1
           self.total_sales += sales
           self.update_stats()
           name_input.value = ""
  
   @on(Button.Pressed, "#btn-clear")
   def handle_clear_button(self) -> None:
       table = self.query_one(DataTable)
       table.clear()
       self.total_rows = 0
       self.total_sales = 0
       self.avg_rating = 0
       self.update_stats()
  
   @on(Button.Pressed, "#btn-generate")
   def handle_generate_button(self) -> None:
       self.generate_sample_data(10)
  
   def action_toggle_dark(self) -> None:
       self.dark = not self.dark
  
   def action_add_row(self) -> None:
       self.handle_add_button()
  
   def action_clear_table(self) -> None:
       self.handle_clear_button()




if __name__ == "__main__":
   import nest_asyncio
   nest_asyncio.apply()
   app = DataDashboard()
   app.run()

We connect UI events to backend actions using button managers, keyboard shortcuts, and application-level functions. As we use the app, we interact with a fully functional dashboard that responds quickly to every click and command. This tutorial completes the program and shows how easy it should be to be able to build dynamic, state-driven UIs.

In conclusion, we see the entire dashboard coming together in a fully functional, interactive way that runs directly in the notebook environment. We find out firsthand how it allows us to design a terminal UIS with a layout and feel for web applications, while staying entirely in Python. This tutorial leaves us confident that we can extend this foundation, even adding charts, multi-page feeds, as we continue to explore modern UI capabilities.


Look Full codes here. Feel free to take a look at ours GitHub page for tutorials, code and notebooks. Also, feel free to follow us Kind of stubborn and don't forget to join ours 100K + ML Subreddit and sign up Our newsletter. Wait! Do you telegraph? Now you can join us by telegraph.


AsifAzzaq is the CEO of MarktechPost Media Inc.. as a visionary entrepreneur and developer, Asifi is committed to harnessing the power of social intelligence for good. His latest effort is the launch of a media intelligence platform, MarktechPpost, which stands out for its deep understanding of machine learning and deep learning stories that are technically sound and easily understood by a wide audience. The platform sticks to more than two million monthly views, which shows its popularity among the audience.

Follow Marktechpost: Add us as a favorite source on Google.

Source link

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button