import dash_mantine_components as dmc
from dash_iconify import DashIconify
from dash import Dash, _dash_renderer, Input, Output, State, clientside_callback,html, callback
import pandas as pd
# Ensure React version compatibility
_dash_renderer._set_react_version("18.2.0")
# Load Data
df = pd.read_csv("https://raw.githubusercontent.com/plotly/Figure-Friday/refs/heads/main/2025/week-10/Popularity%20of%20Programming%20Languages%20from%202004%20to%202024.csv")
# Split Date into month and year
df[['month', 'year']] = df['Date'].str.split(' ', expand=True)
# Keep only December data and drop unnecessary columns
df = df.loc[df['month'] == 'December'].drop(columns=['month', 'Date'])
# columns will be used to create the series
columns = list(df.columns)[:-1] # Exclude the 'year' column
# Convert year to integer for proper axis scaling
df["year"] = df["year"].astype(int)
# Prepare data for AreaChart
data = df.to_dict('records')
colors = ['yellow.5', 'teal.5', 'cyan.5','pink.5',
'yellow.9', 'teal.9', 'cyan.9','pink.9',
'yellow.2', 'teal.2' ]
# Initialize Dash App
app = Dash(external_stylesheets=dmc.styles.ALL)
# Theme Toggle Switch
theme_toggle = dmc.Switch(
offLabel=DashIconify(icon="radix-icons:sun", width=15, color=dmc.DEFAULT_THEME["colors"]["yellow"][8]),
onLabel=DashIconify(icon="radix-icons:moon", width=15, color=dmc.DEFAULT_THEME["colors"]["yellow"][6]),
id="color-scheme-toggle",
persistence=True,
color="grey",
w=70
)
# Define Layout
app.layout = dmc.MantineProvider(
dmc.Container(
[
dmc.Flex(
[
dmc.Title("Usage % of most popular programming languages over the years", order=3),
theme_toggle,
dmc.Divider(mb="lg"),
],direction={"base": "column", "sm": "row"},
gap={"base": "sm", "sm": "lg"},
align='center',
justify={"lg": "flex-end","sm": "center"},
style={"marginBottom": "2rem"}),
dmc.Divider(variant="solid", style = {"marginBottom":"2rem"}),
dmc.Flex(
[
dmc.MultiSelect(
label="Select your favorite programming language",
placeholder="Select all you like!, max 10",
id="framework-multi-select",
value=["PHP", "Python", "Java", "C/C++"],
data= [{"value": lang, "label": lang} for lang in columns],
w=400,
mb=10,
maxValues=10,
clearable=True,
searchable = True
),
dmc.Switch(
label="Zoom",
id="switch-zoom",
checked=True,
onLabel="ON",
offLabel="OFF"
),
],direction={"base": "column", "sm": "row"},
gap={"base": "sm", "sm": "lg"},
align='center',
justify={"lg": "flex-end","sm": "center"},),
html.Div(id='areachart'),
],
fluid=False,
),
id="mantine-provider",
forceColorScheme="light",
)
@callback(
Output("areachart", "children"), Input("framework-multi-select", "value"), Input("switch-zoom", "checked")
)
def select_value(value, checked):
# Assign colors to languages, cycling if there are more than 10
series = [{"name": lang, "color": colors[i % len(colors)]} for i, lang in enumerate(value)]
if checked:
yAxisProps_zoom={}
else:
yAxisProps_zoom={"domain": [0, 100]}
return dmc.AreaChart(
h=600,
dataKey="year", # X-axis
data=data, # Processed data
type="stacked",
series=series,
yAxisProps=yAxisProps_zoom,
curveType="monotone",
tickLine="xy",
xAxisLabel="Year",
yAxisLabel="Percentage of whole",
withGradient=True,
withXAxis=True,
withYAxis=True,
withDots=False,
withLegend=True,
fillOpacity="0.5"
)
# Clientside Callback for Theme Toggle
clientside_callback(
"""
(switchOn) => {
document.documentElement.setAttribute('data-mantine-color-scheme', switchOn ? 'dark' : 'light');
return window.dash_clientside.no_update;
}
""",
Output("color-scheme-toggle", "id"),
Input("color-scheme-toggle", "checked"),
)
# Run the App
if __name__ == "__main__":
app.run(debug=True)