reflex-monocharts 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. reflex_monocharts-0.1.1/LICENSE +21 -0
  2. reflex_monocharts-0.1.1/PKG-INFO +235 -0
  3. reflex_monocharts-0.1.1/README.md +204 -0
  4. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/__init__.py +221 -0
  5. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/card.py +329 -0
  6. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/__init__.py +8 -0
  7. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/_common.py +107 -0
  8. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/areas.py +281 -0
  9. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/bars.py +504 -0
  10. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/layout.py +967 -0
  11. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/lines.py +416 -0
  12. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/points.py +216 -0
  13. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/charts/polar.py +716 -0
  14. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/data.py +303 -0
  15. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/py.typed +0 -0
  16. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/theme.py +161 -0
  17. reflex_monocharts-0.1.1/custom_components/reflex_monocharts/tooltip.py +123 -0
  18. reflex_monocharts-0.1.1/custom_components/reflex_monocharts.egg-info/PKG-INFO +235 -0
  19. reflex_monocharts-0.1.1/custom_components/reflex_monocharts.egg-info/SOURCES.txt +23 -0
  20. reflex_monocharts-0.1.1/custom_components/reflex_monocharts.egg-info/dependency_links.txt +1 -0
  21. reflex_monocharts-0.1.1/custom_components/reflex_monocharts.egg-info/requires.txt +10 -0
  22. reflex_monocharts-0.1.1/custom_components/reflex_monocharts.egg-info/top_level.txt +1 -0
  23. reflex_monocharts-0.1.1/pyproject.toml +74 -0
  24. reflex_monocharts-0.1.1/setup.cfg +4 -0
  25. reflex_monocharts-0.1.1/tests/test_charts.py +66 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ernesto Crespo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: reflex-monocharts
3
+ Version: 0.1.1
4
+ Summary: Monochromatic, rounded chart cards for Reflex - a Python port of the Monocharts design system built on rx.recharts.
5
+ Author-email: Ernesto Crespo <ecrespo@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ecrespo/reflex-monocharts
8
+ Project-URL: Source, https://github.com/ecrespo/reflex-monocharts
9
+ Project-URL: Issues, https://github.com/ecrespo/reflex-monocharts/issues
10
+ Keywords: reflex,reflex-custom-components,charts,recharts,monocharts,dataviz
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Scientific/Engineering :: Visualization
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: reflex>=0.9.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: build; extra == "dev"
24
+ Requires-Dist: twine; extra == "dev"
25
+ Requires-Dist: pytest>=8; extra == "dev"
26
+ Requires-Dist: pytest-cov>=5; extra == "dev"
27
+ Requires-Dist: ruff>=0.6; extra == "dev"
28
+ Requires-Dist: bandit[toml]>=1.7; extra == "dev"
29
+ Requires-Dist: pip-audit>=2.7; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # reflex-monocharts
33
+
34
+ Monochromatic, rounded chart cards for [Reflex](https://reflex.dev) — a pure-Python
35
+ port of the [Monocharts](https://github.com/Subhan-code/Monocharts) design system.
36
+
37
+ 28 components: splines, pill bars, gradient areas, donuts, radars, radial gauges,
38
+ bullet targets, treemaps, heatmaps, candlesticks, Sankey bands and a GitHub-style
39
+ contribution grid. All one hue, all rounded, dark and light.
40
+
41
+ ```bash
42
+ pip install reflex-monocharts
43
+ ```
44
+
45
+ ![Monocharts for Reflex, dark](https://raw.githubusercontent.com/ecrespo/reflex-monocharts/main/monocharts_demo/assets/preview-dark.png)
46
+ ![Monocharts for Reflex, light](https://raw.githubusercontent.com/ecrespo/reflex-monocharts/main/monocharts_demo/assets/preview-light.png)
47
+
48
+ ## Why a port and not a wrapper
49
+
50
+ Monocharts ships as copy-paste React/TSX built on Recharts and Tailwind, with the
51
+ data hard-coded in each component. Reflex already wraps Recharts, so this library
52
+ rebuilds the *design system* in Python instead of shipping JavaScript:
53
+
54
+ - **No npm dependency and no Tailwind requirement.** Every class is translated to
55
+ Reflex style props, so the cards drop into any Reflex app unchanged.
56
+ - **Data-driven.** Each chart takes `data` plus `*_key` arguments and binds to
57
+ `rx.State`. Call it with no arguments and you get the original demo card.
58
+ - **Reactive theming.** `theme=` accepts `"dark"`, `"light"`, or a state Var, so a
59
+ toggle re-themes every card without a reload. `compact=` works the same way.
60
+
61
+ ## Quick start
62
+
63
+ ```python
64
+ import reflex as rx
65
+ from reflex_monocharts import monocharts as mc
66
+
67
+
68
+ class State(rx.State):
69
+ theme: str = "dark"
70
+ traffic: list[dict] = [
71
+ {"hour": "02:00", "hits": 18},
72
+ {"hour": "06:00", "hits": 34},
73
+ {"hour": "10:00", "hits": 72},
74
+ ]
75
+
76
+ @rx.event
77
+ def toggle_theme(self):
78
+ self.theme = "light" if self.theme == "dark" else "dark"
79
+
80
+
81
+ def index() -> rx.Component:
82
+ return rx.vstack(
83
+ rx.button("Toggle theme", on_click=State.toggle_theme),
84
+ mc.area(
85
+ State.traffic,
86
+ x_key="hour",
87
+ value_key="hits",
88
+ theme=State.theme,
89
+ title="Traffic",
90
+ badge="Live",
91
+ unit="requests",
92
+ ),
93
+ mc.gauge(84, theme=State.theme),
94
+ width="420px",
95
+ )
96
+ ```
97
+
98
+ Long names are available too — `mc.area` is `mono_rounded_area_chart`.
99
+
100
+ ## The catalog
101
+
102
+ | Short name | Function | What it draws |
103
+ | --- | --- | --- |
104
+ | `mc.line` | `mono_rounded_line_chart` | Spline with a dashed baseline series |
105
+ | `mc.step` | `mono_rounded_step_chart` | Discrete staircase |
106
+ | `mc.sparkline` | `mono_rounded_sparkline_chart` | Stacked telemetry rows with micro splines |
107
+ | `mc.kpi` | `mono_rounded_kpi_card_chart` | Big KPI over a gradient sparkline |
108
+ | `mc.bar` | `mono_rounded_bar_chart` | Pill bars, as columns or rows |
109
+ | `mc.stacked_bar` | `mono_rounded_stacked_bar_chart` | Tonal stack with rounded ends |
110
+ | `mc.composed` | `mono_rounded_composed_chart` | Outlined columns plus a spline |
111
+ | `mc.waterfall` | `mono_rounded_waterfall_chart` | Floating delta pillars |
112
+ | `mc.funnel` | `mono_rounded_funnel_chart` | Horizontal pipeline stages |
113
+ | `mc.bullet` | `mono_rounded_bullet_chart` | Progress bars with benchmark markers |
114
+ | `mc.pyramid` | `mono_rounded_pyramid_chart` | Hierarchy tiers |
115
+ | `mc.candlestick` | `mono_rounded_candlestick_chart` | OHLC candles with rounded wicks |
116
+ | `mc.area` | `mono_rounded_area_chart` | Curved area with a soft gradient |
117
+ | `mc.range` | `mono_rounded_range_chart` | Floating min-max band |
118
+ | `mc.stream` | `mono_rounded_stream_chart` | Two natural-spline waves |
119
+ | `mc.donut` | `mono_rounded_donut_chart` | Donut with rounded caps and a centre readout |
120
+ | `mc.radar` | `mono_rounded_radar_chart` | Multi-axis polygon web |
121
+ | `mc.polar` | `mono_rounded_polar_chart` | 360-degree radial pillars |
122
+ | `mc.radial_group` | `mono_rounded_radial_bar_group` | Half-circle arc group |
123
+ | `mc.radial_gauge` | `mono_rounded_radial_gauge_chart` | Concentric progress rings |
124
+ | `mc.gauge` | `mono_rounded_gauge_arc` | 240-degree speedometer dial |
125
+ | `mc.meter` | `mono_rounded_meter_chart` | Semicircle meter |
126
+ | `mc.scatter` | `mono_rounded_scatter_chart` | Weighted node matrix |
127
+ | `mc.bubble` | `mono_rounded_bubble_chart` | Outlined bubbles, area-encoded |
128
+ | `mc.heatmap` | `mono_rounded_heatmap_chart` | Labelled density matrix |
129
+ | `mc.treemap` | `mono_rounded_treemap_chart` | Rounded partition tiles |
130
+ | `mc.sankey` | `mono_rounded_sankey_chart` | Curved flow bands |
131
+ | `mc.activity` | `mono_activity_heatmap` | Contribution grid (green/blue/purple/mono) |
132
+
133
+ ## Common arguments
134
+
135
+ Every chart accepts these, on top of its own `*_key` arguments:
136
+
137
+ | Argument | Meaning |
138
+ | --- | --- |
139
+ | `data` | Rows to plot. Omit for the built-in demo dataset. |
140
+ | `theme` | `"dark"`, `"light"`, or a state Var. |
141
+ | `compact` | Short card instead of tall. Accepts a Var. |
142
+ | `title` / `badge` | The uppercase eyebrow and the pill beside it. |
143
+ | `value` / `unit` | The headline metric and its muted suffix. Derived from the data when omitted. |
144
+ | `footer_left` / `footer_right` | The two monospace footer captions. |
145
+ | `control` | A component rendered flush right in the header. |
146
+ | `**props` | Any extra style props, forwarded to the card. |
147
+
148
+ ## Interactive controls
149
+
150
+ The originals bake their toggles into the component. Here the option is a prop,
151
+ so it can be wired to your own state — `mono_segmented` renders the matching pill
152
+ control:
153
+
154
+ ```python
155
+ from reflex_monocharts import mono_segmented, monocharts as mc
156
+
157
+
158
+ class State(rx.State):
159
+ curve: str = "monotone"
160
+
161
+ @rx.event
162
+ def set_curve(self, value: str):
163
+ self.curve = value
164
+
165
+
166
+ mc.area(
167
+ curve=State.curve,
168
+ control=mono_segmented(
169
+ [("monotone", "Monotone"), ("natural", "Natural")],
170
+ State.curve,
171
+ State.set_curve,
172
+ theme=State.theme,
173
+ ),
174
+ )
175
+ ```
176
+
177
+ The same pattern drives `series=` on the line card, `orientation=` on the bar card
178
+ and `show_trend=` on the hybrid card.
179
+
180
+ ## Building your own cards
181
+
182
+ The chrome is exported, so a custom chart can sit in the same system:
183
+
184
+ ```python
185
+ from reflex_monocharts import mono_card, mono_header, mono_stage, mono_footer, mono_tooltip
186
+
187
+ mono_card(
188
+ mono_header("My Metric", "Custom", "1,204", "events", theme="dark"),
189
+ mono_stage(my_chart, theme="dark"),
190
+ mono_footer("Left caption", "Right caption", theme="dark"),
191
+ theme="dark",
192
+ )
193
+ ```
194
+
195
+ `ink()`, `ink_alpha()`, `pick()` and `is_dark()` from `reflex_monocharts.theme`
196
+ resolve the monochrome palette for either a plain theme string or a Var.
197
+
198
+ ## Notes and deliberate differences
199
+
200
+ - **Badge and footer rule are theme-aware here.** Upstream hard-codes
201
+ `bg-white/10 text-white` and `border-white/5`, which is invisible on the light
202
+ card; this port resolves both per theme.
203
+ - **The tooltip is `rx.recharts.graphing_tooltip`** styled to match the original's
204
+ blurred dark panel. Recharts' `content` render-prop takes a React component,
205
+ which Reflex cannot pass, so the styling is reproduced through
206
+ `content_style` / `item_style` / `label_style`.
207
+ - **Gradients are defined in a hidden sibling `<svg>`** with a process-unique id,
208
+ so several gradient-filled cards can share a page.
209
+ - **`mono_activity_heatmap` seeds its RNG** so the grid is stable across
210
+ re-renders. Pass `seed=None` to `data.activity_contributions` for the original
211
+ random behaviour, and use a native `title` tooltip per cell rather than a
212
+ server round-trip for 140 cells.
213
+ - **`mono_rounded_candlestick_chart` needs explicit `low_bound`/`high_bound`**
214
+ when `data` is a state Var, since the price scale cannot be derived at build
215
+ time. `mono_rounded_sankey_chart` computes its band geometry in Python and
216
+ takes a plain list.
217
+
218
+ ## Demo app
219
+
220
+ ```bash
221
+ cd monocharts_demo
222
+ uv run reflex run
223
+ ```
224
+
225
+ The gallery shows every chart, a live-state section wired to `rx.State`, a theme
226
+ toggle, a compact toggle and a category filter.
227
+
228
+ ## Credits
229
+
230
+ Design system by [Syed Subhan](https://github.com/Subhan-code) — see
231
+ [Monocharts](https://github.com/Subhan-code/Monocharts) and
232
+ [amicro](https://amicro.vercel.app/mono-charts). This is an independent Python
233
+ port for Reflex, not affiliated with the original project.
234
+
235
+ MIT licensed.
@@ -0,0 +1,204 @@
1
+ # reflex-monocharts
2
+
3
+ Monochromatic, rounded chart cards for [Reflex](https://reflex.dev) — a pure-Python
4
+ port of the [Monocharts](https://github.com/Subhan-code/Monocharts) design system.
5
+
6
+ 28 components: splines, pill bars, gradient areas, donuts, radars, radial gauges,
7
+ bullet targets, treemaps, heatmaps, candlesticks, Sankey bands and a GitHub-style
8
+ contribution grid. All one hue, all rounded, dark and light.
9
+
10
+ ```bash
11
+ pip install reflex-monocharts
12
+ ```
13
+
14
+ ![Monocharts for Reflex, dark](https://raw.githubusercontent.com/ecrespo/reflex-monocharts/main/monocharts_demo/assets/preview-dark.png)
15
+ ![Monocharts for Reflex, light](https://raw.githubusercontent.com/ecrespo/reflex-monocharts/main/monocharts_demo/assets/preview-light.png)
16
+
17
+ ## Why a port and not a wrapper
18
+
19
+ Monocharts ships as copy-paste React/TSX built on Recharts and Tailwind, with the
20
+ data hard-coded in each component. Reflex already wraps Recharts, so this library
21
+ rebuilds the *design system* in Python instead of shipping JavaScript:
22
+
23
+ - **No npm dependency and no Tailwind requirement.** Every class is translated to
24
+ Reflex style props, so the cards drop into any Reflex app unchanged.
25
+ - **Data-driven.** Each chart takes `data` plus `*_key` arguments and binds to
26
+ `rx.State`. Call it with no arguments and you get the original demo card.
27
+ - **Reactive theming.** `theme=` accepts `"dark"`, `"light"`, or a state Var, so a
28
+ toggle re-themes every card without a reload. `compact=` works the same way.
29
+
30
+ ## Quick start
31
+
32
+ ```python
33
+ import reflex as rx
34
+ from reflex_monocharts import monocharts as mc
35
+
36
+
37
+ class State(rx.State):
38
+ theme: str = "dark"
39
+ traffic: list[dict] = [
40
+ {"hour": "02:00", "hits": 18},
41
+ {"hour": "06:00", "hits": 34},
42
+ {"hour": "10:00", "hits": 72},
43
+ ]
44
+
45
+ @rx.event
46
+ def toggle_theme(self):
47
+ self.theme = "light" if self.theme == "dark" else "dark"
48
+
49
+
50
+ def index() -> rx.Component:
51
+ return rx.vstack(
52
+ rx.button("Toggle theme", on_click=State.toggle_theme),
53
+ mc.area(
54
+ State.traffic,
55
+ x_key="hour",
56
+ value_key="hits",
57
+ theme=State.theme,
58
+ title="Traffic",
59
+ badge="Live",
60
+ unit="requests",
61
+ ),
62
+ mc.gauge(84, theme=State.theme),
63
+ width="420px",
64
+ )
65
+ ```
66
+
67
+ Long names are available too — `mc.area` is `mono_rounded_area_chart`.
68
+
69
+ ## The catalog
70
+
71
+ | Short name | Function | What it draws |
72
+ | --- | --- | --- |
73
+ | `mc.line` | `mono_rounded_line_chart` | Spline with a dashed baseline series |
74
+ | `mc.step` | `mono_rounded_step_chart` | Discrete staircase |
75
+ | `mc.sparkline` | `mono_rounded_sparkline_chart` | Stacked telemetry rows with micro splines |
76
+ | `mc.kpi` | `mono_rounded_kpi_card_chart` | Big KPI over a gradient sparkline |
77
+ | `mc.bar` | `mono_rounded_bar_chart` | Pill bars, as columns or rows |
78
+ | `mc.stacked_bar` | `mono_rounded_stacked_bar_chart` | Tonal stack with rounded ends |
79
+ | `mc.composed` | `mono_rounded_composed_chart` | Outlined columns plus a spline |
80
+ | `mc.waterfall` | `mono_rounded_waterfall_chart` | Floating delta pillars |
81
+ | `mc.funnel` | `mono_rounded_funnel_chart` | Horizontal pipeline stages |
82
+ | `mc.bullet` | `mono_rounded_bullet_chart` | Progress bars with benchmark markers |
83
+ | `mc.pyramid` | `mono_rounded_pyramid_chart` | Hierarchy tiers |
84
+ | `mc.candlestick` | `mono_rounded_candlestick_chart` | OHLC candles with rounded wicks |
85
+ | `mc.area` | `mono_rounded_area_chart` | Curved area with a soft gradient |
86
+ | `mc.range` | `mono_rounded_range_chart` | Floating min-max band |
87
+ | `mc.stream` | `mono_rounded_stream_chart` | Two natural-spline waves |
88
+ | `mc.donut` | `mono_rounded_donut_chart` | Donut with rounded caps and a centre readout |
89
+ | `mc.radar` | `mono_rounded_radar_chart` | Multi-axis polygon web |
90
+ | `mc.polar` | `mono_rounded_polar_chart` | 360-degree radial pillars |
91
+ | `mc.radial_group` | `mono_rounded_radial_bar_group` | Half-circle arc group |
92
+ | `mc.radial_gauge` | `mono_rounded_radial_gauge_chart` | Concentric progress rings |
93
+ | `mc.gauge` | `mono_rounded_gauge_arc` | 240-degree speedometer dial |
94
+ | `mc.meter` | `mono_rounded_meter_chart` | Semicircle meter |
95
+ | `mc.scatter` | `mono_rounded_scatter_chart` | Weighted node matrix |
96
+ | `mc.bubble` | `mono_rounded_bubble_chart` | Outlined bubbles, area-encoded |
97
+ | `mc.heatmap` | `mono_rounded_heatmap_chart` | Labelled density matrix |
98
+ | `mc.treemap` | `mono_rounded_treemap_chart` | Rounded partition tiles |
99
+ | `mc.sankey` | `mono_rounded_sankey_chart` | Curved flow bands |
100
+ | `mc.activity` | `mono_activity_heatmap` | Contribution grid (green/blue/purple/mono) |
101
+
102
+ ## Common arguments
103
+
104
+ Every chart accepts these, on top of its own `*_key` arguments:
105
+
106
+ | Argument | Meaning |
107
+ | --- | --- |
108
+ | `data` | Rows to plot. Omit for the built-in demo dataset. |
109
+ | `theme` | `"dark"`, `"light"`, or a state Var. |
110
+ | `compact` | Short card instead of tall. Accepts a Var. |
111
+ | `title` / `badge` | The uppercase eyebrow and the pill beside it. |
112
+ | `value` / `unit` | The headline metric and its muted suffix. Derived from the data when omitted. |
113
+ | `footer_left` / `footer_right` | The two monospace footer captions. |
114
+ | `control` | A component rendered flush right in the header. |
115
+ | `**props` | Any extra style props, forwarded to the card. |
116
+
117
+ ## Interactive controls
118
+
119
+ The originals bake their toggles into the component. Here the option is a prop,
120
+ so it can be wired to your own state — `mono_segmented` renders the matching pill
121
+ control:
122
+
123
+ ```python
124
+ from reflex_monocharts import mono_segmented, monocharts as mc
125
+
126
+
127
+ class State(rx.State):
128
+ curve: str = "monotone"
129
+
130
+ @rx.event
131
+ def set_curve(self, value: str):
132
+ self.curve = value
133
+
134
+
135
+ mc.area(
136
+ curve=State.curve,
137
+ control=mono_segmented(
138
+ [("monotone", "Monotone"), ("natural", "Natural")],
139
+ State.curve,
140
+ State.set_curve,
141
+ theme=State.theme,
142
+ ),
143
+ )
144
+ ```
145
+
146
+ The same pattern drives `series=` on the line card, `orientation=` on the bar card
147
+ and `show_trend=` on the hybrid card.
148
+
149
+ ## Building your own cards
150
+
151
+ The chrome is exported, so a custom chart can sit in the same system:
152
+
153
+ ```python
154
+ from reflex_monocharts import mono_card, mono_header, mono_stage, mono_footer, mono_tooltip
155
+
156
+ mono_card(
157
+ mono_header("My Metric", "Custom", "1,204", "events", theme="dark"),
158
+ mono_stage(my_chart, theme="dark"),
159
+ mono_footer("Left caption", "Right caption", theme="dark"),
160
+ theme="dark",
161
+ )
162
+ ```
163
+
164
+ `ink()`, `ink_alpha()`, `pick()` and `is_dark()` from `reflex_monocharts.theme`
165
+ resolve the monochrome palette for either a plain theme string or a Var.
166
+
167
+ ## Notes and deliberate differences
168
+
169
+ - **Badge and footer rule are theme-aware here.** Upstream hard-codes
170
+ `bg-white/10 text-white` and `border-white/5`, which is invisible on the light
171
+ card; this port resolves both per theme.
172
+ - **The tooltip is `rx.recharts.graphing_tooltip`** styled to match the original's
173
+ blurred dark panel. Recharts' `content` render-prop takes a React component,
174
+ which Reflex cannot pass, so the styling is reproduced through
175
+ `content_style` / `item_style` / `label_style`.
176
+ - **Gradients are defined in a hidden sibling `<svg>`** with a process-unique id,
177
+ so several gradient-filled cards can share a page.
178
+ - **`mono_activity_heatmap` seeds its RNG** so the grid is stable across
179
+ re-renders. Pass `seed=None` to `data.activity_contributions` for the original
180
+ random behaviour, and use a native `title` tooltip per cell rather than a
181
+ server round-trip for 140 cells.
182
+ - **`mono_rounded_candlestick_chart` needs explicit `low_bound`/`high_bound`**
183
+ when `data` is a state Var, since the price scale cannot be derived at build
184
+ time. `mono_rounded_sankey_chart` computes its band geometry in Python and
185
+ takes a plain list.
186
+
187
+ ## Demo app
188
+
189
+ ```bash
190
+ cd monocharts_demo
191
+ uv run reflex run
192
+ ```
193
+
194
+ The gallery shows every chart, a live-state section wired to `rx.State`, a theme
195
+ toggle, a compact toggle and a category filter.
196
+
197
+ ## Credits
198
+
199
+ Design system by [Syed Subhan](https://github.com/Subhan-code) — see
200
+ [Monocharts](https://github.com/Subhan-code/Monocharts) and
201
+ [amicro](https://amicro.vercel.app/mono-charts). This is an independent Python
202
+ port for Reflex, not affiliated with the original project.
203
+
204
+ MIT licensed.
@@ -0,0 +1,221 @@
1
+ """Monocharts for Reflex.
2
+
3
+ A Python port of the Monocharts design system: 28 monochromatic, rounded chart
4
+ cards built on ``rx.recharts`` and Reflex layout primitives, with no npm
5
+ dependency and no Tailwind requirement.
6
+
7
+ Every chart is a plain function returning an ``rx.Component``. Called with no
8
+ arguments it renders the original demo card; pass ``data`` (and the matching
9
+ ``*_key`` arguments) to bind it to your own state.
10
+
11
+ Example:
12
+ ```python
13
+ import reflex as rx
14
+ from reflex_monocharts import monocharts
15
+
16
+ class State(rx.State):
17
+ theme: str = "dark"
18
+ traffic: list[dict] = [{"label": "Jan", "value": 24}]
19
+
20
+ def index() -> rx.Component:
21
+ return monocharts.line(
22
+ State.traffic, value_key="value", secondary_key=None, theme=State.theme
23
+ )
24
+ ```
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ from types import SimpleNamespace
30
+
31
+ from . import data
32
+ from .card import (
33
+ FONT_MONO,
34
+ FONT_SANS,
35
+ mono_card,
36
+ mono_footer,
37
+ mono_header,
38
+ mono_segmented,
39
+ mono_stage,
40
+ )
41
+ from .charts.areas import (
42
+ mono_rounded_area_chart,
43
+ mono_rounded_range_chart,
44
+ mono_rounded_stream_chart,
45
+ )
46
+ from .charts.bars import (
47
+ mono_rounded_bar_chart,
48
+ mono_rounded_composed_chart,
49
+ mono_rounded_funnel_chart,
50
+ mono_rounded_stacked_bar_chart,
51
+ mono_rounded_waterfall_chart,
52
+ )
53
+ from .charts.layout import (
54
+ mono_activity_heatmap,
55
+ mono_rounded_bullet_chart,
56
+ mono_rounded_candlestick_chart,
57
+ mono_rounded_heatmap_chart,
58
+ mono_rounded_pyramid_chart,
59
+ mono_rounded_sankey_chart,
60
+ mono_rounded_treemap_chart,
61
+ )
62
+ from .charts.lines import (
63
+ mono_rounded_kpi_card_chart,
64
+ mono_rounded_line_chart,
65
+ mono_rounded_sparkline_chart,
66
+ mono_rounded_step_chart,
67
+ )
68
+ from .charts.points import mono_rounded_bubble_chart, mono_rounded_scatter_chart
69
+ from .charts.polar import (
70
+ mono_rounded_donut_chart,
71
+ mono_rounded_gauge_arc,
72
+ mono_rounded_meter_chart,
73
+ mono_rounded_polar_chart,
74
+ mono_rounded_radar_chart,
75
+ mono_rounded_radial_bar_group,
76
+ mono_rounded_radial_gauge_chart,
77
+ )
78
+ from .theme import (
79
+ ACCENT,
80
+ CARD_DARK,
81
+ CARD_LIGHT,
82
+ INK_DARK,
83
+ INK_LIGHT,
84
+ STAGE_DARK,
85
+ STAGE_LIGHT,
86
+ ThemeLike,
87
+ ink,
88
+ ink_alpha,
89
+ is_dark,
90
+ pick,
91
+ )
92
+ from .tooltip import mono_gradient, mono_tooltip
93
+
94
+ __version__ = "0.1.1"
95
+
96
+ #: Short aliases, so a whole dashboard reads as ``monocharts.line(...)``.
97
+ monocharts = SimpleNamespace(
98
+ activity=mono_activity_heatmap,
99
+ area=mono_rounded_area_chart,
100
+ bar=mono_rounded_bar_chart,
101
+ bubble=mono_rounded_bubble_chart,
102
+ bullet=mono_rounded_bullet_chart,
103
+ candlestick=mono_rounded_candlestick_chart,
104
+ composed=mono_rounded_composed_chart,
105
+ donut=mono_rounded_donut_chart,
106
+ funnel=mono_rounded_funnel_chart,
107
+ gauge=mono_rounded_gauge_arc,
108
+ heatmap=mono_rounded_heatmap_chart,
109
+ kpi=mono_rounded_kpi_card_chart,
110
+ line=mono_rounded_line_chart,
111
+ meter=mono_rounded_meter_chart,
112
+ polar=mono_rounded_polar_chart,
113
+ pyramid=mono_rounded_pyramid_chart,
114
+ radar=mono_rounded_radar_chart,
115
+ radial_gauge=mono_rounded_radial_gauge_chart,
116
+ radial_group=mono_rounded_radial_bar_group,
117
+ range=mono_rounded_range_chart,
118
+ sankey=mono_rounded_sankey_chart,
119
+ scatter=mono_rounded_scatter_chart,
120
+ sparkline=mono_rounded_sparkline_chart,
121
+ stacked_bar=mono_rounded_stacked_bar_chart,
122
+ step=mono_rounded_step_chart,
123
+ stream=mono_rounded_stream_chart,
124
+ treemap=mono_rounded_treemap_chart,
125
+ waterfall=mono_rounded_waterfall_chart,
126
+ # chrome
127
+ card=mono_card,
128
+ header=mono_header,
129
+ stage=mono_stage,
130
+ footer=mono_footer,
131
+ segmented=mono_segmented,
132
+ tooltip=mono_tooltip,
133
+ )
134
+
135
+ #: Every chart function, in catalog order - handy for building a gallery.
136
+ ALL_CHARTS = (
137
+ mono_activity_heatmap,
138
+ mono_rounded_line_chart,
139
+ mono_rounded_bar_chart,
140
+ mono_rounded_area_chart,
141
+ mono_rounded_donut_chart,
142
+ mono_rounded_composed_chart,
143
+ mono_rounded_scatter_chart,
144
+ mono_rounded_candlestick_chart,
145
+ mono_rounded_kpi_card_chart,
146
+ mono_rounded_pyramid_chart,
147
+ mono_rounded_radial_bar_group,
148
+ mono_rounded_gauge_arc,
149
+ mono_rounded_bullet_chart,
150
+ mono_rounded_sankey_chart,
151
+ mono_rounded_step_chart,
152
+ mono_rounded_stacked_bar_chart,
153
+ mono_rounded_radar_chart,
154
+ mono_rounded_radial_gauge_chart,
155
+ mono_rounded_funnel_chart,
156
+ mono_rounded_heatmap_chart,
157
+ mono_rounded_sparkline_chart,
158
+ mono_rounded_bubble_chart,
159
+ mono_rounded_treemap_chart,
160
+ mono_rounded_stream_chart,
161
+ mono_rounded_meter_chart,
162
+ mono_rounded_waterfall_chart,
163
+ mono_rounded_polar_chart,
164
+ mono_rounded_range_chart,
165
+ )
166
+
167
+ __all__ = [
168
+ "ACCENT",
169
+ "ALL_CHARTS",
170
+ "CARD_DARK",
171
+ "CARD_LIGHT",
172
+ "FONT_MONO",
173
+ "FONT_SANS",
174
+ "INK_DARK",
175
+ "INK_LIGHT",
176
+ "STAGE_DARK",
177
+ "STAGE_LIGHT",
178
+ "ThemeLike",
179
+ "__version__",
180
+ "data",
181
+ "ink",
182
+ "ink_alpha",
183
+ "is_dark",
184
+ "mono_activity_heatmap",
185
+ "mono_card",
186
+ "mono_footer",
187
+ "mono_gradient",
188
+ "mono_header",
189
+ "mono_rounded_area_chart",
190
+ "mono_rounded_bar_chart",
191
+ "mono_rounded_bubble_chart",
192
+ "mono_rounded_bullet_chart",
193
+ "mono_rounded_candlestick_chart",
194
+ "mono_rounded_composed_chart",
195
+ "mono_rounded_donut_chart",
196
+ "mono_rounded_funnel_chart",
197
+ "mono_rounded_gauge_arc",
198
+ "mono_rounded_heatmap_chart",
199
+ "mono_rounded_kpi_card_chart",
200
+ "mono_rounded_line_chart",
201
+ "mono_rounded_meter_chart",
202
+ "mono_rounded_polar_chart",
203
+ "mono_rounded_pyramid_chart",
204
+ "mono_rounded_radar_chart",
205
+ "mono_rounded_radial_bar_group",
206
+ "mono_rounded_radial_gauge_chart",
207
+ "mono_rounded_range_chart",
208
+ "mono_rounded_sankey_chart",
209
+ "mono_rounded_scatter_chart",
210
+ "mono_rounded_sparkline_chart",
211
+ "mono_rounded_stacked_bar_chart",
212
+ "mono_rounded_step_chart",
213
+ "mono_rounded_stream_chart",
214
+ "mono_rounded_treemap_chart",
215
+ "mono_rounded_waterfall_chart",
216
+ "mono_segmented",
217
+ "mono_stage",
218
+ "mono_tooltip",
219
+ "monocharts",
220
+ "pick",
221
+ ]