anytimeline 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 (63) hide show
  1. anytimeline-0.1.0/.gitignore +29 -0
  2. anytimeline-0.1.0/CHANGELOG.md +34 -0
  3. anytimeline-0.1.0/LICENSE +21 -0
  4. anytimeline-0.1.0/PKG-INFO +144 -0
  5. anytimeline-0.1.0/README.md +110 -0
  6. anytimeline-0.1.0/js/package-lock.json +2053 -0
  7. anytimeline-0.1.0/js/package.json +23 -0
  8. anytimeline-0.1.0/js/playwright.config.ts +42 -0
  9. anytimeline-0.1.0/js/src/core/bars.ts +402 -0
  10. anytimeline-0.1.0/js/src/core/camera.ts +93 -0
  11. anytimeline-0.1.0/js/src/core/dodge.ts +55 -0
  12. anytimeline-0.1.0/js/src/core/help.ts +117 -0
  13. anytimeline-0.1.0/js/src/core/icons.ts +36 -0
  14. anytimeline-0.1.0/js/src/core/legend.ts +143 -0
  15. anytimeline-0.1.0/js/src/core/link.ts +96 -0
  16. anytimeline-0.1.0/js/src/core/renderers/canvas2d.ts +182 -0
  17. anytimeline-0.1.0/js/src/core/renderers/renderer.ts +134 -0
  18. anytimeline-0.1.0/js/src/core/renderers/select.ts +39 -0
  19. anytimeline-0.1.0/js/src/core/renderers/symbols.ts +112 -0
  20. anytimeline-0.1.0/js/src/core/renderers/webgl2.ts +470 -0
  21. anytimeline-0.1.0/js/src/core/renderers/webgpu.ts +477 -0
  22. anytimeline-0.1.0/js/src/core/scene.ts +154 -0
  23. anytimeline-0.1.0/js/src/core/snapshot.ts +107 -0
  24. anytimeline-0.1.0/js/src/core/time.ts +422 -0
  25. anytimeline-0.1.0/js/src/core/toolbar.ts +205 -0
  26. anytimeline-0.1.0/js/src/core/transport.ts +193 -0
  27. anytimeline-0.1.0/js/src/core/types.ts +169 -0
  28. anytimeline-0.1.0/js/src/core/values.ts +294 -0
  29. anytimeline-0.1.0/js/src/core/view.ts +2478 -0
  30. anytimeline-0.1.0/js/src/standalone.ts +111 -0
  31. anytimeline-0.1.0/js/src/widget.css +390 -0
  32. anytimeline-0.1.0/js/src/widget.ts +222 -0
  33. anytimeline-0.1.0/js/test/core.test.ts +180 -0
  34. anytimeline-0.1.0/js/tsconfig.json +17 -0
  35. anytimeline-0.1.0/js/vitest.config.ts +4 -0
  36. anytimeline-0.1.0/pyproject.toml +126 -0
  37. anytimeline-0.1.0/src/anytimeline/__init__.py +12 -0
  38. anytimeline-0.1.0/src/anytimeline/codec.py +98 -0
  39. anytimeline-0.1.0/src/anytimeline/data.py +120 -0
  40. anytimeline-0.1.0/src/anytimeline/events.py +336 -0
  41. anytimeline-0.1.0/src/anytimeline/grouping.py +258 -0
  42. anytimeline-0.1.0/src/anytimeline/intervals.py +427 -0
  43. anytimeline-0.1.0/src/anytimeline/lanes.py +67 -0
  44. anytimeline-0.1.0/src/anytimeline/otel.py +200 -0
  45. anytimeline-0.1.0/src/anytimeline/presets.py +79 -0
  46. anytimeline-0.1.0/src/anytimeline/states.py +169 -0
  47. anytimeline-0.1.0/src/anytimeline/static/standalone.js +407 -0
  48. anytimeline-0.1.0/src/anytimeline/static/widget.css +1 -0
  49. anytimeline-0.1.0/src/anytimeline/static/widget.js +407 -0
  50. anytimeline-0.1.0/src/anytimeline/styling.py +306 -0
  51. anytimeline-0.1.0/src/anytimeline/synthetic.py +397 -0
  52. anytimeline-0.1.0/src/anytimeline/timebase.py +243 -0
  53. anytimeline-0.1.0/src/anytimeline/tree.py +171 -0
  54. anytimeline-0.1.0/src/anytimeline/values.py +240 -0
  55. anytimeline-0.1.0/src/anytimeline/widget.py +1249 -0
  56. anytimeline-0.1.0/tests/test_events.py +164 -0
  57. anytimeline-0.1.0/tests/test_groups.py +118 -0
  58. anytimeline-0.1.0/tests/test_intervals.py +144 -0
  59. anytimeline-0.1.0/tests/test_linked.py +45 -0
  60. anytimeline-0.1.0/tests/test_spans.py +258 -0
  61. anytimeline-0.1.0/tests/test_states_values.py +136 -0
  62. anytimeline-0.1.0/tests/test_timebase.py +90 -0
  63. anytimeline-0.1.0/tests/test_widget.py +167 -0
@@ -0,0 +1,29 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .venv-*/
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ node_modules/
11
+ .DS_Store
12
+ .ipynb_checkpoints/
13
+ __marimo__/
14
+
15
+ # built JavaScript bundle (npm run build in js/)
16
+ src/anytimeline/static/
17
+
18
+ # visual tests (Playwright)
19
+ js/test/visual/dist/
20
+ js/test/visual/scenes/
21
+ js/test-results/
22
+ js/playwright-report/
23
+
24
+ # personal experiments (notebooks, scripts); not part of the project
25
+ _scratch/
26
+
27
+ # user documentation: the built site, and the plot bundle copied in by scripts/build_docs.py
28
+ site/
29
+ docs/user/assets/anytimeline/
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to anytimeline. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.1.0] - 2026-10-11
8
+
9
+ The first release: interactive timeline charts for Jupyter, VS Code and marimo notebooks,
10
+ drawn with WebGPU, WebGL2 or Canvas 2D.
11
+
12
+ ### Added
13
+
14
+ - **Event charts** (`Timeline.events`): a mark per event on lanes, coloured, shaped and sized
15
+ by columns; overlapping events spread out; routes join the events of a group; labels and
16
+ tooltips. Time can be datetimes in any time zone and century, durations from nanoseconds,
17
+ or plain numbers; the **Order** scale spaces events by the order they happened in.
18
+ - **Intervals and Gantt charts** (`Timeline.intervals`, `gantt`): bars from a start to an end,
19
+ packed per lane, with milestones, open bars, progress, dependency arrows and markers.
20
+ - **Traces** (`Timeline.spans`, `anytimeline.otel.read_otlp`): spans as a waterfall that folds,
21
+ with each span's duration and the critical path; OpenTelemetry OTLP/JSON reader.
22
+ - **States and values** (`Timeline.states`, `Timeline.values`): what state a lane was in, and
23
+ a number over time as a line, area or steps behind the events.
24
+ - **Groups** (`group=` on every layer): hosts, days or runs as groups of lanes in one plot;
25
+ `Timeline(align="start")` compares groups from their start.
26
+ - **Linked plots** (`Timeline.link`): separate plots that zoom and pan together.
27
+ - **Sharing**: `save_html` (one file that works without Python), Save as PNG in the toolbar
28
+ and `Timeline.save_png`.
29
+ - Toolbar with Pan, Zoom and Select tools, Time / Order, Back and Home, legend, text size and
30
+ full screen; selections come back to Python as rows of your tables; light and dark themes
31
+ that follow the notebook.
32
+ - Synthetic example data (`anytimeline.synthetic`) and documentation with live examples.
33
+
34
+ [0.1.0]: https://github.com/mluttikh/anytimeline/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mluttikh
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,144 @@
1
+ Metadata-Version: 2.4
2
+ Name: anytimeline
3
+ Version: 0.1.0
4
+ Summary: GPU-accelerated timeline and event charts for notebooks
5
+ Project-URL: Homepage, https://github.com/mluttikh/anytimeline
6
+ Project-URL: Documentation, https://mluttikh.github.io/anytimeline/
7
+ Project-URL: Repository, https://github.com/mluttikh/anytimeline
8
+ Project-URL: Issues, https://github.com/mluttikh/anytimeline/issues
9
+ Project-URL: Changelog, https://github.com/mluttikh/anytimeline/blob/main/CHANGELOG.md
10
+ Author-email: mluttikh <mluttikhof@gmail.com>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: anywidget,event chart,gantt,jupyter,marimo,opentelemetry,timeline,traces,visualization,webgpu
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Framework :: Jupyter
16
+ Classifier: Framework :: Jupyter :: JupyterLab
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Topic :: Scientific/Engineering :: Visualization
26
+ Classifier: Topic :: System :: Monitoring
27
+ Requires-Python: >=3.12
28
+ Requires-Dist: anywidget>=0.9.13
29
+ Requires-Dist: ipywidgets>=8
30
+ Requires-Dist: narwhals>=1.30
31
+ Requires-Dist: numpy>=1.24
32
+ Requires-Dist: traitlets>=5.9
33
+ Description-Content-Type: text/markdown
34
+
35
+ # anytimeline
36
+
37
+ Interactive timeline and event charts for Jupyter and marimo notebooks, drawn on the GPU
38
+ (WebGPU, WebGL2, or Canvas 2D on machines without a usable GPU).
39
+
40
+ ```bash
41
+ pip install anytimeline
42
+ ```
43
+
44
+ Documentation: <https://mluttikh.github.io/anytimeline/> · Changelog:
45
+ [CHANGELOG.md](CHANGELOG.md) · Licence: MIT.
46
+
47
+ Status: version 0.1. It draws **event charts**: one mark per event at the moment it
48
+ happened, on lanes, so the order of what happened is easy to see. Time can be datetimes (any
49
+ time zone, any century), durations from nanoseconds up, or plain numbers; a Time | Order switch
50
+ spaces events by rank instead of time. Up to about a million events. It also draws **Gantt
51
+ charts** and schedules: bars from a start to an end, with dependencies, progress and
52
+ milestones, and overlapping bars stacked per lane; and **traces**: spans under spans.
53
+
54
+ ```python
55
+ from anytimeline import Timeline
56
+ from anytimeline.synthetic import service_log
57
+
58
+ log = service_log() # a dict of columns; any Polars, pandas or PyArrow table works too
59
+ tl = Timeline()
60
+ tl.events(
61
+ log,
62
+ time="time",
63
+ lane="service",
64
+ color="level",
65
+ symbol="event",
66
+ route="request",
67
+ order="seq",
68
+ tooltip=["request", "user", "bytes"],
69
+ )
70
+ tl # click it, then scroll to zoom time; drag to pan; the toolbar has Zoom and Select
71
+ ```
72
+
73
+ A Gantt chart from a table with a row per task:
74
+
75
+ ```python
76
+ from anytimeline import gantt
77
+
78
+ gantt(plan, task="task", start="start", end="end", depends="after", progress="done",
79
+ color="phase", today="2026-10-12")
80
+ ```
81
+
82
+ Bars on other lanes (machines, people, services) come from `Timeline.intervals(...)`, and mix
83
+ with events on the same lanes.
84
+
85
+ Traces (OpenTelemetry, or any table of spans with a parent) plot as a waterfall that folds,
86
+ with each span's duration and the critical path:
87
+
88
+ ```python
89
+ from anytimeline import Timeline
90
+ from anytimeline.otel import read_otlp
91
+
92
+ tr = read_otlp("traces.jsonl") # or anytimeline.synthetic.traces()
93
+ Timeline().spans(tr.spans, color="service").events(tr.events, time="time", lane="span_id")
94
+ ```
95
+
96
+ The toolbar has three tools: **Pan** (drag moves through time and lanes), **Zoom** (drag a
97
+ time range to show it) and **Select** (drag a box, or click an event; the selection is rows of
98
+ your table in `tl.selection`). Time and Order switch the scale; Aa sets the text size (also `Timeline(font_size=14)`).
99
+ Press `?` in the plot for every mouse gesture and key; `f` or
100
+ the button shows it full screen, where lanes fill the screen and overlapping events spread
101
+ out.
102
+
103
+ States (`Timeline.states`: up, degraded, down per lane) and values (`Timeline.values`: a
104
+ number over time, as a line, area or steps) go on the same lanes, behind the events.
105
+
106
+ `group="host"` on a layer puts each host's lanes under a header of their own, in one plot
107
+ (`Timeline(align="start")` compares groups from their start); separate plots link with
108
+ `a.link(b)` and zoom and pan together.
109
+
110
+ `plot.save_html("plot.html")` writes the plot to one file that opens in any browser, still
111
+ interactive; the toolbar saves it as a PNG, and so does `plot.save_png("plot.png")`.
112
+
113
+ Documentation online: <https://mluttikh.github.io/anytimeline/>; or build it with
114
+ `uv run python scripts/build_docs.py` and open `site/index.html`. Example notebook: [`examples/event_charts.ipynb`](examples/event_charts.ipynb). How the code
115
+ is built: [`docs/architecture.md`](docs/architecture.md).
116
+
117
+ ## Development
118
+
119
+ Needs Python (via [uv](https://docs.astral.sh/uv/)) and Node.js 20+ for the JavaScript bundle.
120
+
121
+ ```bash
122
+ (cd js && npm ci && npm run build) # build src/anytimeline/static/widget.js
123
+ uv sync # create .venv with dev tools
124
+ uv run pytest # Python tests
125
+ (cd js && npm run typecheck && npm test)
126
+ uv run ruff check . && uv run ruff format --check . && uv run ty check
127
+ uv run python scripts/make_scenes.py # scenes for the visual tests
128
+ (cd js && npx playwright install chromium && npm run test:visual) # every scene × backend, marimo
129
+ uv run nbstripout --install # once per clone: commit notebooks without outputs
130
+ uv run python scripts/build_docs.py # user documentation into site/ (examples run; warnings fail)
131
+ uv run python scripts/build_docs.py serve # preview it at http://localhost:8000
132
+ ```
133
+
134
+ The user documentation is in `docs/user/`, built with [Zensical](https://zensical.org) and
135
+ organised as tutorials, how-to guides, reference and explanation. Its examples are
136
+ ```` ```python exec="on" ```` blocks that run while building, and its plots are live: each
137
+ example prints `plot._embed_html()`, which `standalone.js` draws in the page. The API
138
+ reference comes from the docstrings (Google style). The browser tests check the built site
139
+ too (`docs.spec.ts`, skipped until it is built).
140
+
141
+ Visual tests draw the scenes in `js/test/visual/scenes/` with each backend and compare them
142
+ with stored screenshots (macOS); `npm run test:visual:update` stores new ones after an
143
+ intended change. `PERF=1 npx playwright test perf` measures a million events (after
144
+ `uv run python scripts/make_scenes.py --million`).
@@ -0,0 +1,110 @@
1
+ # anytimeline
2
+
3
+ Interactive timeline and event charts for Jupyter and marimo notebooks, drawn on the GPU
4
+ (WebGPU, WebGL2, or Canvas 2D on machines without a usable GPU).
5
+
6
+ ```bash
7
+ pip install anytimeline
8
+ ```
9
+
10
+ Documentation: <https://mluttikh.github.io/anytimeline/> · Changelog:
11
+ [CHANGELOG.md](CHANGELOG.md) · Licence: MIT.
12
+
13
+ Status: version 0.1. It draws **event charts**: one mark per event at the moment it
14
+ happened, on lanes, so the order of what happened is easy to see. Time can be datetimes (any
15
+ time zone, any century), durations from nanoseconds up, or plain numbers; a Time | Order switch
16
+ spaces events by rank instead of time. Up to about a million events. It also draws **Gantt
17
+ charts** and schedules: bars from a start to an end, with dependencies, progress and
18
+ milestones, and overlapping bars stacked per lane; and **traces**: spans under spans.
19
+
20
+ ```python
21
+ from anytimeline import Timeline
22
+ from anytimeline.synthetic import service_log
23
+
24
+ log = service_log() # a dict of columns; any Polars, pandas or PyArrow table works too
25
+ tl = Timeline()
26
+ tl.events(
27
+ log,
28
+ time="time",
29
+ lane="service",
30
+ color="level",
31
+ symbol="event",
32
+ route="request",
33
+ order="seq",
34
+ tooltip=["request", "user", "bytes"],
35
+ )
36
+ tl # click it, then scroll to zoom time; drag to pan; the toolbar has Zoom and Select
37
+ ```
38
+
39
+ A Gantt chart from a table with a row per task:
40
+
41
+ ```python
42
+ from anytimeline import gantt
43
+
44
+ gantt(plan, task="task", start="start", end="end", depends="after", progress="done",
45
+ color="phase", today="2026-10-12")
46
+ ```
47
+
48
+ Bars on other lanes (machines, people, services) come from `Timeline.intervals(...)`, and mix
49
+ with events on the same lanes.
50
+
51
+ Traces (OpenTelemetry, or any table of spans with a parent) plot as a waterfall that folds,
52
+ with each span's duration and the critical path:
53
+
54
+ ```python
55
+ from anytimeline import Timeline
56
+ from anytimeline.otel import read_otlp
57
+
58
+ tr = read_otlp("traces.jsonl") # or anytimeline.synthetic.traces()
59
+ Timeline().spans(tr.spans, color="service").events(tr.events, time="time", lane="span_id")
60
+ ```
61
+
62
+ The toolbar has three tools: **Pan** (drag moves through time and lanes), **Zoom** (drag a
63
+ time range to show it) and **Select** (drag a box, or click an event; the selection is rows of
64
+ your table in `tl.selection`). Time and Order switch the scale; Aa sets the text size (also `Timeline(font_size=14)`).
65
+ Press `?` in the plot for every mouse gesture and key; `f` or
66
+ the button shows it full screen, where lanes fill the screen and overlapping events spread
67
+ out.
68
+
69
+ States (`Timeline.states`: up, degraded, down per lane) and values (`Timeline.values`: a
70
+ number over time, as a line, area or steps) go on the same lanes, behind the events.
71
+
72
+ `group="host"` on a layer puts each host's lanes under a header of their own, in one plot
73
+ (`Timeline(align="start")` compares groups from their start); separate plots link with
74
+ `a.link(b)` and zoom and pan together.
75
+
76
+ `plot.save_html("plot.html")` writes the plot to one file that opens in any browser, still
77
+ interactive; the toolbar saves it as a PNG, and so does `plot.save_png("plot.png")`.
78
+
79
+ Documentation online: <https://mluttikh.github.io/anytimeline/>; or build it with
80
+ `uv run python scripts/build_docs.py` and open `site/index.html`. Example notebook: [`examples/event_charts.ipynb`](examples/event_charts.ipynb). How the code
81
+ is built: [`docs/architecture.md`](docs/architecture.md).
82
+
83
+ ## Development
84
+
85
+ Needs Python (via [uv](https://docs.astral.sh/uv/)) and Node.js 20+ for the JavaScript bundle.
86
+
87
+ ```bash
88
+ (cd js && npm ci && npm run build) # build src/anytimeline/static/widget.js
89
+ uv sync # create .venv with dev tools
90
+ uv run pytest # Python tests
91
+ (cd js && npm run typecheck && npm test)
92
+ uv run ruff check . && uv run ruff format --check . && uv run ty check
93
+ uv run python scripts/make_scenes.py # scenes for the visual tests
94
+ (cd js && npx playwright install chromium && npm run test:visual) # every scene × backend, marimo
95
+ uv run nbstripout --install # once per clone: commit notebooks without outputs
96
+ uv run python scripts/build_docs.py # user documentation into site/ (examples run; warnings fail)
97
+ uv run python scripts/build_docs.py serve # preview it at http://localhost:8000
98
+ ```
99
+
100
+ The user documentation is in `docs/user/`, built with [Zensical](https://zensical.org) and
101
+ organised as tutorials, how-to guides, reference and explanation. Its examples are
102
+ ```` ```python exec="on" ```` blocks that run while building, and its plots are live: each
103
+ example prints `plot._embed_html()`, which `standalone.js` draws in the page. The API
104
+ reference comes from the docstrings (Google style). The browser tests check the built site
105
+ too (`docs.spec.ts`, skipped until it is built).
106
+
107
+ Visual tests draw the scenes in `js/test/visual/scenes/` with each backend and compare them
108
+ with stored screenshots (macOS); `npm run test:visual:update` stores new ones after an
109
+ intended change. `PERF=1 npx playwright test perf` measures a million events (after
110
+ `uv run python scripts/make_scenes.py --million`).