Skip to content

Apex Charts support #110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ venv/
ENV/
env.bak/
venv.bak/
uv.lock

# Spyder project settings
.spyderproject
Expand Down
41 changes: 41 additions & 0 deletions docs/api_reference/api_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,3 +1165,44 @@ def ex_loading2():
LoadingT,
title="Loading")


# Charts
def ex_line_chart():
return ApexChart(
opts={
"chart": {"type":"line", "zoom":{"enabled": False}, "toolbar":{"show":False}},
"series": [{"name":"Desktops", "data": [186, 305, 237, 73, 209, 214, 355]}],
"xaxis": {"categories":["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]}
},
cls='max-w-md max-h-md'
)

def ex_pie_chart():
return ApexChart(
opts={
"chart": {"type":"pie", "zoom":{"enabled": False}, "toolbar":{"show":False}},
"series": [186, 305, 237, 73, 209, 214, 355],
"labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]
},
cls='max-w-md max-h-md'
)

docs_charts = create_doc_section(
H1("Charts API Reference"),
P(
"MonsterUI supports ", A("ApexCharts", href="https://apexcharts.com/", cls='underline'),
", a javascript library for rendering different charts like line and pie charts. ",
"See the full list of chart types ", A("here.", href="https://apexcharts.com/javascript-chart-demos/", cls='underline'),
),
P("To render a chart you'll need to include the ApexChart js in your app headers like this"),
CodeSpan("app, rt = fast_app(hdrs=Theme.blue.headers(apex_charts=True))"),
P("Then create an " , CodeSpan("ApexChart"), " component as shown in the examples below."),
P("Generally, you should be able to take any chart from the ApexChart docs, convert the chart's options var to a python dict and plug it straight into MonsterUI's ApexChart component."),
H2("Example usage", cls="mt-4"),
H4("Line chart", cls="mt-4"),
fn2code_string(ex_line_chart),
H4("Pie chart", cls="mt-4"),
fn2code_string(ex_pie_chart),
ApexChart,
title="Charts"
)
2 changes: 1 addition & 1 deletion docs/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def _not_found(req, exc):


app,rt = fast_app(exception_handlers={404:_not_found}, pico=False,
hdrs=(*Theme.blue.headers(highlightjs=True), Link(rel="icon", type="image/x-icon", href="/favicon.ico"),
hdrs=(*Theme.blue.headers(highlightjs=True,apex_charts=True), Link(rel="icon", type="image/x-icon", href="/favicon.ico"),
Link(rel="stylesheet", href="/custom_theme.css", type="text/css")),
)

Expand Down
1 change: 1 addition & 0 deletions monsterui/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
'monsterui.franken.Accordion': ('franken.html#accordion', 'monsterui/franken.py'),
'monsterui.franken.AccordionItem': ('franken.html#accordionitem', 'monsterui/franken.py'),
'monsterui.franken.Address': ('franken.html#address', 'monsterui/franken.py'),
'monsterui.franken.ApexChart': ('franken.html#apexchart', 'monsterui/franken.py'),
'monsterui.franken.Article': ('franken.html#article', 'monsterui/franken.py'),
'monsterui.franken.ArticleMeta': ('franken.html#articlemeta', 'monsterui/franken.py'),
'monsterui.franken.ArticleTitle': ('franken.html#articletitle', 'monsterui/franken.py'),
Expand Down
12 changes: 7 additions & 5 deletions monsterui/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def _headers_theme(color, mode='auto', radii=ThemeRadii.sm, shadows=ThemeShadows
'franken_icons': "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/icon.iife.js",
'tailwind': "https://cdn.tailwindcss.com/3.4.16",
'daisyui': "https://cdn.jsdelivr.net/npm/[email protected]/dist/full.min.css",
'apex_charts': "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/chart.iife.js",
'highlight_js': "https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js",
'highlight_python': "https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/python.min.js",
'highlight_light_css': "https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/atom-one-light.css",
Expand Down Expand Up @@ -182,7 +183,7 @@ def _generate_next_value_(name, start, count, last_values): return name
violet = auto()
zinc = auto()

def _create_headers(self, urls, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm):
def _create_headers(self, urls, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, apex_charts=False, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm):
"Create header elements with given URLs"
hdrs = [
fh.Link(rel="stylesheet", href=urls['franken_css']),
Expand All @@ -198,6 +199,7 @@ def _create_headers(self, urls, mode='auto', icons=True, daisy=True, highlightjs

if icons: hdrs.append(fh.Script(type="module", src=urls['franken_icons']))
if daisy: hdrs += [fh.Link(rel="stylesheet", href=urls['daisyui']), daisy_styles]
if apex_charts: hdrs += [fh.Script(type='module', src=urls['apex_charts'])]

if highlightjs:
hdrs += [
Expand Down Expand Up @@ -251,12 +253,12 @@ def _create_headers(self, urls, mode='auto', icons=True, daisy=True, highlightjs
]
return hdrs

def headers(self, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm ):
def headers(self, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, apex_charts=False, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm ):
"Create frankenui and tailwind cdns"
return self._create_headers(HEADER_URLS, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, radii=radii, shadows=shadows, font=font)
return self._create_headers(HEADER_URLS, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, apex_charts=apex_charts, radii=radii, shadows=shadows, font=font)

def local_headers(self, mode='auto', static_dir='static', icons=True, daisy=True, highlightjs=False, katex=True, radii='md', shadows='sm', font='sm'):
def local_headers(self, mode='auto', static_dir='static', icons=True, daisy=True, highlightjs=False, katex=True, apex_charts=False, radii='md', shadows='sm', font='sm'):
"Create headers using local files downloaded from CDNs"
Path(static_dir).mkdir(exist_ok=True)
local_urls = dict([_download_resource(url, static_dir) for url in HEADER_URLS.items()])
return self._create_headers(local_urls, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, radii=radii, shadows=shadows, font=font)
return self._create_headers(local_urls, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, apex_charts=apex_charts, radii=radii, shadows=shadows, font=font)
15 changes: 13 additions & 2 deletions monsterui/franken.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
'SliderNav', 'Slider', 'DropDownNavContainer', 'TabContainer', 'CardT', 'CardTitle', 'CardHeader',
'CardBody', 'CardFooter', 'CardContainer', 'Card', 'TableT', 'Table', 'Td', 'Th', 'Tbody', 'TableFromLists',
'TableFromDicts', 'apply_classes', 'render_md', 'get_franken_renderer', 'ThemePicker', 'LightboxContainer',
'LightboxItem']
'LightboxItem', 'ApexChart']

# %% ../nbs/02_franken.ipynb
import fasthtml.common as fh
from .foundations import *
from fasthtml.common import Div, P, Span, FT
from enum import Enum, auto
from fasthtml.components import Uk_select,Uk_input_tag,Uk_icon,Uk_input_range
from fasthtml.components import Uk_select,Uk_input_tag,Uk_icon,Uk_input_range, Uk_chart
from functools import partial
from itertools import zip_longest
from typing import Union, Tuple, Optional, Sequence
Expand All @@ -36,6 +36,7 @@
import mistletoe
from lxml import html, etree
import fasthtml.components as fh_comp
import json

# %% ../nbs/02_franken.ipynb
class TextT(VEnum):
Expand Down Expand Up @@ -1627,3 +1628,13 @@ def LightboxItem(*c, # Component that when clicked will open the lightbox (often
)->FT: # A(... href, data_alt, cls., ...)
"Anchor tag with appropriate structure to go inside a `LightBoxContainer`"
return fh.A(*c, href=href, data_alt=data_alt, cls=stringify(cls), **kwargs)

# %% ../nbs/02_franken.ipynb
def ApexChart(*,
opts:Dict, # ApexChart options used to render your chart (e.g. {"chart":{"type":"line"}, ...})
cls: Enum | str | tuple = (), # Classes for the outer container
**kws, # Additional args for the outer container
)->FT: # Div(Uk_chart(Script(...)))
"Apex chart component"
js=NotStr(f"<script type='application/json'>{json.dumps(opts)}</script>")
return Div(Uk_chart(js), cls=stringify(cls), **kws)
12 changes: 7 additions & 5 deletions nbs/01_core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
" 'franken_icons': \"https://cdn.jsdelivr.net/npm/[email protected]/dist/js/icon.iife.js\",\n",
" 'tailwind': \"https://cdn.tailwindcss.com/3.4.16\",\n",
" 'daisyui': \"https://cdn.jsdelivr.net/npm/[email protected]/dist/full.min.css\",\n",
" 'apex_charts': \"https://cdn.jsdelivr.net/npm/[email protected]/dist/js/chart.iife.js\",\n",
" 'highlight_js': \"https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js\",\n",
" 'highlight_python': \"https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/python.min.js\",\n",
" 'highlight_light_css': \"https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/atom-one-light.css\",\n",
Expand Down Expand Up @@ -333,7 +334,7 @@
" violet = auto()\n",
" zinc = auto()\n",
"\n",
" def _create_headers(self, urls, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm):\n",
" def _create_headers(self, urls, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, apex_charts=False, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm):\n",
" \"Create header elements with given URLs\"\n",
" hdrs = [\n",
" fh.Link(rel=\"stylesheet\", href=urls['franken_css']),\n",
Expand All @@ -349,6 +350,7 @@
"\n",
" if icons: hdrs.append(fh.Script(type=\"module\", src=urls['franken_icons']))\n",
" if daisy: hdrs += [fh.Link(rel=\"stylesheet\", href=urls['daisyui']), daisy_styles]\n",
" if apex_charts: hdrs += [fh.Script(type='module', src=urls['apex_charts'])]\n",
" \n",
" if highlightjs:\n",
" hdrs += [\n",
Expand Down Expand Up @@ -402,15 +404,15 @@
" ]\n",
" return hdrs\n",
"\n",
" def headers(self, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm ):\n",
" def headers(self, mode='auto', icons=True, daisy=True, highlightjs=False, katex=True, apex_charts=False, radii=ThemeRadii.sm, shadows=ThemeShadows.sm, font=ThemeFont.sm ):\n",
" \"Create frankenui and tailwind cdns\"\n",
" return self._create_headers(HEADER_URLS, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, radii=radii, shadows=shadows, font=font) \n",
" return self._create_headers(HEADER_URLS, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, apex_charts=apex_charts, radii=radii, shadows=shadows, font=font) \n",
" \n",
" def local_headers(self, mode='auto', static_dir='static', icons=True, daisy=True, highlightjs=False, katex=True, radii='md', shadows='sm', font='sm'):\n",
" def local_headers(self, mode='auto', static_dir='static', icons=True, daisy=True, highlightjs=False, katex=True, apex_charts=False, radii='md', shadows='sm', font='sm'):\n",
" \"Create headers using local files downloaded from CDNs\"\n",
" Path(static_dir).mkdir(exist_ok=True)\n",
" local_urls = dict([_download_resource(url, static_dir) for url in HEADER_URLS.items()])\n",
" return self._create_headers(local_urls, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, radii=radii, shadows=shadows, font=font)"
" return self._create_headers(local_urls, mode=mode, icons=icons, daisy=daisy, highlightjs=highlightjs, katex=katex, apex_charts=apex_charts, radii=radii, shadows=shadows, font=font)"
]
},
{
Expand Down
Loading