reflex-rosencharts 0.1.0__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 (120) hide show
  1. reflex_rosencharts-0.1.0/.gitignore +19 -0
  2. reflex_rosencharts-0.1.0/CONTRIBUTING.md +84 -0
  3. reflex_rosencharts-0.1.0/LICENSE +22 -0
  4. reflex_rosencharts-0.1.0/NOTICE +9 -0
  5. reflex_rosencharts-0.1.0/PKG-INFO +100 -0
  6. reflex_rosencharts-0.1.0/README.md +73 -0
  7. reflex_rosencharts-0.1.0/pyproject.toml +57 -0
  8. reflex_rosencharts-0.1.0/reference/rosencharts/README.md +31 -0
  9. reflex_rosencharts-0.1.0/reflex_rosencharts/__init__.py +30 -0
  10. reflex_rosencharts-0.1.0/reflex_rosencharts/components/__init__.py +5 -0
  11. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/__init__.py +13 -0
  12. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart.py +110 -0
  13. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart.tsx +242 -0
  14. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart_full.py +106 -0
  15. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart_full.tsx +213 -0
  16. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart_gradient.py +112 -0
  17. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart_gradient.tsx +222 -0
  18. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart_semi_filled.py +113 -0
  19. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/area_chart_semi_filled.tsx +224 -0
  20. reflex_rosencharts-0.1.0/reflex_rosencharts/components/area/gallery.py +63 -0
  21. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/__init__.py +29 -0
  22. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_benchmark.py +65 -0
  23. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_benchmark.tsx +75 -0
  24. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_breakdown.py +81 -0
  25. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_breakdown.tsx +129 -0
  26. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_flags_horizontal.py +64 -0
  27. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_flags_horizontal.tsx +146 -0
  28. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_gradient.py +70 -0
  29. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_gradient.tsx +141 -0
  30. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_horizontal.py +69 -0
  31. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_horizontal.tsx +146 -0
  32. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_horizontal_logo.py +70 -0
  33. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_horizontal_logo.tsx +252 -0
  34. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_line.py +73 -0
  35. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_line.tsx +227 -0
  36. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_multi_vertical.py +80 -0
  37. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_multi_vertical.tsx +189 -0
  38. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_thin_breakdown.py +81 -0
  39. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_thin_breakdown.tsx +109 -0
  40. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_thin_horizontal.py +79 -0
  41. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_thin_horizontal.tsx +201 -0
  42. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_triple_flags_horizontal.py +70 -0
  43. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_triple_flags_horizontal.tsx +181 -0
  44. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_vertical.py +71 -0
  45. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/bar_chart_vertical.tsx +160 -0
  46. reflex_rosencharts-0.1.0/reflex_rosencharts/components/bar/gallery.py +168 -0
  47. reflex_rosencharts-0.1.0/reflex_rosencharts/components/helpers/ClientTooltip.tsx +167 -0
  48. reflex_rosencharts-0.1.0/reflex_rosencharts/components/helpers/__init__.py +1 -0
  49. reflex_rosencharts-0.1.0/reflex_rosencharts/components/helpers/client_tooltip.py +17 -0
  50. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/__init__.py +21 -0
  51. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/gallery.py +113 -0
  52. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart.py +78 -0
  53. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart.tsx +226 -0
  54. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_curved.py +74 -0
  55. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_curved.tsx +226 -0
  56. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_full.py +81 -0
  57. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_full.tsx +155 -0
  58. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_labels_curved.py +71 -0
  59. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_labels_curved.tsx +162 -0
  60. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_multiple.py +91 -0
  61. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_multiple.tsx +268 -0
  62. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_pulse.py +71 -0
  63. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_pulse.tsx +231 -0
  64. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_step.py +70 -0
  65. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_step.tsx +220 -0
  66. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_stocks_curved.py +72 -0
  67. reflex_rosencharts-0.1.0/reflex_rosencharts/components/line/line_chart_stocks_curved.tsx +291 -0
  68. reflex_rosencharts-0.1.0/reflex_rosencharts/components/other/__init__.py +6 -0
  69. reflex_rosencharts-0.1.0/reflex_rosencharts/components/other/bubble_chart.py +93 -0
  70. reflex_rosencharts-0.1.0/reflex_rosencharts/components/other/bubble_chart.tsx +125 -0
  71. reflex_rosencharts-0.1.0/reflex_rosencharts/components/other/funnel_chart.py +81 -0
  72. reflex_rosencharts-0.1.0/reflex_rosencharts/components/other/funnel_chart.tsx +108 -0
  73. reflex_rosencharts-0.1.0/reflex_rosencharts/components/other/gallery.py +33 -0
  74. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/__init__.py +21 -0
  75. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart.py +70 -0
  76. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart.tsx +122 -0
  77. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_center_text.py +77 -0
  78. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_center_text.tsx +135 -0
  79. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_fillable.py +43 -0
  80. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_fillable.tsx +83 -0
  81. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_fillable_half.py +43 -0
  82. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_fillable_half.tsx +95 -0
  83. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_half.py +67 -0
  84. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/donut_chart_half.tsx +115 -0
  85. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/gallery.py +121 -0
  86. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/pie_chart.py +77 -0
  87. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/pie_chart.tsx +88 -0
  88. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/pie_chart_labels.py +76 -0
  89. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/pie_chart_labels.tsx +135 -0
  90. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/pie_chart_stocks.py +101 -0
  91. reflex_rosencharts-0.1.0/reflex_rosencharts/components/pie/pie_chart_stocks.tsx +166 -0
  92. reflex_rosencharts-0.1.0/reflex_rosencharts/components/radar/__init__.py +6 -0
  93. reflex_rosencharts-0.1.0/reflex_rosencharts/components/radar/gallery.py +32 -0
  94. reflex_rosencharts-0.1.0/reflex_rosencharts/components/radar/radar_chart.py +65 -0
  95. reflex_rosencharts-0.1.0/reflex_rosencharts/components/radar/radar_chart.tsx +91 -0
  96. reflex_rosencharts-0.1.0/reflex_rosencharts/components/radar/radar_chart_rounded.py +66 -0
  97. reflex_rosencharts-0.1.0/reflex_rosencharts/components/radar/radar_chart_rounded.tsx +116 -0
  98. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/__init__.py +13 -0
  99. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/gallery.py +61 -0
  100. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart.py +84 -0
  101. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart.tsx +227 -0
  102. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart_interactive.py +87 -0
  103. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart_interactive.tsx +208 -0
  104. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart_multiclass.py +89 -0
  105. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart_multiclass.tsx +206 -0
  106. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart_stocks.py +73 -0
  107. reflex_rosencharts-0.1.0/reflex_rosencharts/components/scatter/scatter_chart_stocks.tsx +295 -0
  108. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/__init__.py +7 -0
  109. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/gallery.py +48 -0
  110. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/treemap_chart.py +80 -0
  111. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/treemap_chart.tsx +110 -0
  112. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/treemap_chart_gradient.py +108 -0
  113. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/treemap_chart_gradient.tsx +157 -0
  114. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/treemap_chart_images.py +111 -0
  115. reflex_rosencharts-0.1.0/reflex_rosencharts/components/treemap/treemap_chart_images.tsx +200 -0
  116. reflex_rosencharts-0.1.0/reflex_rosencharts/gallery/__init__.py +5 -0
  117. reflex_rosencharts-0.1.0/reflex_rosencharts/gallery/registry.py +55 -0
  118. reflex_rosencharts-0.1.0/reflex_rosencharts/py.typed +0 -0
  119. reflex_rosencharts-0.1.0/reflex_rosencharts/reflex_rosencharts.py +125 -0
  120. reflex_rosencharts-0.1.0/specs/README.md +33 -0
@@ -0,0 +1,19 @@
1
+ *.db
2
+ *.py[cod]
3
+ .web
4
+ assets/external/
5
+ .states
6
+ # Python-generated files
7
+ __pycache__/
8
+ *.py[oc]
9
+ build/
10
+ dist/
11
+ wheels/
12
+ *.egg-info
13
+
14
+ # Virtual environments
15
+ .venv
16
+
17
+ # coverage
18
+ .coverage
19
+ htmlcov/
@@ -0,0 +1,84 @@
1
+ # Contribuir — Receta de port (rosencharts → Reflex)
2
+
3
+ Patrón **probado** (validado end-to-end con el piloto `line_chart`, compila con
4
+ `reflex export`). Detalle de diseño en
5
+ [`specs/technical/architecture.md`](specs/technical/architecture.md) §5.2.
6
+
7
+ ## Layout de assets (importante)
8
+
9
+ `rx.asset("x.tsx", shared=True)` copia el archivo a
10
+ `public/external/<módulo_python_punteado_como_dirs>/x.tsx`. Es decir, el módulo
11
+ `reflex_rosencharts.components.line.line_chart` deja su TSX en
12
+ `external/reflex_rosencharts/components/line/line_chart/line_chart.tsx`.
13
+
14
+ Como **toda** gráfica vive en `components/<familia>/<name>.py` (asset = `<name>.tsx`),
15
+ su TSX queda en `.../components/<familia>/<name>/<name>.tsx`, y el helper compartido
16
+ en `.../components/helpers/client_tooltip/ClientTooltip.tsx`. Por eso la ruta relativa
17
+ al helper es **constante para todas las gráficas**:
18
+
19
+ ```tsx
20
+ import { ClientTooltip, TooltipTrigger, TooltipContent } from "../../helpers/client_tooltip/ClientTooltip";
21
+ ```
22
+
23
+ ## Pasos por gráfica (TDD)
24
+
25
+ 1. **RED** — `tests/test_<familia>.py`: la función existe, es importable, `.create(data=...)`
26
+ construye un `rx.Component`, y el default reproduce el ejemplo. Corre el test y velo fallar.
27
+ 2. **Copiar** `reference/rosencharts/<familia>-charts/<n>_<Name>.tsx`
28
+ → `reflex_rosencharts/components/<familia>/<name>.tsx`.
29
+ 3. **Parametrizar datos**: sustituir el array hardcodeado por una prop con default = ejemplo:
30
+ ```tsx
31
+ const defaultData = [ ...ejemplo original... ];
32
+ export function ChartName({ data = defaultData, color = "..." }: {...}) {
33
+ if (data.length === 0) return <div className="relative h-72 w-full" />;
34
+ // ... mapear/escalas a partir de `data`
35
+ }
36
+ ```
37
+ 4. **Ajustar import del helper** (sólo si usa tooltip) a la ruta constante de arriba.
38
+ 5. **Wrapper Python** (`<name>.py`):
39
+ ```python
40
+ from typing import TypedDict
41
+ import reflex as rx
42
+ from ..helpers.client_tooltip import client_tooltip_asset # sólo si usa tooltip
43
+
44
+ class LinePoint(TypedDict):
45
+ date: str
46
+ value: float
47
+
48
+ _DEFAULT_DATA: list[LinePoint] = [ ...ejemplo... ]
49
+
50
+ client_tooltip_asset() # sólo si usa tooltip (lo hace viajar)
51
+ _PATH = rx.asset("line_chart.tsx", shared=True)
52
+
53
+ class LineChart(rx.NoSSRComponent): # NoSSRComponent si usa portal/tooltip; rx.Component si no
54
+ library = f"$/public{_PATH}"
55
+ tag = "LineChart" # == nombre exportado en el TSX
56
+ is_default = False
57
+ lib_dependencies: list[str] = ["d3"] # si el TSX importa de "d3"
58
+ data: rx.Var[list[LinePoint]] = rx.Var.create(_DEFAULT_DATA)
59
+ color: rx.Var[str] = rx.Var.create("stroke-fuchsia-400")
60
+
61
+ def line_chart(**props) -> rx.Component:
62
+ return LineChart.create(**props)
63
+ ```
64
+ 6. **Re-exportar** en `components/<familia>/__init__.py` y en `reflex_rosencharts/__init__.py`.
65
+ 7. **Entrada de galería** en `components/<familia>/gallery.py` (lista `GALLERY_ENTRIES`); el
66
+ registry central la recoge sin tocar archivos compartidos.
67
+ 8. **GREEN** — corre el test y velo pasar. Refactor manteniendo verde. Commit.
68
+
69
+ ## Reglas
70
+
71
+ - Nombre Python en `snake_case`; quitar sufijo `_DIV` (técnica de render, va en el docstring).
72
+ - `tag` debe coincidir EXACTAMENTE con el nombre `export function <Tag>` del TSX.
73
+ - `data` vacío ⇒ render de contenedor vacío, nunca lanzar excepción.
74
+ - Conservar variantes `dark:` de Tailwind.
75
+ - Cada variante con campos extra define su propio `TypedDict` (ver Data Model §4).
76
+ - Gráficas SIN tooltip: usar `rx.Component` (no NoSSR) y omitir `client_tooltip_asset()`.
77
+
78
+ ## Definición de Done (por gráfica)
79
+
80
+ - [ ] Test TDD verde (import + render + default)
81
+ - [ ] Wrapper + TSX parametrizado + re-export en ambos `__init__`
82
+ - [ ] Entrada en `components/<familia>/gallery.py`
83
+ - [ ] Compila en `reflex export`
84
+ - [ ] Docstring con esquema de datos y snippet
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Filipe Sommer (original rosencharts)
4
+ Copyright (c) 2026 Ernesto Crespo (reflex-rosencharts port)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,9 @@
1
+ reflex-rosencharts
2
+ ==================
3
+
4
+ Este proyecto es un port a Reflex de "rosencharts":
5
+ https://github.com/Filsommer/rosenCharts
6
+ Copyright (c) Filsommer — Licencia MIT
7
+
8
+ El código original (TSX) se conserva como referencia en reference/rosencharts/
9
+ bajo su licencia MIT original. Las adaptaciones a Reflex se distribuyen bajo MIT.
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: reflex-rosencharts
3
+ Version: 0.1.0
4
+ Summary: rosencharts charts (D3 + Tailwind) ported to Reflex as Python components — 43 charts, no JS required.
5
+ Project-URL: Homepage, https://github.com/ecrespo/reflex-rosencharts
6
+ Project-URL: Source, https://github.com/ecrespo/reflex-rosencharts
7
+ Project-URL: Issues, https://github.com/ecrespo/reflex-rosencharts/issues
8
+ Author-email: Ernesto Crespo <ecrespo@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ License-File: NOTICE
12
+ Keywords: charts,components,d3,dataviz,reflex,rosencharts,tailwind,visualization
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Visualization
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: reflex>=0.9.5.post2
26
+ Description-Content-Type: text/markdown
27
+
28
+ # reflex-rosencharts
29
+
30
+ Port de la librería de gráficas [**rosencharts**](https://github.com/Filsommer/rosenCharts)
31
+ (43 componentes React/TSX con D3.js + Tailwind) a un **custom component de
32
+ [Reflex](https://reflex.dev/)**, para usar las gráficas desde Python puro.
33
+
34
+ > Estado: **43/43 gráficas implementadas** ✅ — todas con wrapper Python, TSX parametrizado,
35
+ > ejemplo en la galería y tests. La app demo (`reflex run`) muestra las 43 con su snippet de uso.
36
+ > Capturas en [`docs/screenshots/`](docs/screenshots/).
37
+
38
+ ## ¿Por qué?
39
+
40
+ rosencharts no es un paquete npm: son componentes `.tsx` para copiar y pegar, con datos
41
+ hardcodeados y estilo Tailwind. Este proyecto los envuelve como **componentes locales de Reflex**
42
+ (`rx.asset` + `library="$/public..."`), los parametriza para recibir datos desde `rx.State`, y los
43
+ expone como funciones Python:
44
+
45
+ ```python
46
+ import reflex as rx
47
+ import reflex_rosencharts as rxc
48
+
49
+ class State(rx.State):
50
+ sales: list[dict] = [{"date": "2023-05-01", "value": 6}, {"date": "2023-05-02", "value": 8}]
51
+
52
+ def index() -> rx.Component:
53
+ return rxc.line_chart(data=State.sales)
54
+ ```
55
+
56
+ ## Gráficas (43 en 8 familias)
57
+
58
+ | Familia | Nº | Ejemplos |
59
+ |---|---|---|
60
+ | Area | 4 | `area_chart`, `area_chart_gradient` |
61
+ | Bar | 12 | `bar_chart_horizontal`, `bar_chart_benchmark` |
62
+ | Line | 8 | `line_chart`, `line_chart_multiple` |
63
+ | Pie/Donut | 8 | `pie_chart`, `donut_chart_center_text` |
64
+ | Scatter | 4 | `scatter_chart`, `scatter_chart_interactive` |
65
+ | Treemap | 3 | `treemap_chart`, `treemap_chart_images` |
66
+ | Radar | 2 | `radar_chart`, `radar_chart_rounded` |
67
+ | Other | 2 | `bubble_chart`, `funnel_chart` |
68
+
69
+ Catálogo completo y props: [`specs/api/component-api-v1.md`](specs/api/component-api-v1.md).
70
+
71
+ ## Desarrollo
72
+
73
+ Gestionado con [uv](https://docs.astral.sh/uv/):
74
+
75
+ ```bash
76
+ uv sync # instalar dependencias
77
+ uv run reflex run # arrancar la demo app / galería (las 43 gráficas)
78
+ uv run pytest # tests de los wrappers (TDD)
79
+ ```
80
+
81
+ La **galería demo** vive en `reflex_rosencharts/reflex_rosencharts.py`: barra lateral por familia
82
+ y una tarjeta por gráfica (gráfica renderizada con datos de ejemplo + snippet Python). Es el banco
83
+ de pruebas visual del port.
84
+
85
+ ## Especificaciones (SDD)
86
+
87
+ El proyecto sigue **Spec-Driven Design**. Las specs son el artefacto primario:
88
+
89
+ - [PRD](specs/prd/reflex-rosencharts-prd.md) — el qué y el para quién
90
+ - [API Spec](specs/api/component-api-v1.md) — API pública Python (funciones, props)
91
+ - [Technical Design](specs/technical/architecture.md) — patrón de wrapping y arquitectura
92
+ - [Data Model](specs/data-model/chart-data-schemas.md) — esquemas de datos por gráfica
93
+ - [Implementation Plan](specs/plans/implementation-plan.md) — fases por familia
94
+
95
+ El código original (referencia, solo lectura) está en [`reference/rosencharts/`](reference/rosencharts/).
96
+
97
+ ## Licencia y atribución
98
+
99
+ MIT. Este proyecto es un port de [rosencharts](https://github.com/Filsommer/rosenCharts)
100
+ de Filsommer (MIT). Ver [`LICENSE`](LICENSE) y [`NOTICE`](NOTICE).
@@ -0,0 +1,73 @@
1
+ # reflex-rosencharts
2
+
3
+ Port de la librería de gráficas [**rosencharts**](https://github.com/Filsommer/rosenCharts)
4
+ (43 componentes React/TSX con D3.js + Tailwind) a un **custom component de
5
+ [Reflex](https://reflex.dev/)**, para usar las gráficas desde Python puro.
6
+
7
+ > Estado: **43/43 gráficas implementadas** ✅ — todas con wrapper Python, TSX parametrizado,
8
+ > ejemplo en la galería y tests. La app demo (`reflex run`) muestra las 43 con su snippet de uso.
9
+ > Capturas en [`docs/screenshots/`](docs/screenshots/).
10
+
11
+ ## ¿Por qué?
12
+
13
+ rosencharts no es un paquete npm: son componentes `.tsx` para copiar y pegar, con datos
14
+ hardcodeados y estilo Tailwind. Este proyecto los envuelve como **componentes locales de Reflex**
15
+ (`rx.asset` + `library="$/public..."`), los parametriza para recibir datos desde `rx.State`, y los
16
+ expone como funciones Python:
17
+
18
+ ```python
19
+ import reflex as rx
20
+ import reflex_rosencharts as rxc
21
+
22
+ class State(rx.State):
23
+ sales: list[dict] = [{"date": "2023-05-01", "value": 6}, {"date": "2023-05-02", "value": 8}]
24
+
25
+ def index() -> rx.Component:
26
+ return rxc.line_chart(data=State.sales)
27
+ ```
28
+
29
+ ## Gráficas (43 en 8 familias)
30
+
31
+ | Familia | Nº | Ejemplos |
32
+ |---|---|---|
33
+ | Area | 4 | `area_chart`, `area_chart_gradient` |
34
+ | Bar | 12 | `bar_chart_horizontal`, `bar_chart_benchmark` |
35
+ | Line | 8 | `line_chart`, `line_chart_multiple` |
36
+ | Pie/Donut | 8 | `pie_chart`, `donut_chart_center_text` |
37
+ | Scatter | 4 | `scatter_chart`, `scatter_chart_interactive` |
38
+ | Treemap | 3 | `treemap_chart`, `treemap_chart_images` |
39
+ | Radar | 2 | `radar_chart`, `radar_chart_rounded` |
40
+ | Other | 2 | `bubble_chart`, `funnel_chart` |
41
+
42
+ Catálogo completo y props: [`specs/api/component-api-v1.md`](specs/api/component-api-v1.md).
43
+
44
+ ## Desarrollo
45
+
46
+ Gestionado con [uv](https://docs.astral.sh/uv/):
47
+
48
+ ```bash
49
+ uv sync # instalar dependencias
50
+ uv run reflex run # arrancar la demo app / galería (las 43 gráficas)
51
+ uv run pytest # tests de los wrappers (TDD)
52
+ ```
53
+
54
+ La **galería demo** vive en `reflex_rosencharts/reflex_rosencharts.py`: barra lateral por familia
55
+ y una tarjeta por gráfica (gráfica renderizada con datos de ejemplo + snippet Python). Es el banco
56
+ de pruebas visual del port.
57
+
58
+ ## Especificaciones (SDD)
59
+
60
+ El proyecto sigue **Spec-Driven Design**. Las specs son el artefacto primario:
61
+
62
+ - [PRD](specs/prd/reflex-rosencharts-prd.md) — el qué y el para quién
63
+ - [API Spec](specs/api/component-api-v1.md) — API pública Python (funciones, props)
64
+ - [Technical Design](specs/technical/architecture.md) — patrón de wrapping y arquitectura
65
+ - [Data Model](specs/data-model/chart-data-schemas.md) — esquemas de datos por gráfica
66
+ - [Implementation Plan](specs/plans/implementation-plan.md) — fases por familia
67
+
68
+ El código original (referencia, solo lectura) está en [`reference/rosencharts/`](reference/rosencharts/).
69
+
70
+ ## Licencia y atribución
71
+
72
+ MIT. Este proyecto es un port de [rosencharts](https://github.com/Filsommer/rosenCharts)
73
+ de Filsommer (MIT). Ver [`LICENSE`](LICENSE) y [`NOTICE`](NOTICE).
@@ -0,0 +1,57 @@
1
+ [project]
2
+ name = "reflex-rosencharts"
3
+ version = "0.1.0"
4
+ description = "rosencharts charts (D3 + Tailwind) ported to Reflex as Python components — 43 charts, no JS required."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE", "NOTICE"]
8
+ requires-python = ">=3.10"
9
+ authors = [{ name = "Ernesto Crespo", email = "ecrespo@gmail.com" }]
10
+ keywords = ["reflex", "charts", "d3", "tailwind", "dataviz", "visualization", "rosencharts", "components"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Intended Audience :: Developers",
14
+ "Operating System :: OS Independent",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Topic :: Scientific/Engineering :: Visualization",
21
+ "Topic :: Software Development :: Libraries :: Python Modules",
22
+ "Typing :: Typed",
23
+ ]
24
+ dependencies = [
25
+ "reflex>=0.9.5.post2",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/ecrespo/reflex-rosencharts"
30
+ Source = "https://github.com/ecrespo/reflex-rosencharts"
31
+ Issues = "https://github.com/ecrespo/reflex-rosencharts/issues"
32
+
33
+ [dependency-groups]
34
+ dev = [
35
+ "playwright>=1.60.0",
36
+ "pytest>=9.1.0",
37
+ "pytest-cov>=7.1.0",
38
+ "twine>=5.0.0",
39
+ ]
40
+
41
+ [build-system]
42
+ requires = ["hatchling"]
43
+ build-backend = "hatchling.build"
44
+
45
+ [tool.hatch.build.targets.wheel]
46
+ # Ship the Python wrappers AND the parametrized .tsx assets they wrap.
47
+ packages = ["reflex_rosencharts"]
48
+ artifacts = ["*.tsx"]
49
+
50
+ [tool.hatch.build.targets.sdist]
51
+ include = [
52
+ "reflex_rosencharts",
53
+ "README.md",
54
+ "LICENSE",
55
+ "NOTICE",
56
+ "CONTRIBUTING.md",
57
+ ]
@@ -0,0 +1,31 @@
1
+ # Rosen - A React Charting Library
2
+
3
+ A lightweight and easy-to-use charting library built with D3.js and Tailwind. Just copy-paste the code and install the required dependencies to get started!
4
+
5
+ ## Installation
6
+
7
+ First, install D3.js by running:
8
+
9
+ ```sh
10
+ npm install d3
11
+ ```
12
+
13
+ If you're using TypeScript, install the D3 types as well:
14
+
15
+ ```sh
16
+ npm install --save-dev @types/d3
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ Simply copy and paste the provided charting code into your project and ensure that D3.js is installed.
22
+
23
+ ## Features
24
+
25
+ - Simple copy-paste integration
26
+ - Uses D3.js for powerful and flexible charting
27
+ - Works with JavaScript and TypeScript
28
+
29
+ ## License
30
+
31
+ MIT
@@ -0,0 +1,30 @@
1
+ """reflex-rosencharts: port de rosencharts a componentes de Reflex.
2
+
3
+ API pública (a poblar durante la implementación, ver specs/api/component-api-v1.md):
4
+ import reflex_rosencharts as rxc
5
+ rxc.line_chart(data=...)
6
+
7
+ Por ahora el paquete expone el scaffold y la demo app. Las funciones de gráfica
8
+ se irán re-exportando aquí a medida que se porten (fases F1-F7 del plan).
9
+ """
10
+
11
+ __version__ = "0.1.0"
12
+
13
+ # Public API — aggregated dynamically from each family package so that charts can be
14
+ # ported in parallel without ever editing this shared file. Each family's __init__
15
+ # declares __all__; we lift those names into the package namespace.
16
+ import importlib as _importlib # noqa: E402
17
+
18
+ _FAMILIES = ["line", "area", "bar", "pie", "scatter", "treemap", "radar", "other"]
19
+ __all__: list[str] = []
20
+
21
+ for _family in _FAMILIES:
22
+ try:
23
+ _mod = _importlib.import_module(f".components.{_family}", __name__)
24
+ except ModuleNotFoundError:
25
+ continue
26
+ for _name in getattr(_mod, "__all__", []):
27
+ globals()[_name] = getattr(_mod, _name)
28
+ __all__.append(_name)
29
+
30
+ del _importlib, _family, _FAMILIES
@@ -0,0 +1,5 @@
1
+ """Subpaquetes de componentes por familia de gráfica.
2
+
3
+ Cada familia (area, bar, line, pie, radar, scatter, treemap, other) contendrá
4
+ los wrappers de Reflex (rx.Component) + sus TSX parametrizados. Ver specs/.
5
+ """
@@ -0,0 +1,13 @@
1
+ """Componentes rosencharts: familia area."""
2
+
3
+ from .area_chart import area_chart
4
+ from .area_chart_full import area_chart_full
5
+ from .area_chart_gradient import area_chart_gradient
6
+ from .area_chart_semi_filled import area_chart_semi_filled
7
+
8
+ __all__ = [
9
+ "area_chart",
10
+ "area_chart_full",
11
+ "area_chart_gradient",
12
+ "area_chart_semi_filled",
13
+ ]
@@ -0,0 +1,110 @@
1
+ """area_chart — port of rosencharts area-charts/1_AreaChart.tsx to Reflex.
2
+
3
+ Render technique: D3 ``scaleTime``/``scaleLinear`` with ``d3.area`` + ``d3.line``
4
+ (curveMonotoneX), styled with Tailwind. Uses the shared ClientTooltip helper
5
+ (createPortal), so the component renders client-side only (NoSSRComponent).
6
+
7
+ Data schema (``AreaPoint``)::
8
+
9
+ {"date": "YYYY-MM-DD", "value": float}
10
+
11
+ Example::
12
+
13
+ import reflex_rosencharts as rxc
14
+ rxc.area_chart(data=State.sales, color="text-purple-200 dark:text-purple-400")
15
+ """
16
+
17
+ from typing import TypedDict
18
+
19
+ import reflex as rx
20
+
21
+ from ..helpers.client_tooltip import client_tooltip_asset
22
+
23
+
24
+ class AreaPoint(TypedDict):
25
+ """A single point of a time series."""
26
+
27
+ date: str # ISO date 'YYYY-MM-DD'
28
+ value: float
29
+
30
+
31
+ # Default dataset == the original rosencharts example, so ``area_chart()`` with no
32
+ # args reproduces the reference chart (Tech Design DD-002).
33
+ _DEFAULT_DATA: list[AreaPoint] = [
34
+ {"date": "2023-04-30", "value": 4},
35
+ {"date": "2023-05-01", "value": 6},
36
+ {"date": "2023-05-02", "value": 8},
37
+ {"date": "2023-05-03", "value": 7},
38
+ {"date": "2023-05-04", "value": 10},
39
+ {"date": "2023-05-05", "value": 12},
40
+ {"date": "2023-05-06", "value": 10.5},
41
+ {"date": "2023-05-07", "value": 6},
42
+ {"date": "2023-05-08", "value": 8},
43
+ {"date": "2023-05-09", "value": 7.5},
44
+ {"date": "2023-05-10", "value": 6},
45
+ {"date": "2023-05-11", "value": 8},
46
+ {"date": "2023-05-12", "value": 9},
47
+ {"date": "2023-05-13", "value": 10},
48
+ {"date": "2023-05-14", "value": 17},
49
+ {"date": "2023-05-15", "value": 14},
50
+ {"date": "2023-05-16", "value": 15},
51
+ {"date": "2023-05-17", "value": 20},
52
+ {"date": "2023-05-18", "value": 18},
53
+ {"date": "2023-05-19", "value": 16},
54
+ {"date": "2023-05-20", "value": 15},
55
+ {"date": "2023-05-21", "value": 16},
56
+ {"date": "2023-05-22", "value": 13},
57
+ {"date": "2023-05-23", "value": 11},
58
+ {"date": "2023-05-24", "value": 11},
59
+ {"date": "2023-05-25", "value": 13},
60
+ {"date": "2023-05-26", "value": 12},
61
+ {"date": "2023-05-27", "value": 9},
62
+ {"date": "2023-05-28", "value": 8},
63
+ {"date": "2023-05-29", "value": 10},
64
+ {"date": "2023-05-30", "value": 11},
65
+ {"date": "2023-05-31", "value": 8},
66
+ {"date": "2023-06-01", "value": 9},
67
+ {"date": "2023-06-02", "value": 10},
68
+ {"date": "2023-06-03", "value": 12},
69
+ {"date": "2023-06-04", "value": 13},
70
+ {"date": "2023-06-05", "value": 15},
71
+ {"date": "2023-06-06", "value": 13.5},
72
+ {"date": "2023-06-07", "value": 13},
73
+ {"date": "2023-06-08", "value": 13},
74
+ {"date": "2023-06-09", "value": 14},
75
+ {"date": "2023-06-10", "value": 13},
76
+ {"date": "2023-06-11", "value": 12.5},
77
+ ]
78
+
79
+ # Ship the shared helper next to this chart so the TSX's relative import resolves.
80
+ client_tooltip_asset()
81
+ _PATH = rx.asset("area_chart.tsx", shared=True)
82
+
83
+
84
+ class AreaChart(rx.NoSSRComponent):
85
+ """Reflex wrapper around the parametrized AreaChart TSX."""
86
+
87
+ library = f"$/public{_PATH}"
88
+ tag = "AreaChart"
89
+ is_default = False
90
+
91
+ lib_dependencies: list[str] = ["d3"]
92
+
93
+ # Props
94
+ data: rx.Var[list[AreaPoint]] = rx.Var.create(_DEFAULT_DATA)
95
+ color: rx.Var[str] = rx.Var.create("text-purple-200 dark:text-purple-400")
96
+
97
+
98
+ def area_chart(**props) -> rx.Component:
99
+ """Filled area chart over a time series, with a per-point tooltip.
100
+
101
+ Args:
102
+ data: list of ``{"date": "YYYY-MM-DD", "value": float}``. Defaults to the
103
+ original rosencharts example.
104
+ color: Tailwind ``text-*`` class for the filled area. Defaults to
105
+ ``"text-purple-200 dark:text-purple-400"``.
106
+
107
+ Returns:
108
+ A Reflex component rendering the area chart.
109
+ """
110
+ return AreaChart.create(**props)