Skip to content

Commit 7bb2805

Browse files
committed
Merge with v4.0
2 parents 3aaf531 + 445ce41 commit 7bb2805

591 files changed

Lines changed: 169091 additions & 309915 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/setup-workspace/action.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
name: 'Setup Workspace'
22
description: 'Setup Node.js, install dependencies, and download build artifacts'
33

4-
inputs:
5-
node-version:
6-
description: 'Node.js version to use'
7-
default: '18'
8-
94
runs:
105
using: 'composite'
116
steps:
127
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
138
with:
14-
node-version: ${{ inputs.node-version }}
9+
node-version-file: '.nvmrc'
1510
cache: 'npm'
1611

1712
- name: Install dependencies

.github/workflows/ci.yml

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ concurrency:
1414
group: ci-${{ github.event.pull_request.number || github.ref }}
1515
cancel-in-progress: true
1616

17-
env:
18-
NODE_VERSION: '18'
19-
2017
jobs:
2118
detect-changes:
2219
runs-on: ubuntu-latest
@@ -60,7 +57,7 @@ jobs:
6057

6158
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
6259
with:
63-
node-version: ${{ env.NODE_VERSION }}
60+
node-version-file: '.nvmrc'
6461
cache: 'npm'
6562

6663
- name: Install dependencies
@@ -270,9 +267,9 @@ jobs:
270267
chrome-version: 'stable'
271268

272269
- name: Run noCI tests
273-
uses: coactions/setup-xvfb@b6b4fcfb9f5a895edadc3bc76318fae0ac17c8b3 # v1
270+
uses: ./.github/actions/run-xvfb
274271
with:
275-
run: ./tasks/noci_test.sh jasmine
272+
run: npm run test-jasmine -- --tags=noCI,noCIdep --nowatch
276273

277274
# ============================================================
278275
# Image baseline generation and comparison
@@ -579,6 +576,26 @@ jobs:
579576
- name: Run syntax tests on source files
580577
run: .github/scripts/test.sh source-syntax
581578

579+
typecheck:
580+
needs: install-and-cibuild
581+
runs-on: ubuntu-latest
582+
steps:
583+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
584+
- uses: ./.github/actions/setup-workspace
585+
586+
- name: Type-check TypeScript sources
587+
run: npm run typecheck
588+
589+
generated-types-drift:
590+
needs: install-and-cibuild
591+
runs-on: ubuntu-latest
592+
steps:
593+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
594+
- uses: ./.github/actions/setup-workspace
595+
596+
- name: Verify generated types are in sync with schema
597+
run: npm run schema-typegen-diff-check
598+
582599
# ============================================================
583600
# Standalone jobs (no dependencies on install-and-cibuild)
584601
# ============================================================
@@ -593,7 +610,7 @@ jobs:
593610

594611
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
595612
with:
596-
node-version: ${{ env.NODE_VERSION }}
613+
node-version-file: '.nvmrc'
597614
cache: 'npm'
598615

599616
- name: Set up build environment
@@ -624,7 +641,7 @@ jobs:
624641

625642
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
626643
with:
627-
node-version: ${{ env.NODE_VERSION }}
644+
node-version-file: '.nvmrc'
628645
cache: 'npm'
629646

630647
- name: Set up build environment

.github/workflows/publish-dist.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525

2626
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
2727
with:
28-
node-version: '22.14.0'
28+
node-version-file: '.nvmrc'
2929
cache: 'npm'
3030

3131
- name: Set up build environment

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ build/*
77
dist/*.LICENSE.txt
88
dist/*.css
99

10+
# Ignore local dev mocks/baselines
11+
test/image/**/dev_*.*
12+
1013
npm-debug.log*
1114
*.sublime*
1215
*~
@@ -16,3 +19,4 @@ tags
1619
!.github/
1720
!.gitignore
1821
!.npmignore
22+
!.nvmrc

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
22.23.0

CHANGELOG.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,54 @@ To see all merged commits on the master branch that will be part of the next plo
99

1010
where X.Y.Z is the semver of most recent plotly.js release.
1111

12+
## [4.0.0-rc.0] -- 2026-07-21
13+
14+
### Added
15+
- Add `minscale`, `maxscale` geo plot attributes [[#7371](https://github.com/plotly/plotly.js/pull/7371)], with thanks to @mojoaxel for the contribution!
16+
- Enable TypeScript compatibility within the library and start exporting types [[#7680](https://github.com/plotly/plotly.js/pull/7680)]
17+
- Add `quiver` trace type to visualize vector fields using arrows [[#7710](https://github.com/plotly/plotly.js/pull/7710)], with thanks to @degzhaus for the contribution!
18+
- Use dashed markers in legend for shape traces with dash configured [[#7845](https://github.com/plotly/plotly.js/pull/7845)]
19+
- Add `sort` option to Sankey links and nodes [[#7873](https://github.com/plotly/plotly.js/pull/7873)], with thanks to @adamreeve for the contribution!
20+
- Add support for MathJax v4 [[#7898](https://github.com/plotly/plotly.js/pull/7898)]
21+
22+
### Removed
23+
- **Breaking**: Remove `scattermapbox`, `choroplethmapbox`, `densitymapbox` trace types, the `mapbox` subplot, and the `mapboxAccessToken` config option [[#7860](https://github.com/plotly/plotly.js/pull/7860)]
24+
- These traces have been deprecated since v3. Use the equivalent `*map` traces going forward.
25+
- **Breaking**: Drop support for MathJax v2 [[#7898](https://github.com/plotly/plotly.js/pull/7898)]
26+
- MathJax v3 and v4 are now supported in plotly.js
27+
- Remove config attributes `showLink`, `linkText`, `sendData`, `showSources`, and `showEditInChartStudio`, as well as trace attribute `stream`, since all of these were associated with Chart Studio and are no longer needed [[#7812](https://github.com/plotly/plotly.js/pull/7812)]
28+
- Remove all `*src` attributes, as well as `layout.hidesources` attribute, from the schema [[#7829](https://github.com/plotly/plotly.js/pull/7829)]
29+
- Remove internal `trace._fullInput` property and other dead code related to the removed `transforms` feature. No user-facing changes expected [[#7834](https://github.com/plotly/plotly.js/pull/7834)]
30+
31+
### Changed
32+
- **Breaking**: Switch color processing library from [TinyColor](https://github.com/bgrins/TinyColor) to [color](https://github.com/Qix-/color) [[#7536](https://github.com/plotly/plotly.js/pull/7536)]
33+
- `rgb()`/`rgba()` strings with decimal 0–1 fractions are no longer supported
34+
- `hsv()` color strings are no longer permitted
35+
- Color calculations may differ slightly (by a few RGB units)
36+
- New color formats are now supported: '#ff0000aa', '#f00a', 'rgb(255 0 0)', 'rgba(255 0 0 / 0.5)', 'hsl(0 100% 50% / 0.5)', 'hsla(0, 100%, 50%, 0.5)', 'hwb(0, 0%, 0%)'
37+
- **Breaking**: Set default `layout.axis.tickmode` to `'sync'` when axis is overlaying [[#7684](https://github.com/plotly/plotly.js/pull/7684)]
38+
- **Breaking**: Change `splom.axis.matches` default from `false` to `true` [[#7843](https://github.com/plotly/plotly.js/pull/7843)]
39+
- **Breaking**: Replace `country-regex` with `country-iso-search` to search for country names in choropleth, scattergeo traces [[#7856](https://github.com/plotly/plotly.js/pull/7856)]
40+
- The vast majority of country names are handled exactly the same with the new library; a small number of legacy entries have been removed
41+
- **Breaking**: Update minimum required Node version to 22 [[#7861](https://github.com/plotly/plotly.js/pull/7861)]
42+
- **Breaking:** Change `layout.geo.fitbounds` default from `false` to `'locations'` [[#7895](https://github.com/plotly/plotly.js/pull/7895)]
43+
- `geo` subplots will now auto-fit the initial view to the trace data
44+
- Set `fitbounds: false` explicitly to opt out
45+
- Enable `scattermap` icons to render in color, upgrade Maki icons version to 8.2, and standardize scattermap legend icons to circles [[#7825](https://github.com/plotly/plotly.js/pull/7825)]
46+
- Use plot title as default filename for "Download plot" button [[#7828](https://github.com/plotly/plotly.js/pull/7828)]
47+
- Change signature of `plots.graphJson()` function to remove `mode` argument [[#7829](https://github.com/plotly/plotly.js/pull/7829)]
48+
- Upgrade `plotly/d3-sankey` to 0.12.3. [[#7830](https://github.com/plotly/plotly.js/pull/7830)], with thanks to @adamreeve for the contribution!
49+
- Update `plot_config` to show the "Upload to Cloud" button by default, and set the default server URL to cloud.plotly.com via [[#7909](https://github.com/plotly/plotly.js/pull/7909)]
50+
51+
### Fixed
52+
- Fix `histogram` autobin size for single-point traces in `overlay` mode on data updates via `Plotly.react` [[#7507](https://github.com/plotly/plotly.js/pull/7507)], with thanks to @Lexachoc for the contribution!
53+
- Format tick labels correctly for small numbers in exponential notation [[#7768](https://github.com/plotly/plotly.js/pull/7768)], with thanks to @Hasnaathussain for the contribution!
54+
- Fix crash when ordering categories by value (e.g. `sum descending`) with `null` coordinates [[#7855](https://github.com/plotly/plotly.js/pull/7855)]
55+
- Fix `scattermap`, `densitymap` traces not showing all points by dynamically computing `center`, `zoom` values [[#7884](https://github.com/plotly/plotly.js/pull/7884), [#7913](https://github.com/plotly/plotly.js/pull/7913)], with thanks to @palmerusaf and @DhruvGarg111 for the contributions!
56+
- Fix GeoJSON bounding-box computation for `choropleth` and `scattergeo` traces whose geometry crosses the antimeridian [[#7891](https://github.com/plotly/plotly.js/pull/7891)]
57+
- Snap cartesian axis tick values to multiple of delta so custom `tickformat` (e.g. `"~r"`) no longer shows floating-point artifacts [[#7901](https://github.com/plotly/plotly.js/pull/7901)], with thanks to @arieleli01212 and @kirthi-b for the contribution!
58+
59+
1260
## [3.7.0] -- 2026-07-03
1361

1462
### Changed

CONTRIBUTING.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ but the general idea is to be nice.
1414

1515
## Plotly.js vs Plotly.py and Plotly.R
1616

17-
[Plotly.js](https://plotly.com/javascript) is a standalone Javascript data visualization library, and it also powers the Python and R modules named `plotly` in those respective ecosystems (referred to as [Plotly.py](https://plotly.com/python) and [Plotly.R](http://plotly.com/r), respectively, for clarity). There also exist Plotly.js-powered libraries for other languages such as Julia, Scala, Rust, .NET and even C++!
17+
[Plotly.js](https://plotly.com/javascript) is a standalone Javascript data visualization library, and it also powers the Python and R modules named `plotly` in those respective ecosystems (referred to as [Plotly.py](https://plotly.com/python) and [Plotly.R](https://plotly.com/r), respectively, for clarity). There also exist Plotly.js-powered libraries for other languages such as Julia, Scala, Rust, .NET and even C++!
1818

1919
The basic architecture of Plotly.js is to accept [JSON](https://json.org/) representation of figures that adhere to the [figure schema](https://plotly.com/javascript/reference/index/) and draw interactive graphical representations of these figures in a browser. Libraries in other languages like Python and R provide idiomatic interfaces for users of those languages to create and manipulate these JSON structures, and arrange for them to be rendered in a browser context by Plotly.js. This means that in many cases, when a Python or R user wishes to add a feature to the library they know as `plotly`, the relevant changes must be implemented in Plotly.js, in this repo.
2020

@@ -78,7 +78,7 @@ We use the following [labels](https://github.com/plotly/plotly.js/labels) to tra
7878
#### Prerequisites
7979

8080
- git
81-
- [node.js](https://nodejs.org/en/). We recommend using node.js v18.x.
81+
- [node.js](https://nodejs.org/en/). We recommend using node.js v22.x.
8282
Upgrading and managing node versions can be easily done using
8383
[`nvm`](https://github.com/nvm-sh/nvm) or its Windows alternatives.
8484
- [`npm`](https://www.npmjs.com/) v10.x and up to ensure that the
@@ -405,8 +405,10 @@ All traces modules set:
405405
This object is used to generate the plot-schema JSON.
406406
- `_module.supplyDefaults`: Takes in input trace settings and coerces them into "full" settings
407407
under `gd._fullData`. This one is called during the figure-wide `Plots.supplyDefaults` routine.
408-
Note that the `supplyDefaults` method performance should scale with the number of attributes (**not** the
409-
number of data points - so it should not loop over any data arrays).
408+
As a rule, `supplyDefaults` performance should scale with the number of attributes rather than
409+
the number of data points, so avoid looping over data arrays in this function. That being said,
410+
there are a few exceptions to this rule due to technical requirements (`fitbounds` on map subplots).
411+
The same guidance applies to `_module.supplyLayoutDefaults`.
410412
- `_module.calc`: Converts inputs data into "calculated" (or sanitized) data. This one is called during
411413
the figure-wide `Plots.doCalcdata` routine. The `calc` method is allowed to
412414
scale with the number of data points and is in general more costly than `supplyDefaults`.
@@ -432,7 +434,7 @@ Other methods used by some trace modules:
432434
selections.
433435
- `_module.convert`: Sometimes separated from `_module.plot` or `_module.calc` to convert the
434436
plotly.js settings to another framework e.g. to `gl-plot3d` for `gl3d` traces, to
435-
`mapbox-gl` for `mapbox` traces. This split can make the logic easier to test.
437+
`maplibre-gl` for `map` traces. This split can make the logic easier to test.
436438
If you make a `convert`, you should call it from either `calc` or `plot`.
437439

438440
## Coding style

CUSTOM_BUNDLE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ Make sure you have the versions of node/npm that's recommended:
55
- plotly.js before 2.5: Node 12/npm 6
66
- plotly.js from 2.5: Node 16/npm 8
77
- plotly.js from 2.35: Node 18/npm 10
8+
- plotly.js from 4.0: Node 22/npm 10
89

9-
To download a specific node version look [here](https://nodejs.org/en/download/package-manager).
10+
To download a specific node version look [here](https://nodejs.org/en/download).
1011

1112
Note: For CI, it's faster to do `git clone --depth 1` to only get one commit.
1213

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,23 @@ While non-minified source files may contain characters outside UTF-8, it is reco
9595
> Please note that as of v2 the "plotly-latest" outputs (e.g. https://cdn.plot.ly/plotly-latest.min.js) will no longer be updated on the CDN, and will stay at the last v1 patch v1.58.5. Therefore, to use the CDN with plotly.js v2 and higher, you must specify an exact plotly.js version.
9696
9797
### MathJax
98-
You can load either version two or version three of MathJax files. For example:
98+
plotly.js supports using MathJax v3 or v4 to render mathematical expressions within plots.
99+
100+
MathJax is not included in the plotly.js bundle, so it must be loaded separately as a script on the webpage.
101+
102+
For MathJax v4:
99103
```html
100-
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_SVG.js"></script>
104+
<script src="https://cdn.jsdelivr.net/npm/mathjax@4.1.3/tex-svg.js"></script>
101105
```
102106

107+
For MathJax v3:
103108
```html
104109
<script src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js"></script>
105110
```
106111

107-
> When using MathJax version 3, it is also possible to use `chtml` output on the other parts of the page in addition to `svg` output for the plotly graph.
108-
Please refer to `devtools/test_dashboard/index-mathjax3chtml.html` to see an example.
112+
When MathJax is available, any string contained within `$..$` signs will be rendered using the MathJax engine. This applies to plot titles, axis labels, tick label text, and annotations.
113+
114+
plotly.js's use of the MathJax `svg` renderer should not prevent using other MathJax renderers elsewhere on the page, nor will it affect the global MathJax config. See `devtools/test_dashboard/index-mathjax3chtml.html` for an example of a webpage which uses the MathJax `chtml` renderer in the main page, and also displays Plotly charts containing MathJax equations rendered as `svg`.
109115

110116
### Need to have several WebGL graphs on a page?
111117
You may simply load the [virtual-webgl](https://github.com/greggman/virtual-webgl) script for WebGL 1 (not WebGL 2) before loading other scripts.

build/plotcss.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,20 @@ var rules = {
5454
"X .plotly-cloud-dialog .plotly-cloud-dialog-box": "box-sizing:border-box;min-width:300px;max-width:420px;padding:20px 24px;background-color:#fff;border:1px solid #e0e2e5;border-radius:4px;box-shadow:0 4px 16px rgba(0,0,0,.25);font-size:13px;color:#2a3f5f;",
5555
"X .plotly-cloud-dialog .plotly-cloud-dialog-title": "font-size:16px;font-weight:bold;margin-bottom:12px;",
5656
"X .plotly-cloud-dialog .plotly-cloud-dialog-message": "line-height:1.5;overflow-wrap:break-word;word-wrap:break-word;",
57+
"X .plotly-cloud-dialog .plotly-cloud-dialog-message--hostname": "font-weight:bold;",
5758
"X .plotly-cloud-dialog .plotly-cloud-dialog-label": "display:block;margin-top:16px;margin-bottom:6px;font-weight:bold;",
5859
"X .plotly-cloud-dialog .plotly-cloud-dialog-input": "box-sizing:border-box;width:100%;padding:7px 10px;font-family:inherit;font-size:13px;color:#2a3f5f;background-color:#fff;border:1px solid #e0e2e5;border-radius:3px;",
5960
"X .plotly-cloud-dialog .plotly-cloud-dialog-input:focus": "outline:none;border-color:#447adb;",
6061
"X .plotly-cloud-dialog .plotly-cloud-dialog-error": "margin-top:6px;color:#db44a5;",
6162
"X .plotly-cloud-dialog .plotly-cloud-dialog-buttons": "display:flex;justify-content:flex-end;margin-top:20px;",
6263
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn": "font-family:inherit;font-size:13px;padding:7px 16px;margin-left:8px;border-radius:3px;border:1px solid rgba(0,0,0,0);cursor:pointer;",
6364
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn:focus-visible": "outline:2px solid #447adb;outline-offset:1px;",
64-
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn--cancel": "background-color:#fff;border-color:#e0e2e5;color:#777;",
65-
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn--cancel:hover": "background-color:#f3f3f3;",
65+
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn.plotly-cloud-dialog-btn--cancel,X .plotly-cloud-dialog .plotly-cloud-dialog-btn--cancel": "background-color:#f3f3f3;margin-left:auto;color:#777;",
66+
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn.plotly-cloud-dialog-btn--cancel:hover,X .plotly-cloud-dialog .plotly-cloud-dialog-btn--cancel:hover": "background-color:#e0e2e5;",
67+
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn.plotly-cloud-dialog-btn--confirm": "background-color:#447adb;color:#fff;",
68+
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn.plotly-cloud-dialog-btn--confirm:hover": "background-color:#1d3b84;",
69+
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn.plotly-cloud-dialog-btn--custom": "background-color:#fff;color:#777;font-size:11px;padding-left:0;margin-left:0;",
70+
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn.plotly-cloud-dialog-btn--custom:hover": "text-decoration:underline;",
6671
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn--confirm": "background-color:#447adb;color:#fff;",
6772
"X .plotly-cloud-dialog .plotly-cloud-dialog-btn--confirm:hover": "background-color:#1d3b84;",
6873
Y: "font-family:\"Open Sans\",verdana,arial,sans-serif;position:fixed;top:50px;right:20px;z-index:10000;font-size:10pt;max-width:180px;",

0 commit comments

Comments
 (0)