plotjs 0.0.4__tar.gz → 0.0.5__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 (111) hide show
  1. {plotjs-0.0.4 → plotjs-0.0.5}/.coverage +0 -0
  2. {plotjs-0.0.4 → plotjs-0.0.5}/.github/workflows/lint.yaml +3 -2
  3. plotjs-0.0.5/.github/workflows/tests-js.yaml +18 -0
  4. plotjs-0.0.4/.github/workflows/tests.yaml → plotjs-0.0.5/.github/workflows/tests-python.yaml +4 -5
  5. {plotjs-0.0.4 → plotjs-0.0.5}/.github/workflows/type.yaml +3 -2
  6. {plotjs-0.0.4 → plotjs-0.0.5}/.pre-commit-config.yaml +0 -1
  7. {plotjs-0.0.4 → plotjs-0.0.5}/Makefile +6 -0
  8. {plotjs-0.0.4/plotjs.egg-info → plotjs-0.0.5}/PKG-INFO +2 -2
  9. {plotjs-0.0.4 → plotjs-0.0.5}/README.md +1 -1
  10. {plotjs-0.0.4 → plotjs-0.0.5}/coverage-badge.svg +1 -1
  11. {plotjs-0.0.4 → plotjs-0.0.5}/docs/developers/contributing.md +18 -6
  12. plotjs-0.0.5/docs/developers/overview.md +27 -0
  13. plotjs-0.0.4/docs/developers/how-it-works.md → plotjs-0.0.5/docs/developers/parsing-matplotlib-svg.md +5 -1
  14. plotjs-0.0.5/docs/developers/svg-parser-reference.md +117 -0
  15. {plotjs-0.0.4 → plotjs-0.0.5}/docs/gallery/index.md +18 -2
  16. {plotjs-0.0.4 → plotjs-0.0.5}/docs/guides/advanced/advanced.py +79 -16
  17. {plotjs-0.0.4 → plotjs-0.0.5}/docs/guides/advanced/index.md +90 -2
  18. {plotjs-0.0.4 → plotjs-0.0.5}/docs/guides/css/CSS.py +5 -5
  19. {plotjs-0.0.4 → plotjs-0.0.5}/docs/guides/css/index.md +6 -6
  20. plotjs-0.0.5/docs/guides/embed-graphs/index.md +104 -0
  21. {plotjs-0.0.4 → plotjs-0.0.5}/docs/guides/javascript/index.md +5 -5
  22. {plotjs-0.0.4 → plotjs-0.0.5}/docs/guides/javascript/javascript.py +3 -3
  23. plotjs-0.0.5/docs/guides/troubleshooting/index.md +194 -0
  24. plotjs-0.0.5/docs/iframes/CSS-2.html +1656 -0
  25. plotjs-0.0.5/docs/iframes/CSS.html +1652 -0
  26. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/area-natural-disasters.html +298 -216
  27. plotjs-0.0.5/docs/iframes/bug.html +1071 -0
  28. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/javascript.html +603 -521
  29. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/javascript2.html +461 -379
  30. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/quickstart.html +603 -521
  31. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/quickstart10.html +465 -383
  32. plotjs-0.0.5/docs/iframes/quickstart11.html +2489 -0
  33. plotjs-0.0.4/docs/iframes/quickstart3.html → plotjs-0.0.5/docs/iframes/quickstart2.html +604 -522
  34. plotjs-0.0.4/docs/iframes/quickstart2.html → plotjs-0.0.5/docs/iframes/quickstart3.html +603 -521
  35. plotjs-0.0.5/docs/iframes/quickstart4.html +1335 -0
  36. plotjs-0.0.5/docs/iframes/quickstart5.html +1551 -0
  37. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/quickstart6.html +304 -222
  38. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/quickstart7.html +461 -379
  39. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/quickstart8.html +302 -220
  40. {plotjs-0.0.4 → plotjs-0.0.5}/docs/iframes/quickstart9.html +918 -836
  41. plotjs-0.0.5/docs/iframes/random-walk-1.html +39191 -0
  42. plotjs-0.0.5/docs/img/overview.png +0 -0
  43. {plotjs-0.0.4 → plotjs-0.0.5}/docs/index.md +77 -35
  44. {plotjs-0.0.4 → plotjs-0.0.5}/docs/index.qmd +75 -34
  45. plotjs-0.0.5/docs/reference/plotjs.md +1 -0
  46. plotjs-0.0.5/docs/stylesheets/style.css +24 -0
  47. {plotjs-0.0.4 → plotjs-0.0.5}/mkdocs.yaml +11 -3
  48. plotjs-0.0.5/package-lock.json +3659 -0
  49. plotjs-0.0.5/package.json +14 -0
  50. plotjs-0.0.5/plotjs/__init__.py +6 -0
  51. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/css.py +1 -1
  52. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/javascript.py +1 -1
  53. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/main.py +107 -56
  54. plotjs-0.0.5/plotjs/static/plotparser.js +229 -0
  55. plotjs-0.0.5/plotjs/static/template.html +103 -0
  56. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/utils.py +13 -0
  57. {plotjs-0.0.4 → plotjs-0.0.5/plotjs.egg-info}/PKG-INFO +2 -2
  58. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs.egg-info/SOURCES.txt +16 -5
  59. {plotjs-0.0.4 → plotjs-0.0.5}/pyproject.toml +4 -2
  60. plotjs-0.0.5/tests/test-javascript/ParserSelectors.test.js +51 -0
  61. plotjs-0.0.5/tests/test-javascript/ParserSetHover.test.js +42 -0
  62. plotjs-0.0.5/tests/test-python/static/script2.js +1 -0
  63. plotjs-0.0.5/tests/test-python/static/style-invalid.css +1 -0
  64. {plotjs-0.0.4 → plotjs-0.0.5}/tests/test-python/test_css_and_js_utils.py +27 -0
  65. plotjs-0.0.5/tests/test-python/test_magic_plot.py +145 -0
  66. {plotjs-0.0.4 → plotjs-0.0.5}/tests/test-python/test_main.py +4 -4
  67. plotjs-0.0.5/tests/test-python/test_other_utils.py +46 -0
  68. {plotjs-0.0.4 → plotjs-0.0.5}/vitest.config.js +1 -1
  69. plotjs-0.0.4/docs/guides/troubleshooting/index.md +0 -28
  70. plotjs-0.0.4/docs/iframes/CSS-2.html +0 -1574
  71. plotjs-0.0.4/docs/iframes/CSS.html +0 -1570
  72. plotjs-0.0.4/docs/iframes/quickstart11.html +0 -2407
  73. plotjs-0.0.4/docs/iframes/quickstart4.html +0 -1253
  74. plotjs-0.0.4/docs/iframes/quickstart5.html +0 -1507
  75. plotjs-0.0.4/docs/reference/magic-plot.md +0 -1
  76. plotjs-0.0.4/docs/stylesheets/style.css +0 -52
  77. plotjs-0.0.4/package-lock.json +0 -6317
  78. plotjs-0.0.4/package.json +0 -11
  79. plotjs-0.0.4/plotjs/__init__.py +0 -6
  80. plotjs-0.0.4/plotjs/static/main.js +0 -87
  81. plotjs-0.0.4/plotjs/static/template.html +0 -236
  82. plotjs-0.0.4/tests/PlotSVGParser.test.js +0 -83
  83. plotjs-0.0.4/tests/test-python/test_magic_plot.py +0 -13
  84. {plotjs-0.0.4 → plotjs-0.0.5}/.gitattributes +0 -0
  85. {plotjs-0.0.4 → plotjs-0.0.5}/.github/workflows/doc.yaml +0 -0
  86. {plotjs-0.0.4 → plotjs-0.0.5}/.github/workflows/pypi.yaml +0 -0
  87. {plotjs-0.0.4 → plotjs-0.0.5}/.gitignore +0 -0
  88. {plotjs-0.0.4 → plotjs-0.0.5}/LICENSE +0 -0
  89. {plotjs-0.0.4 → plotjs-0.0.5}/docs/gallery/index.qmd +0 -0
  90. {plotjs-0.0.4 → plotjs-0.0.5}/docs/img/how-it-works-1.png +0 -0
  91. {plotjs-0.0.4 → plotjs-0.0.5}/docs/img/how-it-works-2.png +0 -0
  92. {plotjs-0.0.4 → plotjs-0.0.5}/docs/index_files/figure-commonmark/cell-3-output-1.png +0 -0
  93. {plotjs-0.0.4 → plotjs-0.0.5}/docs/reference/css.md +0 -0
  94. {plotjs-0.0.4 → plotjs-0.0.5}/docs/reference/datasets.md +0 -0
  95. {plotjs-0.0.4 → plotjs-0.0.5}/docs/reference/javascript.md +0 -0
  96. {plotjs-0.0.4 → plotjs-0.0.5}/docs/static/style.css +0 -0
  97. {plotjs-0.0.4 → plotjs-0.0.5}/overrides/partials/footer.html +0 -0
  98. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/data/__init__.py +0 -0
  99. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/data/datasets.py +0 -0
  100. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/data/iris.csv +0 -0
  101. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/data/mtcars.csv +0 -0
  102. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/data/titanic.csv +0 -0
  103. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs/static/default.css +0 -0
  104. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs.egg-info/dependency_links.txt +0 -0
  105. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs.egg-info/requires.txt +0 -0
  106. {plotjs-0.0.4 → plotjs-0.0.5}/plotjs.egg-info/top_level.txt +0 -0
  107. {plotjs-0.0.4 → plotjs-0.0.5}/setup.cfg +0 -0
  108. {plotjs-0.0.4 → plotjs-0.0.5}/tests/test-python/__init__.py +0 -0
  109. {plotjs-0.0.4 → plotjs-0.0.5}/tests/test-python/static/script.js +0 -0
  110. {plotjs-0.0.4 → plotjs-0.0.5}/tests/test-python/static/style.css +0 -0
  111. {plotjs-0.0.4 → plotjs-0.0.5}/tests/test-python/test_data.py +0 -0
Binary file
@@ -2,8 +2,9 @@ name: Check Code Formatting
2
2
 
3
3
  on:
4
4
  pull_request:
5
- branches:
6
- - main
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
7
8
 
8
9
  jobs:
9
10
  check-formatting:
@@ -0,0 +1,18 @@
1
+ name: Tests JavaScript
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version: 20
17
+ - run: npm install
18
+ - run: npm test
@@ -1,8 +1,10 @@
1
- name: Tests (Python + JS)
1
+ name: Tests Python
2
2
 
3
3
  on:
4
4
  pull_request:
5
5
  branches: [main]
6
+ push:
7
+ branches: [main]
6
8
 
7
9
  jobs:
8
10
  build:
@@ -24,8 +26,5 @@ jobs:
24
26
  - name: Install the project
25
27
  run: uv sync --all-groups
26
28
 
27
- - name: Install npm dependencies
28
- run: npm install
29
-
30
29
  - name: Run tests
31
- run: make test
30
+ run: uv run pytest
@@ -2,8 +2,9 @@ name: Check Static Typing
2
2
 
3
3
  on:
4
4
  pull_request:
5
- branches:
6
- - main
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
7
8
 
8
9
  jobs:
9
10
  check-formatting:
@@ -13,7 +13,6 @@ repos:
13
13
  - id: check-yaml
14
14
  - id: trailing-whitespace
15
15
  - id: end-of-file-fixer
16
- - id: check-added-large-files
17
16
  - repo: https://github.com/python-jsonschema/check-jsonschema
18
17
  rev: 0.28.2
19
18
  hooks:
@@ -16,6 +16,12 @@ coverage:
16
16
  uv run genbadge coverage -i coverage.xml
17
17
  rm coverage.xml
18
18
 
19
+ preview:
20
+ uv run mkdocs serve
21
+
22
+ jsdoc:
23
+ npm run docs:js
24
+
19
25
  test:
20
26
  uv run pytest # run python tests
21
27
  npm test # run javascript tests
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotjs
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: Turn static matplotlib charts into interactive web visualizations
5
5
  Author-email: Joseph Barbier <joseph.barbierdarnal@mail.com>
6
6
  License-Expression: MIT
@@ -41,7 +41,7 @@ Dynamic: license-file
41
41
 
42
42
  ## Installation
43
43
 
44
- From PyPI:
44
+ From PyPI (recommended):
45
45
 
46
46
  ```
47
47
  pip install plotjs
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## Installation
21
21
 
22
- From PyPI:
22
+ From PyPI (recommended):
23
23
 
24
24
  ```
25
25
  pip install plotjs
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 93.02%"><title>coverage: 93.02%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#4c1"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">93.02%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">93.02%</text></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 93.92%"><title>coverage: 93.92%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#4c1"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">93.92%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">93.92%</text></g></svg>
@@ -2,16 +2,22 @@
2
2
 
3
3
  The best way to help the development is to:
4
4
 
5
- - list the bugs you found by opening [GitHub issues](https://github.com/y-sunflower/plotjs/issues){target="_blank"}
6
- - list the features you'd like to see by opening [GitHub issues](https://github.com/y-sunflower/plotjs/issues){target="_blank"}
5
+ - list the bugs you found by opening [GitHub issues](https://github.com/y-sunflower/plotjs/issues){target="\_blank"}
6
+ - list the features you'd like to see by opening [GitHub issues](https://github.com/y-sunflower/plotjs/issues){target="\_blank"}
7
7
 
8
8
  ## Setting up your environment
9
9
 
10
+ You need to have the following installed on your machine:
11
+
12
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/)
13
+ - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
14
+ - [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
15
+
10
16
  ### Install for development
11
17
 
12
18
  - Fork the repository to your own GitHub account.
13
19
 
14
- - Clone your forked repository to your local machine (ensure you have [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)):
20
+ - Clone your forked repository to your local machine:
15
21
 
16
22
  ```bash
17
23
  git clone https://github.com/github_user_name/plotjs.git
@@ -25,7 +31,7 @@ git remote add upstream https://github.com/y-sunflower/plotjs.git
25
31
  git checkout -b my-feature
26
32
  ```
27
33
 
28
- - Set up your Python environment (ensure you have [uv installed](https://docs.astral.sh/uv/getting-started/installation/)):
34
+ - Set up your Python environment:
29
35
 
30
36
  ```bash
31
37
  uv sync --all-groups --dev
@@ -33,6 +39,12 @@ uv run pre-commit install
33
39
  uv pip install -e .
34
40
  ```
35
41
 
42
+ - Install npm dependencies:
43
+
44
+ ```bash
45
+ npm install
46
+ ```
47
+
36
48
  ## Code
37
49
 
38
50
  You can now make changes to the package and start coding!
@@ -42,13 +54,13 @@ You can now make changes to the package and start coding!
42
54
  - Test that everything works correctly by running:
43
55
 
44
56
  ```bash
45
- uv run pytest
57
+ make test
46
58
  ```
47
59
 
48
60
  ### Preview documentation locally
49
61
 
50
62
  ```bash
51
- uv run mkdocs serve
63
+ make preview
52
64
  ```
53
65
 
54
66
  ## Push changes
@@ -0,0 +1,27 @@
1
+ The core idea behind `plotjs` is that since you can natively save a matplotlib plot as [SVG](https://developer.mozilla.org/en-US/docs/Web/SVG), it's possible to manipulate that SVG from the browser.
2
+
3
+ ![](../img/overview.png)
4
+
5
+ In practice, the saved HTML file from `plotjs` is just:
6
+
7
+ - the SVG output from matplotlib
8
+ - some CSS styling (default and from user)
9
+ - a parser for the SVG (in javascript) and javascript from user
10
+
11
+ ## Core issues
12
+
13
+ There are 2 things important things to solve at this point:
14
+
15
+ - communicate info from Python to JavaScript
16
+ - parse the SVG with JavaScript
17
+
18
+ The first point is important because the SVG file is not enough for us to parse it correctly. We need some info from the original matplotlib `Figure`. This is mainly solved using [`jinja2`](https://jinja.palletsprojects.com/en/stable/), often used in web development. This allows us to pass variables from Python to an HTML template (e.g., simple HTML file with placeholders that we'll fill). The core things we want to pass are:
19
+
20
+ - the SVG of the plot
21
+ - the JavaScript parser (kept in its own js file)
22
+ - additional CSS/JS from the user
23
+ - a dictionnary with custom info (named `plot_data_json` in the codebase)
24
+
25
+ `plot_data_json` is passed directly to JavaScript and is then parsed with `JSON.parse()`. This works because Python dictionnaries can be (assuming a few rules that we respect here) valid JSON and be considered as such.
26
+
27
+ Then we "just" have to parse the SVG and apply the effects the user want: hover, onclick effects, etc. You can learn more about how the SVG is parsed [here](./parsing-matplotlib-svg.md).
@@ -21,7 +21,7 @@ But it means we don't have full control over how the plot is structured (from th
21
21
  For the moment, we just take the user's matplotlib figure and save it as SVG. This is just:
22
22
 
23
23
  ```python
24
- fig.savefig("plot.svg")
24
+ plt.savefig("plot.svg")
25
25
  ```
26
26
 
27
27
  Now, let's say the figure contains a scatter plot and we want to add a tooltip: when someone hovers their mouse over a point, it displays a label.
@@ -156,3 +156,7 @@ The idea is basically:
156
156
  This gives us a `lines` variable that only contains the lines of interest!
157
157
 
158
158
  The logic is the same for other plot elements: bars, points, polygons, etc.
159
+
160
+ <br>
161
+
162
+ You can find the **reference page** of the parser [here](./svg-parser-reference.md)
@@ -0,0 +1,117 @@
1
+ ## Functions
2
+
3
+ <dl>
4
+ <dt><a href="#findBars">findBars(svg, axes_class)</a> ⇒ <code>d3.Selection</code></dt>
5
+ <dd><p>Find bar elements (<code>patch</code> groups with clipping) inside a given axes.</p>
6
+ </dd>
7
+ <dt><a href="#findPoints">findPoints(svg, axes_class, tooltip_groups)</a> ⇒ <code>d3.Selection</code></dt>
8
+ <dd><p>Find scatter plot points inside a given axes.
9
+ Handles both <code>&lt;use&gt;</code> and <code>&lt;path&gt;</code> fallback cases,
10
+ and assigns <code>data-group</code> attributes based on tooltip groups.</p>
11
+ </dd>
12
+ <dt><a href="#findLines">findLines(svg, axes_class)</a> ⇒ <code>d3.Selection</code></dt>
13
+ <dd><p>Find line elements (<code>line2d</code> paths) inside a given axes,
14
+ excluding axis grid lines.</p>
15
+ </dd>
16
+ <dt><a href="#findAreas">findAreas(svg, axes_class)</a> ⇒ <code>d3.Selection</code></dt>
17
+ <dd><p>Find filled area elements (<code>FillBetweenPolyCollection</code> paths) inside a given axes.</p>
18
+ </dd>
19
+ <dt><a href="#nearestElementFromMouse">nearestElementFromMouse(mouseX, mouseY, elements)</a> ⇒ <code>Element</code> | <code>null</code></dt>
20
+ <dd><p>Compute the nearest element to the mouse cursor from a set of elements.
21
+ Uses bounding box centers for distance.
22
+ This function is used when the <code>hover_nearest</code> argument is true.</p>
23
+ </dd>
24
+ <dt><a href="#setHoverEffect">setHoverEffect(plot_element, axes_class, tooltip_labels, tooltip_groups, show_tooltip, hover_nearest)</a></dt>
25
+ <dd><p>Attach hover interaction and tooltip display to plot elements.
26
+ Can highlight nearest element (if enabled) or hovered element directly.</p>
27
+ </dd>
28
+ </dl>
29
+
30
+ <a name="findBars"></a>
31
+
32
+ ## findBars(svg, axes_class) ⇒ <code>d3.Selection</code>
33
+ Find bar elements (`patch` groups with clipping) inside a given axes.
34
+
35
+ **Kind**: global function
36
+ **Returns**: <code>d3.Selection</code> - D3 selection of bar elements.
37
+
38
+ | Param | Type | Description |
39
+ | --- | --- | --- |
40
+ | svg | <code>d3.Selection</code> | D3 selection of the SVG element. |
41
+ | axes_class | <code>string</code> | ID of the axes group (e.g. "axes_1"). |
42
+
43
+ <a name="findPoints"></a>
44
+
45
+ ## findPoints(svg, axes_class, tooltip_groups) ⇒ <code>d3.Selection</code>
46
+ Find scatter plot points inside a given axes.
47
+ Handles both `<use>` and `<path>` fallback cases,
48
+ and assigns `data-group` attributes based on tooltip groups.
49
+
50
+ **Kind**: global function
51
+ **Returns**: <code>d3.Selection</code> - D3 selection of point elements.
52
+
53
+ | Param | Type | Description |
54
+ | --- | --- | --- |
55
+ | svg | <code>d3.Selection</code> | D3 selection of the SVG element. |
56
+ | axes_class | <code>string</code> | ID of the axes group (e.g. "axes_1"). |
57
+ | tooltip_groups | <code>Array.&lt;string&gt;</code> | Group identifiers for tooltips, parallel to points. |
58
+
59
+ <a name="findLines"></a>
60
+
61
+ ## findLines(svg, axes_class) ⇒ <code>d3.Selection</code>
62
+ Find line elements (`line2d` paths) inside a given axes,
63
+ excluding axis grid lines.
64
+
65
+ **Kind**: global function
66
+ **Returns**: <code>d3.Selection</code> - D3 selection of line elements.
67
+
68
+ | Param | Type | Description |
69
+ | --- | --- | --- |
70
+ | svg | <code>d3.Selection</code> | D3 selection of the SVG element. |
71
+ | axes_class | <code>string</code> | ID of the axes group. |
72
+
73
+ <a name="findAreas"></a>
74
+
75
+ ## findAreas(svg, axes_class) ⇒ <code>d3.Selection</code>
76
+ Find filled area elements (`FillBetweenPolyCollection` paths) inside a given axes.
77
+
78
+ **Kind**: global function
79
+ **Returns**: <code>d3.Selection</code> - D3 selection of area elements.
80
+
81
+ | Param | Type | Description |
82
+ | --- | --- | --- |
83
+ | svg | <code>d3.Selection</code> | D3 selection of the SVG element. |
84
+ | axes_class | <code>string</code> | ID of the axes group. |
85
+
86
+ <a name="nearestElementFromMouse"></a>
87
+
88
+ ## nearestElementFromMouse(mouseX, mouseY, elements) ⇒ <code>Element</code> \| <code>null</code>
89
+ Compute the nearest element to the mouse cursor from a set of elements.
90
+ Uses bounding box centers for distance.
91
+ This function is used when the `hover_nearest` argument is true.
92
+
93
+ **Kind**: global function
94
+ **Returns**: <code>Element</code> \| <code>null</code> - The nearest DOM element or `null`.
95
+
96
+ | Param | Type | Description |
97
+ | --- | --- | --- |
98
+ | mouseX | <code>number</code> | X coordinate of the mouse relative to SVG. |
99
+ | mouseY | <code>number</code> | Y coordinate of the mouse relative to SVG. |
100
+ | elements | <code>d3.Selection</code> | Selection of candidate elements. |
101
+
102
+ <a name="setHoverEffect"></a>
103
+
104
+ ## setHoverEffect(plot_element, axes_class, tooltip_labels, tooltip_groups, show_tooltip, hover_nearest)
105
+ Attach hover interaction and tooltip display to plot elements.
106
+ Can highlight nearest element (if enabled) or hovered element directly.
107
+
108
+ **Kind**: global function
109
+
110
+ | Param | Type | Description |
111
+ | --- | --- | --- |
112
+ | plot_element | <code>d3.Selection</code> | Selection of plot elements (points, lines, etc.). |
113
+ | axes_class | <code>string</code> | ID of the axes group. |
114
+ | tooltip_labels | <code>Array.&lt;string&gt;</code> | Tooltip labels for each element. |
115
+ | tooltip_groups | <code>Array.&lt;string&gt;</code> | Group identifiers for each element. |
116
+ | show_tooltip | <code>&quot;block&quot;</code> \| <code>&quot;none&quot;</code> | Whether to display tooltips. |
117
+ | hover_nearest | <code>boolean</code> | If true, highlight nearest element instead of hovered one. |
@@ -70,6 +70,18 @@ This page contains all the `plotjs` examples from this website.
70
70
 
71
71
  </iframe>
72
72
 
73
+ <iframe width="100%" height="300" src="../iframes/quickstart11.html" style="flex: 1; border: none;">
74
+
75
+ </iframe>
76
+
77
+ </div>
78
+
79
+ <div style="display: flex;">
80
+
81
+ <iframe width="100%" height="300" src="../iframes/random-walk-1.html" style="flex: 1; border: none;">
82
+
83
+ </iframe>
84
+
73
85
  <iframe width="100%" height="300" src="../iframes/javascript2.html" style="flex: 1; border: none;">
74
86
 
75
87
  </iframe>
@@ -78,11 +90,11 @@ This page contains all the `plotjs` examples from this website.
78
90
 
79
91
  <div style="display: flex;">
80
92
 
81
- <iframe width="100%" height="300" src="../iframes/CSS-2.html" style="flex: 1; border: none;">
93
+ <iframe width="100%" height="300" src="../iframes/bug.html" style="flex: 1; border: none;">
82
94
 
83
95
  </iframe>
84
96
 
85
- <iframe width="100%" height="300" src="../iframes/quickstart6.html" style="flex: 1; border: none;">
97
+ <iframe width="100%" height="300" src="../iframes/CSS-2.html" style="flex: 1; border: none;">
86
98
 
87
99
  </iframe>
88
100
 
@@ -90,6 +102,10 @@ This page contains all the `plotjs` examples from this website.
90
102
 
91
103
  <div style="display: flex;">
92
104
 
105
+ <iframe width="100%" height="300" src="../iframes/quickstart6.html" style="flex: 1; border: none;">
106
+
107
+ </iframe>
108
+
93
109
  <iframe width="100%" height="300" src="../iframes/quickstart7.html" style="flex: 1; border: none;">
94
110
 
95
111
  </iframe>
@@ -1,4 +1,4 @@
1
- from plotjs import MagicPlot, css
1
+ from plotjs import PlotJS, css
2
2
  import pandas as pd
3
3
  import numpy as np
4
4
  import matplotlib.pyplot as plt
@@ -179,7 +179,7 @@ ax_arrow(
179
179
  )
180
180
  plt.savefig("debug.svg")
181
181
 
182
- MagicPlot(fig, bbox_inches="tight").add_css(
182
+ PlotJS(fig, bbox_inches="tight").add_css(
183
183
  css.from_dict(
184
184
  {
185
185
  ".tooltip": {
@@ -195,19 +195,82 @@ MagicPlot(fig, bbox_inches="tight").add_css(
195
195
  #####################################################
196
196
 
197
197
 
198
+ size = 10000
199
+
200
+ labels = ["S&P500", "CAC40", "Bitcoin", "Livret A", "Default"]
201
+ groups = ["safe", "safe", "safe", "not safe", "not safe"]
202
+
203
+ fig, axs = plt.subplots(figsize=(10, 10), nrows=2)
204
+ axs[0].plot(
205
+ np.cumsum(np.random.choice([-1, 1], size=size)),
206
+ linewidth=5,
207
+ color="#264653",
208
+ label=labels[0],
209
+ )
210
+ axs[0].plot(
211
+ np.cumsum(np.random.choice([-1, 1], size=size)),
212
+ linewidth=5,
213
+ color="#2a9d8f",
214
+ label=labels[1],
215
+ )
216
+ axs[0].plot(
217
+ np.cumsum(np.random.choice([-1, 1], size=size)),
218
+ linewidth=5,
219
+ color="#e9c46a",
220
+ label=labels[2],
221
+ )
222
+ axs[0].plot(
223
+ np.cumsum(np.random.choice([-1, 1], size=size)),
224
+ linewidth=5,
225
+ color="#0077b6",
226
+ label=labels[3],
227
+ )
228
+ axs[0].plot(
229
+ np.cumsum(np.random.choice([-1, 1], size=size)),
230
+ linewidth=5,
231
+ color="#14213d",
232
+ label=labels[4],
233
+ )
234
+ axs[0].legend()
235
+
236
+ axs[1].plot(
237
+ np.cumsum(np.random.choice([-1, 1], size=size)),
238
+ linewidth=5,
239
+ color="#264653",
240
+ label=labels[0],
241
+ )
242
+ axs[1].plot(
243
+ np.cumsum(np.random.choice([-1, 1], size=size)),
244
+ linewidth=5,
245
+ color="#2a9d8f",
246
+ label=labels[1],
247
+ )
248
+ axs[1].plot(
249
+ np.cumsum(np.random.choice([-1, 1], size=size)),
250
+ linewidth=5,
251
+ color="#e9c46a",
252
+ label=labels[2],
253
+ )
254
+ axs[1].plot(
255
+ np.cumsum(np.random.choice([-1, 1], size=size)),
256
+ linewidth=5,
257
+ color="#0077b6",
258
+ label=labels[3],
259
+ )
260
+ axs[1].plot(
261
+ np.cumsum(np.random.choice([-1, 1], size=size)),
262
+ linewidth=5,
263
+ color="#14213d",
264
+ label=labels[4],
265
+ )
266
+ axs[1].legend()
267
+
268
+
198
269
  (
199
- MagicPlot(fig)
200
- .add_css(
201
- css.from_dict(
202
- {
203
- ".tooltip": {
204
- "width": "180px",
205
- "text-align": "center",
206
- "font-size": "1.2em",
207
- "background": "#000814",
208
- }
209
- }
210
- )
211
- )
212
- .add_tooltip(labels=columns)
270
+ PlotJS(fig=fig)
271
+ .add_tooltip(labels=labels, groups=labels, ax=axs[0])
272
+ .add_tooltip(labels=labels, groups=labels, ax=axs[1])
273
+ .save("docs/iframes/random-walk-1.html")
213
274
  )
275
+
276
+ ##########################################
@@ -3,7 +3,7 @@
3
3
  ## Natural disasters
4
4
 
5
5
  ```py
6
- from plotjs import MagicPlot, css
6
+ from plotjs import PlotJS, css
7
7
  import pandas as pd
8
8
  import numpy as np
9
9
  import matplotlib.pyplot as plt
@@ -184,7 +184,7 @@ ax_arrow(
184
184
  )
185
185
  plt.savefig("debug.svg")
186
186
 
187
- MagicPlot(fig, bbox_inches="tight").add_css(
187
+ PlotJS(fig, bbox_inches="tight").add_css(
188
188
  css.from_dict(
189
189
  {
190
190
  ".tooltip": {
@@ -199,3 +199,91 @@ MagicPlot(fig, bbox_inches="tight").add_css(
199
199
  ```
200
200
 
201
201
  <iframe width="1000" height="400" src="../../iframes/area-natural-disasters.html" style="border:none;"></iframe>
202
+
203
+ ## Random walks
204
+
205
+ ```python
206
+ import numpy as np
207
+ import matplotlib.pyplot as plt
208
+ from plotjs import PlotJS
209
+
210
+ size = 10000
211
+
212
+ labels = ["S&P500", "CAC40", "Bitcoin", "Livret A", "Default"]
213
+ groups = ["safe", "safe", "safe", "not safe", "not safe"]
214
+
215
+ fig, axs = plt.subplots(figsize=(10, 10), nrows=2)
216
+ axs[0].plot(
217
+ np.cumsum(np.random.choice([-1, 1], size=size)),
218
+ linewidth=5,
219
+ color="#264653",
220
+ label=labels[0],
221
+ )
222
+ axs[0].plot(
223
+ np.cumsum(np.random.choice([-1, 1], size=size)),
224
+ linewidth=5,
225
+ color="#2a9d8f",
226
+ label=labels[1],
227
+ )
228
+ axs[0].plot(
229
+ np.cumsum(np.random.choice([-1, 1], size=size)),
230
+ linewidth=5,
231
+ color="#e9c46a",
232
+ label=labels[2],
233
+ )
234
+ axs[0].plot(
235
+ np.cumsum(np.random.choice([-1, 1], size=size)),
236
+ linewidth=5,
237
+ color="#0077b6",
238
+ label=labels[3],
239
+ )
240
+ axs[0].plot(
241
+ np.cumsum(np.random.choice([-1, 1], size=size)),
242
+ linewidth=5,
243
+ color="#14213d",
244
+ label=labels[4],
245
+ )
246
+ axs[0].legend()
247
+
248
+ axs[1].plot(
249
+ np.cumsum(np.random.choice([-1, 1], size=size)),
250
+ linewidth=5,
251
+ color="#264653",
252
+ label=labels[0],
253
+ )
254
+ axs[1].plot(
255
+ np.cumsum(np.random.choice([-1, 1], size=size)),
256
+ linewidth=5,
257
+ color="#2a9d8f",
258
+ label=labels[1],
259
+ )
260
+ axs[1].plot(
261
+ np.cumsum(np.random.choice([-1, 1], size=size)),
262
+ linewidth=5,
263
+ color="#e9c46a",
264
+ label=labels[2],
265
+ )
266
+ axs[1].plot(
267
+ np.cumsum(np.random.choice([-1, 1], size=size)),
268
+ linewidth=5,
269
+ color="#0077b6",
270
+ label=labels[3],
271
+ )
272
+ axs[1].plot(
273
+ np.cumsum(np.random.choice([-1, 1], size=size)),
274
+ linewidth=5,
275
+ color="#14213d",
276
+ label=labels[4],
277
+ )
278
+ axs[1].legend()
279
+
280
+
281
+ (
282
+ PlotJS(fig=fig)
283
+ .add_tooltip(labels=labels, groups=labels, ax=axs[0])
284
+ .add_tooltip(labels=labels, groups=labels, ax=axs[1])
285
+ .save("docs/iframes/random-walk-1.html")
286
+ )
287
+ ```
288
+
289
+ <iframe width="1000" height="800" src="../../iframes/random-walk-1.html" style="border:none;"></iframe>
@@ -1,5 +1,5 @@
1
1
  import matplotlib.pyplot as plt
2
- from plotjs import MagicPlot, data, css
2
+ from plotjs import PlotJS, data, css
3
3
 
4
4
  df = data.load_iris()
5
5
 
@@ -26,7 +26,7 @@ df["tooltip"] = (
26
26
  )
27
27
 
28
28
  (
29
- MagicPlot()
29
+ PlotJS()
30
30
  .add_tooltip(labels=df["tooltip"])
31
31
  .add_css(".tooltip {background: red; color: blue;}")
32
32
  .save("docs/iframes/CSS.html")
@@ -34,13 +34,13 @@ df["tooltip"] = (
34
34
 
35
35
 
36
36
  (
37
- MagicPlot()
37
+ PlotJS()
38
38
  .add_tooltip(labels=df["tooltip"])
39
39
  .add_css(css.from_dict({".tooltip": {"background": "red", "color": "blue"}}))
40
40
  )
41
41
 
42
42
  (
43
- MagicPlot()
43
+ PlotJS()
44
44
  .add_tooltip(
45
45
  labels=df["tooltip"],
46
46
  )
@@ -49,7 +49,7 @@ df["tooltip"] = (
49
49
  )
50
50
 
51
51
  (
52
- MagicPlot()
52
+ PlotJS()
53
53
  .add_tooltip(labels=df["tooltip"])
54
54
  .add_css(css.from_file("docs/static/style.css"))
55
55
  .save("docs/iframes/CSS-2.html")