Id like to create a dashboard with the following KPIs. Each section will be its own unique tab: 1. Knowledge Inventory : Tracks the volume, status, and lifecycle of content in the knowledge base. Example KPIs: Number of Published KBAs Number of Active Articles Number of Articles Retired % of Articles Reviewed Time to Publish (SLA) — if tracked 2. Usage & Adoption: Shows how often knowledge is being used and integrated into workflows. Example KPIs: KBA Views % of KBAs in Use % of KBAs Attached to Tickets Articles Created from Ticket Management Most Viewed/Used KBAs % of Tickets Closed with a KBA (to be added)
Drop files here
or click to upload
import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import altair as alt
from datetime import datetime, timedelta
import random
# Set page config
st.set_page_config(
page_title="Knowledge Base Dashboard",
page_icon="📊",
layout="wide"
)
# Generate sample data
@st.cache_data
def generate_sample_data():
# Knowledge Inventory Data
np.random.seed(42)
dates = pd.date_range(start='2024-01-01', end='2024-12-31', freq='D')
knowledge_inventory = {
'published_kbas': np.random.randint(450, 550, len(dates)),
'active_articles': np.random.randint(400, 480, len(dates)),
'retired_articles': np.random.randint(20, 60, len(dates)),
'reviewed_percentage': np.random.uniform(75, 95, len(dates)),
'time_to_publish': np.random.uniform(2, 8, len(dates)), # days
'date': dates
}
# Usage & Adoption Data
usage_adoption = {
'kba_views': np.random.randint(1000, 5000, len(dates)),
'kbas_in_use_percentage': np.random.uniform(60, 85, len(dates)),
'kbas_attached_to_tickets_percentage': np.random.uniform(40, 70, len(dates)),
'articles_from_tickets': np.random.randint(5, 25, len(dates)),
'tickets_closed_with_kba_percentage': np.random.uniform(25, 50, len(dates)),
'date': dates
}
# Most viewed KBAs
kba_titles = [
"Password Reset Procedures",
"VPN Connection Issues",
"Email Configuration Guide",
"Software Installation Steps",
"Network Troubleshooting",
"Database Connection Problems",
"Security Best Practices",
"Backup and Recovery",
"User Account Management",
"System Performance Issues"
]
most_viewed_kbas = pd.DataFrame({
'KBA_Title': kba_titles,
'Views': np.random.randint(500, 3000, len(kba_titles)),
'Category': np.random.choice(['IT Support', 'Security', 'Network', 'Database', 'General'], len(kba_titles))
}).sort_values('Views', ascending=False)
return pd.DataFrame(knowledge_inventory), pd.DataFrame(usage_adoption), most_viewed_kbas
# Load data
ki_data, ua_data, top_kbas = generate_sample_data()
# Main title
st.title("📊 Knowledge Base Dashboard")
st.markdown("---")
# Create tabs
tab1, tab2 = st.tabs(["📚 Knowledge Inventory", "📈 Usage & Adoption"])
with tab1:
st.header("Knowledge Inventory")
st.markdown("Tracks the volume, status, and lifecycle of content in the knowledge base.")
# Current metrics row
col1, col2, col3, col4 = st.columns(4)
current_date = ki_data['date'].max()
latest_data = ki_data[ki_data['date'] == current_date].iloc[0]
with col1:
st.metric(
"Published KBAs",
f"{latest_data['published_kbas']:,}",
delta=f"{latest_data['published_kbas'] - ki_data['published_kbas'].iloc[-30]}"
)
with col2:
st.metric(
"Active Articles",
f"{latest_data['active_articles']:,}",
delta=f"{latest_data['active_articles'] - ki_data['active_articles'].iloc[-30]}"
)
with col3:
st.metric(
"Articles Reviewed",
f"{latest_data['reviewed_percentage']:.1f}%",
delta=f"{latest_data['reviewed_percentage'] - ki_data['reviewed_percentage'].iloc[-30]:.1f}%"
)
with col4:
st.metric(
"Avg Time to Publish",
f"{latest_data['time_to_publish']:.1f} days",
delta=f"{latest_data['time_to_publish'] - ki_data['time_to_publish'].iloc[-30]:.1f}"
)
# Charts row
col1, col2 = st.columns(2)
with col1:
st.subheader("Article Status Over Time")
fig = go.Figure()
fig.add_trace(go.Scatter(
x=ki_data['date'],
y=ki_data['published_kbas'],
mode='lines',
name='Published KBAs',
line=dict(color='#1f77b4')
))
fig.add_trace(go.Scatter(
x=ki_data['date'],
y=ki_data['active_articles'],
mode='lines',
name='Active Articles',
line=dict(color='#2ca02c')
))
fig.add_trace(go.Scatter(
x=ki_data['date'],
y=ki_data['retired_articles'],
mode='lines',
name='Retired Articles',
line=dict(color='#ff7f0e')
))
fig.update_layout(
xaxis_title="Date",
yaxis_title="Number of Articles",
hovermode='x unified'
)
st.plotly_chart(fig, use_container_width=True)
with col2:
st.subheader("Time to Publish Trend")
fig = px.line(
ki_data,
x='date',
y='time_to_publish',
title="Average Time to Publish (Days)"
)
fig.add_hline(
y=5,
line_dash="dash",
line_color="red",
annotation_text="SLA Target: 5 days"
)
fig.update_layout(
xaxis_title="Date",
yaxis_title="Days"
)
st.plotly_chart(fig, use_container_width=True)
# Review percentage chart
st.subheader("Article Review Completion Rate")
fig = px.area(
ki_data,
x='date',
y='reviewed_percentage',
title="Percentage of Articles Reviewed"
)
fig.add_hline(
y=90,
line_dash="dash",
line_color="green",
annotation_text="Target: 90%"
)
fig.update_layout(
xaxis_title="Date",
yaxis_title="Percentage (%)",
yaxis=dict(range=[0, 100])
)
st.plotly_chart(fig, use_container_width=True)
with tab2:
st.header("Usage & Adoption")
st.markdown("Shows how often knowledge is being used and integrated into workflows.")
# Current metrics row
col1, col2, col3, col4 = st.columns(4)
latest_ua_data = ua_data[ua_data['date'] == ua_data['date'].max()].iloc[0]
with col1:
st.metric(
"KBA Views (Today)",
f"{latest_ua_data['kba_views']:,}",
delta=f"{latest_ua_data['kba_views'] - ua_data['kba_views'].iloc[-30]:,}"
)
with col2:
st.metric(
"KBAs in Use",
f"{latest_ua_data['kbas_in_use_percentage']:.1f}%",
delta=f"{latest_ua_data['kbas_in_use_percentage'] - ua_data['kbas_in_use_percentage'].iloc[-30]:.1f}%"
)
with col3:
st.metric(
"KBAs Attached to Tickets",
f"{latest_ua_data['kbas_attached_to_tickets_percentage']:.1f}%",
delta=f"{latest_ua_data['kbas_attached_to_tickets_percentage'] - ua_data['kbas_attached_to_tickets_percentage'].iloc[-30]:.1f}%"
)
with col4:
st.metric(
"Tickets Closed with KBA",
f"{latest_ua_data['tickets_closed_with_kba_percentage']:.1f}%",
delta=f"{latest_ua_data['tickets_closed_with_kba_percentage'] - ua_data['tickets_closed_with_kba_percentage'].iloc[-30]:.1f}%"
)
# Charts row
col1, col2 = st.columns(2)
with col1:
st.subheader("KBA Views Over Time")
fig = px.line(
ua_data,
x='date',
y='kba_views',
title="Daily KBA Views"
)
fig.update_layout(
xaxis_title="Date",
yaxis_title="Number of Views"
)
st.plotly_chart(fig, use_container_width=True)
with col2:
st.subheader("Articles Created from Tickets")
fig = px.bar(
ua_data.tail(30),
x='date',
y='articles_from_tickets',
title="Daily Articles Created from Ticket Management"
)
fig.update_layout(
xaxis_title="Date",
yaxis_title="Number of Articles"
)
st.plotly_chart(fig, use_container_width=True)
# Usage percentage trends
st.subheader("Usage & Adoption Trends")
fig = go.Figure()
fig.add_trace(go.Scatter(
x=ua_data['date'],
y=ua_data['kbas_in_use_percentage'],
mode='lines',
name='KBAs in Use (%)',
line=dict(color='#1f77b4')
))
fig.add_trace(go.Scatter(
x=ua_data['date'],
y=ua_data['kbas_attached_to_tickets_percentage'],
mode='lines',
name='KBAs Attached to Tickets (%)',
line=dict(color='#ff7f0e')
))
fig.add_trace(go.Scatter(
x=ua_data['date'],
y=ua_data['tickets_closed_with_kba_percentage'],
mode='lines',
name='Tickets Closed with KBA (%)',
line=dict(color='#2ca02c')
))
fig.update_layout(
xaxis_title="Date",
yaxis_title="Percentage (%)",
hovermode='x unified',
yaxis=dict(range=[0, 100])
)
st.plotly_chart(fig, use_container_width=True)
# Most viewed KBAs
st.subheader("Most Viewed/Used KBAs")
col1, col2 = st.columns([2, 1])
with col1:
fig = px.bar(
top_kbas,
x='Views',
y='KBA_Title',
orientation='h',
color='Category',
title="Top 10 Most Viewed KBAs"
)
fig.update_layout(
yaxis={'categoryorder': 'total ascending'},
height=500
)
st.plotly_chart(fig, use_container_width=True)
with col2:
st.subheader("Top KBAs Table")
st.dataframe(
top_kbas[['KBA_Title', 'Views', 'Category']],
use_container_width=True,
height=400
)
# Footer
st.markdown("---")
st.markdown("*Dashboard automatically refreshes with the latest data. Last updated: " + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "*")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?