shiny-charts 0.4.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 (75) hide show
  1. shiny_charts-0.4.0/.gitignore +12 -0
  2. shiny_charts-0.4.0/CHANGELOG.md +137 -0
  3. shiny_charts-0.4.0/CONTRIBUTING.md +49 -0
  4. shiny_charts-0.4.0/LICENSE +21 -0
  5. shiny_charts-0.4.0/Makefile +57 -0
  6. shiny_charts-0.4.0/PKG-INFO +572 -0
  7. shiny_charts-0.4.0/README.md +552 -0
  8. shiny_charts-0.4.0/THIRD_PARTY.md +9 -0
  9. shiny_charts-0.4.0/bench/adoption.py +155 -0
  10. shiny_charts-0.4.0/bench/capture.py +69 -0
  11. shiny_charts-0.4.0/bench/dashboard.py +198 -0
  12. shiny_charts-0.4.0/bench/profile_large.py +217 -0
  13. shiny_charts-0.4.0/bench/run.py +203 -0
  14. shiny_charts-0.4.0/bench/updates.py +223 -0
  15. shiny_charts-0.4.0/bench/write_profile_report.py +81 -0
  16. shiny_charts-0.4.0/bench/write_report.py +122 -0
  17. shiny_charts-0.4.0/docs/adoption.md +184 -0
  18. shiny_charts-0.4.0/docs/api-contract.md +295 -0
  19. shiny_charts-0.4.0/docs/incremental-updates.md +94 -0
  20. shiny_charts-0.4.0/docs/migration.md +94 -0
  21. shiny_charts-0.4.0/docs/portfolio-adoption.md +53 -0
  22. shiny_charts-0.4.0/examples/__init__.py +1 -0
  23. shiny_charts-0.4.0/examples/adoption_app.py +215 -0
  24. shiny_charts-0.4.0/examples/app.py +15 -0
  25. shiny_charts-0.4.0/examples/data.py +72 -0
  26. shiny_charts-0.4.0/examples/express_app.py +33 -0
  27. shiny_charts-0.4.0/examples/finops.py +485 -0
  28. shiny_charts-0.4.0/examples/finops_app.py +5 -0
  29. shiny_charts-0.4.0/examples/operations_app.py +345 -0
  30. shiny_charts-0.4.0/examples/operations_data.py +64 -0
  31. shiny_charts-0.4.0/examples/pilot_app.py +207 -0
  32. shiny_charts-0.4.0/examples/portfolio_app.py +351 -0
  33. shiny_charts-0.4.0/examples/www/OFL.txt +93 -0
  34. shiny_charts-0.4.0/examples/www/manrope-400.ttf +0 -0
  35. shiny_charts-0.4.0/examples/www/manrope-600.ttf +0 -0
  36. shiny_charts-0.4.0/examples/www/manrope-700.ttf +0 -0
  37. shiny_charts-0.4.0/examples/www/operations.css +15 -0
  38. shiny_charts-0.4.0/examples/www/styles.css +70 -0
  39. shiny_charts-0.4.0/frontend/build.mjs +14 -0
  40. shiny_charts-0.4.0/frontend/compile.js +507 -0
  41. shiny_charts-0.4.0/frontend/export.js +52 -0
  42. shiny_charts-0.4.0/frontend/index.js +369 -0
  43. shiny_charts-0.4.0/frontend/updates.js +49 -0
  44. shiny_charts-0.4.0/package-lock.json +536 -0
  45. shiny_charts-0.4.0/package.json +11 -0
  46. shiny_charts-0.4.0/pyproject.toml +61 -0
  47. shiny_charts-0.4.0/scripts/check_floor.py +38 -0
  48. shiny_charts-0.4.0/scripts/check_wheel.py +48 -0
  49. shiny_charts-0.4.0/scripts/portfolio_wheel_smoke.py +44 -0
  50. shiny_charts-0.4.0/scripts/wheel_smoke.py +121 -0
  51. shiny_charts-0.4.0/src/shiny_charts/__init__.py +18 -0
  52. shiny_charts-0.4.0/src/shiny_charts/_proxy.py +157 -0
  53. shiny_charts-0.4.0/src/shiny_charts/_render.py +87 -0
  54. shiny_charts-0.4.0/src/shiny_charts/_version.py +1 -0
  55. shiny_charts-0.4.0/src/shiny_charts/_wire.py +28 -0
  56. shiny_charts-0.4.0/src/shiny_charts/chart.py +659 -0
  57. shiny_charts-0.4.0/src/shiny_charts/events.py +64 -0
  58. shiny_charts-0.4.0/src/shiny_charts/py.typed +0 -0
  59. shiny_charts-0.4.0/src/shiny_charts/www/ECHARTS-LICENSE.txt +222 -0
  60. shiny_charts-0.4.0/src/shiny_charts/www/ECHARTS-NOTICE.txt +5 -0
  61. shiny_charts-0.4.0/src/shiny_charts/www/ZRENDER-LICENSE.txt +29 -0
  62. shiny_charts-0.4.0/src/shiny_charts/www/shiny-charts.css +61 -0
  63. shiny_charts-0.4.0/src/shiny_charts/www/shiny-charts.js +24 -0
  64. shiny_charts-0.4.0/src/shiny_charts/www/shiny-charts.js.LEGAL.txt +28 -0
  65. shiny_charts-0.4.0/tests/compile.test.mjs +292 -0
  66. shiny_charts-0.4.0/tests/conftest.py +192 -0
  67. shiny_charts-0.4.0/tests/fixtures/portfolio_original.py +187 -0
  68. shiny_charts-0.4.0/tests/test_adoption.py +271 -0
  69. shiny_charts-0.4.0/tests/test_browser.py +453 -0
  70. shiny_charts-0.4.0/tests/test_chart.py +360 -0
  71. shiny_charts-0.4.0/tests/test_pilot.py +303 -0
  72. shiny_charts-0.4.0/tests/test_portfolio.py +188 -0
  73. shiny_charts-0.4.0/tests/test_proxy.py +187 -0
  74. shiny_charts-0.4.0/tests/updates.test.mjs +44 -0
  75. shiny_charts-0.4.0/uv.lock +1793 -0
@@ -0,0 +1,12 @@
1
+ .venv/
2
+ .venv-*/
3
+ node_modules/
4
+ __pycache__/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ dist/
8
+ bench/results*.json
9
+ bench/report*.md
10
+ DESIGN.md
11
+ .impeccable/
12
+ PRODUCT.md
@@ -0,0 +1,137 @@
1
+ # Changelog
2
+
3
+ ## 0.4.0 — stable
4
+
5
+ - Publish the first stable release of the documented Core/Express API after external
6
+ beta re-tests. No new Python runtime dependencies.
7
+ - Add one shared-axis `Chart.line(...)` overlay on vertical category bars, with gaps,
8
+ shared formatting/palette/legend, image export and a separate data table/CSV.
9
+ Bar selections keep their keys; bar proxies retain the overlay snapshot.
10
+ - Honor directional plot-edge annotation positions against category dividers; measure
11
+ available text space, truncate long labels and omit later overlapping edge labels.
12
+ Fit between-category rule labels inside the plot, including narrow cards.
13
+ - Count visible nonzero pie slices in the accessible summary, excluding missing and
14
+ hidden groups while retaining all supplied rows in tables/CSV.
15
+
16
+
17
+ ## 0.4.0b6 — beta
18
+
19
+ - Fix truncated `100%` ticks by including stack totals and semantic percentage
20
+ endpoints when reserving numeric axis space.
21
+ - Format temporal category bar axes with short UTC dates, preserving identities.
22
+ - Keep annotation text at domain edges visible, while respecting explicit domains.
23
+ - Make explicit `number:N`/`percent:N` precision fixed (including trailing zeros);
24
+ bare formats retain compact up-to-two-digit precision. CSV keeps raw values.
25
+ - Omit missing-value pie groups from the legend.
26
+ - Add category midpoint `.rule(x_between=(...,...), label=...)` and plot-edge
27
+ `.annotate(x=..., y="top"/"bottom", text=...)` on vertical charts.
28
+ Filtered/nonadjacent divider categories are omitted; annotations remain literal.
29
+
30
+ ## 0.4.0b5 — beta
31
+
32
+ - Bound rotated tick labels using actual chart height to preserve plotting space
33
+ and move the axis title close to them. Reserve space for wide numeric ticks and
34
+ the y-axis title in narrow cards.
35
+ - Add `.legend(layout="scroll", placement="bottom")` and single-row narrow-card
36
+ toolbar icons with full accessible names.
37
+ - Add `chart.pie`, data-coordinate `.annotate`, semantic `.rule(x=...)`, and escaped
38
+ `.hover(template=..., formats=...)` for full-app migration pilots. Include synthetic
39
+ SVG/Canvas interaction, export and update regressions with no new Python dependencies.
40
+ - Scope performance claims to their measured platform/workload. Add reported Linux
41
+ import, warm-build and real-view CPU/RSS results; many-series bars and scatter have
42
+ no general construction, wire-CPU or payload advantage.
43
+
44
+
45
+ ## 0.4.0b4 — beta
46
+
47
+ - Keep compact fixed percent domains evenly spaced, including both endpoints.
48
+ - Register the modular ECharts label-layout feature. Hide zero-height and undersized
49
+ stacked segment labels using actual text/bar dimensions, leaving stack totals
50
+ and tooltip/table values available; retain overlap handling for other value labels.
51
+ - Automatically wrap a few long category names at word boundaries; explicit
52
+ rotation retains all categories. Add `.ticks(x_labels="all" | "wrap" | "auto")`.
53
+ - Add synthetic H–L browser regressions in SVG and Canvas, and an isolated import-RSS
54
+ and warm construction-CPU benchmark with documented scope and migration coverage.
55
+
56
+
57
+ ## 0.4.0b3 — beta
58
+
59
+ - Place the visible chart title above the keyboard legend and plot; preserve titles
60
+ and the current chart snapshot in SVG/PNG exports without re-rendering the chart.
61
+ - Serialize live SVG DOM safely so quoted host font families produce valid exports.
62
+ - Add `output_chart(..., empty_message="...")` for Core and
63
+ `@render_chart(empty_message="...")` for Express automatic output UI. The message
64
+ applies to None, zero-row and non-plottable results and survives recovery.
65
+ - Document the b2 title migration: omit `.labels(title=...)`, or use
66
+ `.labels(title="")`, when the host card header already supplies the visible title.
67
+
68
+ ## 0.4.0b2 — beta
69
+
70
+ - Synchronize selection, legend, view and click inputs when revision or renderer
71
+ changes; clear stale interaction inputs on None/error results. Keep same-revision
72
+ view preservation and the documented `view(..., zoom=True)` default.
73
+ - Show a no-data state for None and zero-row results, hide zero-row axes/tools,
74
+ and show chart-level recalculation feedback with recovery.
75
+ - Draw chart titles, including in SVG/PNG exports. Migration: apps with an existing
76
+ card-header title can omit `.labels(title=...)` or use `.labels(title="")` to avoid
77
+ displaying it twice. Keep normalized percentage
78
+ stacks at 0–100% in compact layouts without clipping oversubscribed data.
79
+ - Support polars DataFrames through `to_dicts()` without a runtime dependency.
80
+ - Thin dense date categories without mid-string wrapping; avoid duplicate integer
81
+ ticks on zero data. Match legend swatches to bar/scatter/line families.
82
+ - Add optional numeric domains, tick rotation, bar values and signed stack totals,
83
+ legend/stack ordering, hidden data-table columns, and twelve explicit palette slots.
84
+ Preserve the existing default six-colour hash and selection/CSV key transport.
85
+ - Add a synthetic pilot app and browser/compiler/Python regressions based on client
86
+ feedback, without including client data or machine-dependent performance claims.
87
+
88
+ ## 0.4.0b1 — beta
89
+
90
+ - Package the first public beta for pinned development and staging pilots, with
91
+ bundled browser assets and an explicit supported API contract.
92
+
93
+ - Migrate the existing Portfolio pulse app locally, retaining calculations, filters
94
+ and selective URL restoration; keep its illustrative data explicitly labeled.
95
+ - Add tooltip fields to bar and area builders.
96
+ - Honor custom host colors in tools, focus indicators and data dialogs.
97
+ - Format table cells consistently with tooltips; keep raw CSV values. Show full UTC
98
+ timestamps in data previews and tooltips.
99
+ - Add loading, recalculation and error semantics; detect scatter empty states from
100
+ complete x/y pairs.
101
+ - Define the beta contract and exercise desktop/mobile dashboard updates.
102
+
103
+ ## 0.3.0a1 — local alpha
104
+
105
+ - Add renderer-bound ChartProxy with async replacement and append, rolling row
106
+ limits, aligned interval bounds, ordered generations/sequences and browser status.
107
+ - Add service-operations adoption with queue filters, gaps/missing measurements,
108
+ compact cards, live batches, revisions, stable selected record identity and
109
+ region feedback that resets when data or scope changes.
110
+ - Add named inherited palette slots to resolve common group color collisions.
111
+ - Add horizontal bars, long-label handling, adaptive numeric gutters, Escape to
112
+ exit brushing, and automatic closing of stale table previews after data changes.
113
+ - Verify Core/Express/module proxies, session isolation, failed transport,
114
+ concurrent calls, stale/malformed messages, current exports and empty recovery.
115
+ - Add a controlled completed-render and websocket full/proxy comparison.
116
+ - Validation change: integer keys outside JavaScript's safe range are rejected;
117
+ use string identifiers to retain exact record identity.
118
+
119
+ ## 0.2.0a1 — local alpha
120
+
121
+ - Extract a native FinOps app that runs without Plotly; retain a separate styled
122
+ comparison. Support 100,000 requests and opt the dense scatter into Canvas.
123
+ - Remove redundant scatter/bar source copies and copy scalar row containers
124
+ directly when creating public/wire snapshots, preserving mutation isolation.
125
+ - Resize the renderer only when dimensions change. Disable progressive SVG
126
+ patches; keep progressive Canvas painting with individual point identity.
127
+ - Define the alpha API/event contract and public selection TypedDicts.
128
+ - Add Python/dependency-floor/browser CI, isolated wheel/native-app checks,
129
+ repeatable 10k/100k preparation/paint profiling, and migration examples.
130
+
131
+ ## 0.1.0a1 — prototype
132
+
133
+ - Five dashboard chart families, native Shiny Core/Express output binding,
134
+ host-theme integration, intervals/rules, normalized click/brush events,
135
+ preserved view state, and CSV/SVG/PNG/table access.
136
+
137
+ These alphas have not been published. Measurements and review artifacts stay local.
@@ -0,0 +1,49 @@
1
+ # Development
2
+
3
+ The project is a standalone package with a stable documented API. Node is needed to build the browser
4
+ adapter, not to use the installed Python wheel.
5
+
6
+ ```sh
7
+ make sync
8
+ make browsers
9
+ make check
10
+ make check-wheel
11
+ make check-floor
12
+ ```
13
+
14
+ `make check` runs Ruff, the frontend build, JavaScript/unit/browser tests, and
15
+ wheel/sdist builds. `make check-wheel` installs the wheel and a copied native
16
+ FinOps example in a temporary environment without either Plotly package and
17
+ runs real browser checks. `make check-floor` uses Python 3.10, Shiny 1.5.0, and
18
+ htmltools 0.6.0 in a separate `.venv-floor`.
19
+
20
+ Select another installed Playwright engine with `SHINY_CHARTS_BROWSER=firefox`
21
+ or `webkit` before `make test-browser`. Install it with
22
+ `uv run playwright install firefox webkit`. CI uses these same tests and has a
23
+ single `All checks passed` status for branch protection. Remote CI runs require
24
+ the project to be pushed; nothing in this local workflow publishes packages.
25
+
26
+ The checked-in `src/shiny_charts/www` bundle must match `npm run build`. CI checks
27
+ its diff. ECharts/zrender notices and linked legal comments travel with the wheel.
28
+ The frontend compiler owns engine-specific options; the Python API stays semantic.
29
+
30
+ Use Conventional Commits. Keep benchmark result/report files, DESIGN.md,
31
+ `.impeccable`, review captures, and generated design collateral out of commits.
32
+ Never publish, push, release, or send external messages without explicit approval.
33
+
34
+ See `docs/api-contract.md` before changing defaults or event fields. Add tests
35
+ for behavior that could regress, including empty/missing data, keys, modules,
36
+ view changes and lifecycle cleanup. Keep performance profiles separate from
37
+ functional tests; machine-dependent timings are not CI pass/fail thresholds.
38
+
39
+ `make operations` runs the second adoption app. `make profile-updates` compares
40
+ full/proxy rolling-window updates, including complete point paint and received
41
+ websocket bytes. Do not run browser tests concurrently with timing profiles.
42
+ `src/shiny_charts/_version.py` is the single version source; uv cache keys include
43
+ it so editable distribution metadata is refreshed when the version changes.
44
+
45
+ The default development environment also installs the `adoption` group for Portfolio
46
+ pulse. At the library dependency floor, those SDK-specific tests skip because its
47
+ optional SDK requires Shiny >=1.8. Run `tests/test_portfolio.py` with the default
48
+ environment. Include it in the Firefox/WebKit adoption checks. Generated benchmark
49
+ reports and design-review files remain local and must not be committed.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ruben J. Jongejan
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,57 @@
1
+ .PHONY: sync lint build-browser test test-unit test-browser browsers build check check-wheel check-floor demo native operations profile profile-updates
2
+
3
+ sync:
4
+ uv sync --locked
5
+ npm ci
6
+
7
+ lint:
8
+ uv run ruff check src examples tests bench scripts
9
+
10
+ build-browser:
11
+ npm run build
12
+
13
+ test-unit:
14
+ npm test
15
+ uv run pytest -q tests/test_chart.py
16
+
17
+ test-browser:
18
+ uv run pytest -q tests/test_browser.py
19
+
20
+ test:
21
+ npm test
22
+ uv run pytest -q
23
+
24
+ browsers:
25
+ uv run playwright install chromium $(PLAYWRIGHT_ARGS)
26
+
27
+ build:
28
+ uv build
29
+
30
+ check: lint build-browser test build
31
+
32
+ check-wheel: build
33
+ uv run python scripts/check_wheel.py
34
+
35
+ check-floor:
36
+ uv run python scripts/check_floor.py --python 3.10
37
+
38
+ demo:
39
+ uv run uvicorn examples.app:app --host 127.0.0.1 --port 8055
40
+
41
+ native:
42
+ uv run uvicorn examples.finops_app:app --host 127.0.0.1 --port 8056
43
+
44
+ profile:
45
+ uv run python bench/profile_large.py
46
+
47
+ operations:
48
+ uv run uvicorn examples.operations_app:app --host 127.0.0.1 --port 8057
49
+
50
+ profile-updates:
51
+ uv run python bench/updates.py
52
+
53
+ portfolio:
54
+ uv run uvicorn examples.portfolio_app:app --host 127.0.0.1 --port 8058
55
+
56
+ profile-dashboard:
57
+ uv run python bench/dashboard.py