From 7e42d19df4be0bcdd4d6a74637f1c76ab554f4b3 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Mon, 14 Sep 2026 15:27:41 -0600 Subject: [PATCH 1/4] chore: Convert constants files to TS --- src/components/colorbar/constants.js | 18 --- src/components/colorbar/constants.ts | 14 ++ src/components/fx/constants.js | 22 --- src/components/fx/constants.ts | 18 +++ src/components/legend/constants.js | 14 -- src/components/legend/constants.ts | 10 ++ src/components/rangeselector/constants.js | 19 --- src/components/rangeselector/constants.ts | 13 ++ src/components/rangeslider/constants.js | 46 ------ src/components/rangeslider/constants.ts | 41 +++++ src/components/selections/constants.js | 15 -- src/components/selections/constants.ts | 11 ++ src/components/shapes/constants.js | 53 ------- src/components/shapes/constants.ts | 57 +++++++ .../shapes/draw_newshape/constants.js | 14 -- .../shapes/draw_newshape/constants.ts | 10 ++ src/components/sliders/constants.js | 83 ---------- src/components/sliders/constants.ts | 77 +++++++++ src/components/updatemenus/constants.js | 70 -------- src/components/updatemenus/constants.ts | 66 ++++++++ src/constants/alignment.js | 55 ------- src/constants/alignment.ts | 64 ++++++++ src/constants/axis_placeable_objects.js | 21 --- src/constants/axis_placeable_objects.ts | 22 +++ src/constants/delta.js | 12 -- src/constants/delta.ts | 9 ++ src/constants/docs.js | 6 - src/constants/docs.ts | 2 + src/constants/filter_ops.js | 28 ---- src/constants/filter_ops.ts | 23 +++ src/constants/gl3d_dashes.js | 10 -- src/constants/gl3d_dashes.ts | 15 ++ .../{gl3d_markers.js => gl3d_markers.ts} | 8 +- src/constants/interactions.js | 13 -- src/constants/interactions.ts | 8 + src/constants/numerical.js | 64 -------- src/constants/numerical.ts | 60 +++++++ ...{pixelated_image.js => pixelated_image.ts} | 10 +- src/constants/xmlns_namespaces.js | 13 -- src/constants/xmlns_namespaces.ts | 10 ++ src/plots/cartesian/constants.js | 72 --------- src/plots/cartesian/constants.ts | 78 +++++++++ src/plots/geo/{constants.js => constants.ts} | 150 ++++++++++++------ src/plots/polar/constants.js | 35 ---- src/plots/polar/constants.ts | 35 ++++ src/plots/smith/constants.js | 12 -- src/plots/smith/constants.ts | 13 ++ src/traces/bar/constants.js | 11 -- src/traces/bar/constants.ts | 8 + src/traces/carpet/constants.js | 5 - src/traces/carpet/constants.ts | 1 + src/traces/contour/constants.js | 68 -------- src/traces/contour/constants.ts | 65 ++++++++ src/traces/funnel/constants.js | 9 -- src/traces/funnel/constants.ts | 5 + src/traces/histogram/constants.js | 5 - src/traces/histogram/constants.ts | 1 + src/traces/image/constants.js | 51 ------ src/traces/image/constants.ts | 66 ++++++++ src/traces/indicator/constants.js | 12 -- src/traces/indicator/constants.ts | 8 + src/traces/parcoords/constants.js | 50 ------ src/traces/parcoords/constants.ts | 47 ++++++ src/traces/sankey/constants.js | 21 --- src/traces/sankey/constants.ts | 18 +++ src/traces/scatter/constants.js | 18 --- src/traces/scatter/constants.ts | 14 ++ src/traces/scattergl/constants.js | 23 --- src/traces/scattergl/constants.ts | 19 +++ .../scattermap/{constants.js => constants.ts} | 20 +-- src/traces/sunburst/constants.js | 18 --- src/traces/sunburst/constants.ts | 15 ++ src/traces/table/constants.js | 50 ------ src/traces/table/constants.ts | 47 ++++++ src/traces/treemap/constants.js | 19 --- src/traces/treemap/constants.ts | 17 ++ src/traces/waterfall/constants.js | 9 -- src/traces/waterfall/constants.ts | 5 + 78 files changed, 1113 insertions(+), 1131 deletions(-) delete mode 100644 src/components/colorbar/constants.js create mode 100644 src/components/colorbar/constants.ts delete mode 100644 src/components/fx/constants.js create mode 100644 src/components/fx/constants.ts delete mode 100644 src/components/legend/constants.js create mode 100644 src/components/legend/constants.ts delete mode 100644 src/components/rangeselector/constants.js create mode 100644 src/components/rangeselector/constants.ts delete mode 100644 src/components/rangeslider/constants.js create mode 100644 src/components/rangeslider/constants.ts delete mode 100644 src/components/selections/constants.js create mode 100644 src/components/selections/constants.ts delete mode 100644 src/components/shapes/constants.js create mode 100644 src/components/shapes/constants.ts delete mode 100644 src/components/shapes/draw_newshape/constants.js create mode 100644 src/components/shapes/draw_newshape/constants.ts delete mode 100644 src/components/sliders/constants.js create mode 100644 src/components/sliders/constants.ts delete mode 100644 src/components/updatemenus/constants.js create mode 100644 src/components/updatemenus/constants.ts delete mode 100644 src/constants/alignment.js create mode 100644 src/constants/alignment.ts delete mode 100644 src/constants/axis_placeable_objects.js create mode 100644 src/constants/axis_placeable_objects.ts delete mode 100644 src/constants/delta.js create mode 100644 src/constants/delta.ts delete mode 100644 src/constants/docs.js create mode 100644 src/constants/docs.ts delete mode 100644 src/constants/filter_ops.js create mode 100644 src/constants/filter_ops.ts delete mode 100644 src/constants/gl3d_dashes.js create mode 100644 src/constants/gl3d_dashes.ts rename src/constants/{gl3d_markers.js => gl3d_markers.ts} (65%) delete mode 100644 src/constants/interactions.js create mode 100644 src/constants/interactions.ts delete mode 100644 src/constants/numerical.js create mode 100644 src/constants/numerical.ts rename src/constants/{pixelated_image.js => pixelated_image.ts} (80%) delete mode 100644 src/constants/xmlns_namespaces.js create mode 100644 src/constants/xmlns_namespaces.ts delete mode 100644 src/plots/cartesian/constants.js create mode 100644 src/plots/cartesian/constants.ts rename src/plots/geo/{constants.js => constants.ts} (63%) delete mode 100644 src/plots/polar/constants.js create mode 100644 src/plots/polar/constants.ts delete mode 100644 src/plots/smith/constants.js create mode 100644 src/plots/smith/constants.ts delete mode 100644 src/traces/bar/constants.js create mode 100644 src/traces/bar/constants.ts delete mode 100644 src/traces/carpet/constants.js create mode 100644 src/traces/carpet/constants.ts delete mode 100644 src/traces/contour/constants.js create mode 100644 src/traces/contour/constants.ts delete mode 100644 src/traces/funnel/constants.js create mode 100644 src/traces/funnel/constants.ts delete mode 100644 src/traces/histogram/constants.js create mode 100644 src/traces/histogram/constants.ts delete mode 100644 src/traces/image/constants.js create mode 100644 src/traces/image/constants.ts delete mode 100644 src/traces/indicator/constants.js create mode 100644 src/traces/indicator/constants.ts delete mode 100644 src/traces/parcoords/constants.js create mode 100644 src/traces/parcoords/constants.ts delete mode 100644 src/traces/sankey/constants.js create mode 100644 src/traces/sankey/constants.ts delete mode 100644 src/traces/scatter/constants.js create mode 100644 src/traces/scatter/constants.ts delete mode 100644 src/traces/scattergl/constants.js create mode 100644 src/traces/scattergl/constants.ts rename src/traces/scattermap/{constants.js => constants.ts} (77%) delete mode 100644 src/traces/sunburst/constants.js create mode 100644 src/traces/sunburst/constants.ts delete mode 100644 src/traces/table/constants.js create mode 100644 src/traces/table/constants.ts delete mode 100644 src/traces/treemap/constants.js create mode 100644 src/traces/treemap/constants.ts delete mode 100644 src/traces/waterfall/constants.js create mode 100644 src/traces/waterfall/constants.ts diff --git a/src/components/colorbar/constants.js b/src/components/colorbar/constants.js deleted file mode 100644 index 593ba31a2c3..00000000000 --- a/src/components/colorbar/constants.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -module.exports = { - cn: { - colorbar: 'colorbar', - cbbg: 'cbbg', - cbfill: 'cbfill', - cbfills: 'cbfills', - cbline: 'cbline', - cblines: 'cblines', - cbaxis: 'cbaxis', - cbtitleunshift: 'cbtitleunshift', - cbtitle: 'cbtitle', - cboutline: 'cboutline', - crisp: 'crisp', - jsPlaceholder: 'js-placeholder' - } -}; diff --git a/src/components/colorbar/constants.ts b/src/components/colorbar/constants.ts new file mode 100644 index 00000000000..5a799425ae4 --- /dev/null +++ b/src/components/colorbar/constants.ts @@ -0,0 +1,14 @@ +export const cn = { + colorbar: 'colorbar', + cbbg: 'cbbg', + cbfill: 'cbfill', + cbfills: 'cbfills', + cbline: 'cbline', + cblines: 'cblines', + cbaxis: 'cbaxis', + cbtitleunshift: 'cbtitleunshift', + cbtitle: 'cbtitle', + cboutline: 'cboutline', + crisp: 'crisp', + jsPlaceholder: 'js-placeholder' +} as const; diff --git a/src/components/fx/constants.js b/src/components/fx/constants.js deleted file mode 100644 index 0658a3adc57..00000000000 --- a/src/components/fx/constants.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -module.exports = { - // hover labels for multiple horizontal bars get tilted by this angle - YANGLE: 60, - - // size and display constants for hover text - - // pixel size of hover arrows - HOVERARROWSIZE: 6, - // pixels padding around text - HOVERTEXTPAD: 3, - // hover font - HOVERFONTSIZE: 13, - HOVERFONT: 'Arial, sans-serif', - - // minimum time (msec) between hover calls - HOVERMINTIME: 50, - - // ID suffix (with fullLayout._uid) for hover events in the throttle cache - HOVERID: '-hover' -}; diff --git a/src/components/fx/constants.ts b/src/components/fx/constants.ts new file mode 100644 index 00000000000..6ad811d9a0c --- /dev/null +++ b/src/components/fx/constants.ts @@ -0,0 +1,18 @@ +// Hover labels for multiple horizontal bars get tilted by this angle +export const YANGLE = 60; + +// Size and display constants for hover text + +// Pixel size of hover arrows +export const HOVERARROWSIZE = 6; +// Pixels padding around text +export const HOVERTEXTPAD = 3; +// Hover font +export const HOVERFONTSIZE = 13; +export const HOVERFONT = 'Arial, sans-serif'; + +// Minimum time (msec) between hover calls +export const HOVERMINTIME = 50; + +// ID suffix (with fullLayout._uid) for hover events in the throttle cache +export const HOVERID = '-hover'; diff --git a/src/components/legend/constants.js b/src/components/legend/constants.js deleted file mode 100644 index b5b4264de39..00000000000 --- a/src/components/legend/constants.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -module.exports = { - scrollBarWidth: 6, - scrollBarMinHeight: 20, - scrollBarColor: '#808BA4', - scrollBarMargin: 4, - scrollBarEnterAttrs: {rx: 20, ry: 3, width: 0, height: 0}, - - // number of px between legend title and (left) side of legend (always in x direction and from inner border) - titlePad: 2, - // number of px between each legend item (x and/or y direction) - itemGap: 5 -}; diff --git a/src/components/legend/constants.ts b/src/components/legend/constants.ts new file mode 100644 index 00000000000..6b950ac03d3 --- /dev/null +++ b/src/components/legend/constants.ts @@ -0,0 +1,10 @@ +export const scrollBarWidth = 6; +export const scrollBarMinHeight = 20; +export const scrollBarColor = '#808BA4'; +export const scrollBarMargin = 4; +export const scrollBarEnterAttrs = { rx: 20, ry: 3, width: 0, height: 0 } as const; + +// Number of px between legend title and (left) side of legend (always in x direction and from inner border) +export const titlePad = 2; +// Number of px between each legend item (x and/or y direction) +export const itemGap = 5; diff --git a/src/components/rangeselector/constants.js b/src/components/rangeselector/constants.js deleted file mode 100644 index 88f7b2e9cda..00000000000 --- a/src/components/rangeselector/constants.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - - -module.exports = { - - // 'y' position pad above counter axis domain - yPad: 0.02, - - // minimum button width (regardless of text size) - minButtonWidth: 30, - - // buttons rect radii - rx: 3, - ry: 3, - - // light fraction used to compute the 'activecolor' default - lightAmount: 25, - darkAmount: 10 -}; diff --git a/src/components/rangeselector/constants.ts b/src/components/rangeselector/constants.ts new file mode 100644 index 00000000000..53e2c7f8169 --- /dev/null +++ b/src/components/rangeselector/constants.ts @@ -0,0 +1,13 @@ +// 'y' position pad above counter axis domain +export const yPad = 0.02; + +// Minimum button width (regardless of text size) +export const minButtonWidth = 30; + +// Buttons rect radii +export const rx = 3; +export const ry = 3; + +// Light fraction used to compute the 'activecolor' default +export const lightAmount = 25; +export const darkAmount = 10; diff --git a/src/components/rangeslider/constants.js b/src/components/rangeslider/constants.js deleted file mode 100644 index c819ec21582..00000000000 --- a/src/components/rangeslider/constants.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -module.exports = { - - // attribute container name - name: 'rangeslider', - - // class names - - containerClassName: 'rangeslider-container', - bgClassName: 'rangeslider-bg', - rangePlotClassName: 'rangeslider-rangeplot', - - maskMinClassName: 'rangeslider-mask-min', - maskMaxClassName: 'rangeslider-mask-max', - slideBoxClassName: 'rangeslider-slidebox', - - grabberMinClassName: 'rangeslider-grabber-min', - grabAreaMinClassName: 'rangeslider-grabarea-min', - handleMinClassName: 'rangeslider-handle-min', - - grabberMaxClassName: 'rangeslider-grabber-max', - grabAreaMaxClassName: 'rangeslider-grabarea-max', - handleMaxClassName: 'rangeslider-handle-max', - - maskMinOppAxisClassName: 'rangeslider-mask-min-opp-axis', - maskMaxOppAxisClassName: 'rangeslider-mask-max-opp-axis', - - // style constants - - maskColor: 'rgba(0,0,0,0.4)', - maskOppAxisColor: 'rgba(0,0,0,0.2)', - - slideBoxFill: 'transparent', - slideBoxCursor: 'ew-resize', - - grabAreaFill: 'transparent', - grabAreaCursor: 'col-resize', - grabAreaWidth: 10, - - handleWidth: 4, - handleRadius: 1, - handleStrokeWidth: 1, - - extraPad: 15 -}; diff --git a/src/components/rangeslider/constants.ts b/src/components/rangeslider/constants.ts new file mode 100644 index 00000000000..1866163342b --- /dev/null +++ b/src/components/rangeslider/constants.ts @@ -0,0 +1,41 @@ +// Attribute container name +export const name = 'rangeslider'; + +// Class names + +export const containerClassName = 'rangeslider-container'; +export const bgClassName = 'rangeslider-bg'; +export const rangePlotClassName = 'rangeslider-rangeplot'; + +export const maskMinClassName = 'rangeslider-mask-min'; +export const maskMaxClassName = 'rangeslider-mask-max'; +export const slideBoxClassName = 'rangeslider-slidebox'; + +export const grabberMinClassName = 'rangeslider-grabber-min'; +export const grabAreaMinClassName = 'rangeslider-grabarea-min'; +export const handleMinClassName = 'rangeslider-handle-min'; + +export const grabberMaxClassName = 'rangeslider-grabber-max'; +export const grabAreaMaxClassName = 'rangeslider-grabarea-max'; +export const handleMaxClassName = 'rangeslider-handle-max'; + +export const maskMinOppAxisClassName = 'rangeslider-mask-min-opp-axis'; +export const maskMaxOppAxisClassName = 'rangeslider-mask-max-opp-axis'; + +// Style constants + +export const maskColor = 'rgba(0,0,0,0.4)'; +export const maskOppAxisColor = 'rgba(0,0,0,0.2)'; + +export const slideBoxFill = 'transparent'; +export const slideBoxCursor = 'ew-resize'; + +export const grabAreaFill = 'transparent'; +export const grabAreaCursor = 'col-resize'; +export const grabAreaWidth = 10; + +export const handleWidth = 4; +export const handleRadius = 1; +export const handleStrokeWidth = 1; + +export const extraPad = 15; diff --git a/src/components/selections/constants.js b/src/components/selections/constants.js deleted file mode 100644 index eec3d375259..00000000000 --- a/src/components/selections/constants.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -module.exports = { - // max pixels off straight before a lasso select line counts as bent - BENDPX: 1.5, - - // smallest dimension allowed for a select box - MINSELECT: 12, - - // throttling limit (ms) for selectPoints calls - SELECTDELAY: 100, - - // cache ID suffix for throttle - SELECTID: '-select', -}; diff --git a/src/components/selections/constants.ts b/src/components/selections/constants.ts new file mode 100644 index 00000000000..1fd9cf8cb58 --- /dev/null +++ b/src/components/selections/constants.ts @@ -0,0 +1,11 @@ +// Max pixels off straight before a lasso select line counts as bent +export const BENDPX = 1.5; + +// Smallest dimension allowed for a select box +export const MINSELECT = 12; + +// Throttling limit (ms) for selectPoints calls +export const SELECTDELAY = 100; + +// Cache ID suffix for throttle +export const SELECTID = '-select'; diff --git a/src/components/shapes/constants.js b/src/components/shapes/constants.js deleted file mode 100644 index 1a9b392f11a..00000000000 --- a/src/components/shapes/constants.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - - -module.exports = { - segmentRE: /[MLHVQCTSZ][^MLHVQCTSZ]*/g, - paramRE: /[^\s,]+/g, - - // which numbers in each path segment are x (or y) values - // drawn is which param is a drawn point, as opposed to a - // control point (which doesn't count toward autorange. - // TODO: this means curved paths could extend beyond the - // autorange bounds. This is a bit tricky to get right - // unless we revert to bounding boxes, but perhaps there's - // a calculation we could do...) - paramIsX: { - M: {0: true, drawn: 0}, - L: {0: true, drawn: 0}, - H: {0: true, drawn: 0}, - V: {}, - Q: {0: true, 2: true, drawn: 2}, - C: {0: true, 2: true, 4: true, drawn: 4}, - T: {0: true, drawn: 0}, - S: {0: true, 2: true, drawn: 2}, - // A: {0: true, 5: true}, - Z: {} - }, - - paramIsY: { - M: {1: true, drawn: 1}, - L: {1: true, drawn: 1}, - H: {}, - V: {0: true, drawn: 0}, - Q: {1: true, 3: true, drawn: 3}, - C: {1: true, 3: true, 5: true, drawn: 5}, - T: {1: true, drawn: 1}, - S: {1: true, 3: true, drawn: 3}, - // A: {1: true, 6: true}, - Z: {} - }, - - numParams: { - M: 2, - L: 2, - H: 1, - V: 1, - Q: 4, - C: 6, - T: 2, - S: 4, - // A: 7, - Z: 0 - } -}; diff --git a/src/components/shapes/constants.ts b/src/components/shapes/constants.ts new file mode 100644 index 00000000000..3de4185f59b --- /dev/null +++ b/src/components/shapes/constants.ts @@ -0,0 +1,57 @@ +export const segmentRE = /[MLHVQCTSZ][^MLHVQCTSZ]*/g; +export const paramRE = /[^\s,]+/g; + +/** + * Flags for one SVG path command: which numeric params are coordinates, plus + * `drawn`, the index of the param that is a drawn point + */ +type PathParams = Record; + +// Which numbers in each path segment are x (or y) values +// drawn is which param is a drawn point, as opposed to a +// control point (which doesn't count toward autorange. +// TODO: this means curved paths could extend beyond the +// autorange bounds. This is a bit tricky to get right +// unless we revert to bounding boxes, but perhaps there's +// a calculation we could do...) +export const paramIsX = { + M: { 0: true, drawn: 0 }, + L: { 0: true, drawn: 0 }, + H: { 0: true, drawn: 0 }, + V: {}, + Q: { 0: true, 2: true, drawn: 2 }, + C: { 0: true, 2: true, 4: true, drawn: 4 }, + T: { 0: true, drawn: 0 }, + S: { 0: true, 2: true, drawn: 2 }, + // A: {0: true, 5: true}, + Z: {} +} as const satisfies Record; + +export const paramIsY = { + M: { 1: true, drawn: 1 }, + L: { 1: true, drawn: 1 }, + H: {}, + V: { 0: true, drawn: 0 }, + Q: { 1: true, 3: true, drawn: 3 }, + C: { 1: true, 3: true, 5: true, drawn: 5 }, + T: { 1: true, drawn: 1 }, + S: { 1: true, 3: true, drawn: 3 }, + // A: {1: true, 6: true}, + Z: {} +} as const satisfies Record; + +export const numParams = { + M: 2, + L: 2, + H: 1, + V: 1, + Q: 4, + C: 6, + T: 2, + S: 4, + // A: 7, + Z: 0 +} as const; + +/** One SVG path command letter, such as `M` or `C` */ +export type PathCommand = keyof typeof numParams; diff --git a/src/components/shapes/draw_newshape/constants.js b/src/components/shapes/draw_newshape/constants.js deleted file mode 100644 index 28e282eaa67..00000000000 --- a/src/components/shapes/draw_newshape/constants.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -var CIRCLE_SIDES = 32; // should be divisible by 4 - -module.exports = { - CIRCLE_SIDES: CIRCLE_SIDES, - i000: 0, - i090: CIRCLE_SIDES / 4, - i180: CIRCLE_SIDES / 2, - i270: CIRCLE_SIDES / 4 * 3, - cos45: Math.cos(Math.PI / 4), - sin45: Math.sin(Math.PI / 4), - SQRT2: Math.sqrt(2) -}; diff --git a/src/components/shapes/draw_newshape/constants.ts b/src/components/shapes/draw_newshape/constants.ts new file mode 100644 index 00000000000..319eb869f87 --- /dev/null +++ b/src/components/shapes/draw_newshape/constants.ts @@ -0,0 +1,10 @@ +export const CIRCLE_SIDES = 32; // Should be divisible by 4 + +export const i000 = 0; +export const i090 = CIRCLE_SIDES / 4; +export const i180 = CIRCLE_SIDES / 2; +export const i270 = (CIRCLE_SIDES / 4) * 3; + +export const cos45 = Math.cos(Math.PI / 4); +export const sin45 = Math.sin(Math.PI / 4); +export const SQRT2 = Math.sqrt(2); diff --git a/src/components/sliders/constants.js b/src/components/sliders/constants.js deleted file mode 100644 index b8a9660b183..00000000000 --- a/src/components/sliders/constants.js +++ /dev/null @@ -1,83 +0,0 @@ -'use strict'; - - -module.exports = { - - // layout attribute name - name: 'sliders', - - // class names - containerClassName: 'slider-container', - groupClassName: 'slider-group', - inputAreaClass: 'slider-input-area', - railRectClass: 'slider-rail-rect', - railTouchRectClass: 'slider-rail-touch-rect', - gripRectClass: 'slider-grip-rect', - tickRectClass: 'slider-tick-rect', - inputProxyClass: 'slider-input-proxy', - labelsClass: 'slider-labels', - labelGroupClass: 'slider-label-group', - labelClass: 'slider-label', - currentValueClass: 'slider-current-value', - - railHeight: 5, - - // DOM attribute name in button group keeping track - // of active update menu - menuIndexAttrName: 'slider-active-index', - - // id root pass to Plots.autoMargin - autoMarginIdRoot: 'slider-', - - // min item width / height - minWidth: 30, - minHeight: 30, - - // padding around item text - textPadX: 40, - - // arrow offset off right edge - arrowOffsetX: 4, - - railRadius: 2, - railWidth: 5, - railBorder: 4, - railBorderWidth: 1, - railBorderColor: '#bec8d9', - railBgColor: '#f8fafc', - - // The distance of the rail from the edge of the touchable area - // Slightly less than the step inset because of the curved edges - // of the rail - railInset: 8, - - // The distance from the extremal tick marks to the edge of the - // touchable area. This is basically the same as the grip radius, - // but for other styles it wouldn't really need to be. - stepInset: 10, - - gripRadius: 10, - gripWidth: 20, - gripHeight: 20, - gripBorder: 20, - gripBorderWidth: 1, - gripBorderColor: '#bec8d9', - gripBgColor: '#f6f8fa', - gripBgActiveColor: '#dbdde0', - - labelPadding: 8, - labelOffset: 0, - - tickWidth: 1, - tickColor: '#333', - tickOffset: 25, - tickLength: 7, - - minorTickOffset: 25, - minorTickColor: '#333', - minorTickLength: 4, - - // Extra space below the current value label: - currentValuePadding: 8, - currentValueInset: 0, -}; diff --git a/src/components/sliders/constants.ts b/src/components/sliders/constants.ts new file mode 100644 index 00000000000..15fb9768798 --- /dev/null +++ b/src/components/sliders/constants.ts @@ -0,0 +1,77 @@ +// Layout attribute name +export const name = 'sliders'; + +// Class names +export const containerClassName = 'slider-container'; +export const groupClassName = 'slider-group'; +export const inputAreaClass = 'slider-input-area'; +export const railRectClass = 'slider-rail-rect'; +export const railTouchRectClass = 'slider-rail-touch-rect'; +export const gripRectClass = 'slider-grip-rect'; +export const tickRectClass = 'slider-tick-rect'; +export const inputProxyClass = 'slider-input-proxy'; +export const labelsClass = 'slider-labels'; +export const labelGroupClass = 'slider-label-group'; +export const labelClass = 'slider-label'; +export const currentValueClass = 'slider-current-value'; + +export const railHeight = 5; + +// DOM attribute name in button group keeping track +// of active update menu +export const menuIndexAttrName = 'slider-active-index'; + +// ID root pass to Plots.autoMargin +export const autoMarginIdRoot = 'slider-'; + +// Min item width / height +export const minWidth = 30; +export const minHeight = 30; + +// Padding around item text +export const textPadX = 40; + +// Arrow offset off right edge +export const arrowOffsetX = 4; + +export const railRadius = 2; +export const railWidth = 5; +export const railBorder = 4; +export const railBorderWidth = 1; +export const railBorderColor = '#bec8d9'; +export const railBgColor = '#f8fafc'; + +// The distance of the rail from the edge of the touchable area +// Slightly less than the step inset because of the curved edges +// of the rail +export const railInset = 8; + +// The distance from the extremal tick marks to the edge of the +// touchable area. This is basically the same as the grip radius, +// but for other styles it wouldn't really need to be. +export const stepInset = 10; + +export const gripRadius = 10; +export const gripWidth = 20; +export const gripHeight = 20; +export const gripBorder = 20; +export const gripBorderWidth = 1; +export const gripBorderColor = '#bec8d9'; +export const gripBgColor = '#f6f8fa'; +export const gripBgActiveColor = '#dbdde0'; + +export const labelPadding = 8; +export const labelOffset = 0; + +export const tickWidth = 1; +export const tickColor = '#333'; +export const tickOffset = 25; +export const tickLength = 7; + +export const minorTickOffset = 25; +export const minorTickColor = '#333'; +export const minorTickLength = 4; + +// Extra space below the current value label: +export const currentValuePadding = 8; +export const currentValueInset = 0; diff --git a/src/components/updatemenus/constants.js b/src/components/updatemenus/constants.js deleted file mode 100644 index 9fdc76fc011..00000000000 --- a/src/components/updatemenus/constants.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - - -module.exports = { - - // layout attribute name - name: 'updatemenus', - - // class names - containerClassName: 'updatemenu-container', - headerGroupClassName: 'updatemenu-header-group', - headerClassName: 'updatemenu-header', - headerArrowClassName: 'updatemenu-header-arrow', - dropdownButtonGroupClassName: 'updatemenu-dropdown-button-group', - dropdownButtonClassName: 'updatemenu-dropdown-button', - buttonClassName: 'updatemenu-button', - itemRectClassName: 'updatemenu-item-rect', - itemTextClassName: 'updatemenu-item-text', - - // DOM attribute name in button group keeping track - // of active update menu - menuIndexAttrName: 'updatemenu-active-index', - - // id root pass to Plots.autoMargin - autoMarginIdRoot: 'updatemenu-', - - // options when 'active: -1' - blankHeaderOpts: { label: ' ' }, - - // min item width / height - minWidth: 30, - minHeight: 30, - - // padding around item text - textPadX: 24, - arrowPadX: 16, - - // item rect radii - rx: 2, - ry: 2, - - // item text x offset off left edge - textOffsetX: 12, - - // item text y offset (w.r.t. middle) - textOffsetY: 3, - - // arrow offset off right edge - arrowOffsetX: 4, - - // gap between header and buttons - gapButtonHeader: 5, - - // gap between between buttons - gapButton: 2, - - // color given to active buttons - activeColor: '#F4FAFF', - - // color given to hovered buttons - hoverColor: '#F4FAFF', - - // symbol for menu open arrow - arrowSymbol: { - left: '◄', - right: '►', - up: '▲', - down: '▼' - } -}; diff --git a/src/components/updatemenus/constants.ts b/src/components/updatemenus/constants.ts new file mode 100644 index 00000000000..0a4ab7fc1ec --- /dev/null +++ b/src/components/updatemenus/constants.ts @@ -0,0 +1,66 @@ +import type { UpdateMenu } from '../../types/generated/schema'; + +// Layout attribute name +export const name = 'updatemenus'; + +// Class names +export const containerClassName = 'updatemenu-container'; +export const headerGroupClassName = 'updatemenu-header-group'; +export const headerClassName = 'updatemenu-header'; +export const headerArrowClassName = 'updatemenu-header-arrow'; +export const dropdownButtonGroupClassName = 'updatemenu-dropdown-button-group'; +export const dropdownButtonClassName = 'updatemenu-dropdown-button'; +export const buttonClassName = 'updatemenu-button'; +export const itemRectClassName = 'updatemenu-item-rect'; +export const itemTextClassName = 'updatemenu-item-text'; + +// DOM attribute name in button group keeping track +// of active update menu +export const menuIndexAttrName = 'updatemenu-active-index'; + +// ID root pass to Plots.autoMargin +export const autoMarginIdRoot = 'updatemenu-'; + +// Options when 'active: -1' +export const blankHeaderOpts = { label: ' ' } as const; + +// Min item width / height +export const minWidth = 30; +export const minHeight = 30; + +// Padding around item text +export const textPadX = 24; +export const arrowPadX = 16; + +// Item rect radii +export const rx = 2; +export const ry = 2; + +// Item text x offset off left edge +export const textOffsetX = 12; + +// Item text y offset (w.r.t. middle) +export const textOffsetY = 3; + +// Arrow offset off right edge +export const arrowOffsetX = 4; + +// Gap between header and buttons +export const gapButtonHeader = 5; + +// Gap between between buttons +export const gapButton = 2; + +// Color given to active buttons +export const activeColor = '#F4FAFF'; + +// Color given to hovered buttons +export const hoverColor = '#F4FAFF'; + +// Symbol for menu open arrow +export const arrowSymbol = { + left: '◄', + right: '►', + up: '▲', + down: '▼' +} as const satisfies Record, string>; diff --git a/src/constants/alignment.js b/src/constants/alignment.js deleted file mode 100644 index 09eb4fa88a6..00000000000 --- a/src/constants/alignment.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict'; - -// fraction of some size to get to a named position -module.exports = { - // from bottom left: this is the origin of our paper-reference - // positioning system - FROM_BL: { - left: 0, - center: 0.5, - right: 1, - bottom: 0, - middle: 0.5, - top: 1 - }, - // from top left: this is the screen pixel positioning origin - FROM_TL: { - left: 0, - center: 0.5, - right: 1, - bottom: 1, - middle: 0.5, - top: 0 - }, - // from bottom right: sometimes you just need the opposite of ^^ - FROM_BR: { - left: 1, - center: 0.5, - right: 0, - bottom: 0, - middle: 0.5, - top: 1 - }, - // multiple of fontSize to get the vertical offset between lines - LINE_SPACING: 1.3, - - // multiple of fontSize to shift from the baseline - // to the cap (captical letter) line - // (to use when we don't calculate this shift from Drawing.bBox) - // This is an approximation since in reality cap height can differ - // from font to font. However, according to Wikipedia - // an "average" font might have a cap height of 70% of the em - // https://en.wikipedia.org/wiki/Em_(typography)#History - CAP_SHIFT: 0.70, - - // half the cap height (distance between baseline and cap line) - // of an "average" font (for more info see above). - MID_SHIFT: 0.35, - - OPPOSITE_SIDE: { - left: 'right', - right: 'left', - top: 'bottom', - bottom: 'top' - } -}; diff --git a/src/constants/alignment.ts b/src/constants/alignment.ts new file mode 100644 index 00000000000..3beb67122cb --- /dev/null +++ b/src/constants/alignment.ts @@ -0,0 +1,64 @@ +import type { LayoutAxis } from '../types/generated/schema'; +import type { XAnchor, YAnchor } from '../types/lib/common'; + +// Fraction of some size to get to a named position + +/** Fraction of the full size for each named position along both axes */ +export type PositionFractions = Record, number>; + +// From bottom left: this is the origin of our paper-reference +// positioning system +export const FROM_BL = { + left: 0, + center: 0.5, + right: 1, + bottom: 0, + middle: 0.5, + top: 1 +} as const satisfies PositionFractions; + +// From top left: this is the screen pixel positioning origin +export const FROM_TL = { + left: 0, + center: 0.5, + right: 1, + bottom: 1, + middle: 0.5, + top: 0 +} as const satisfies PositionFractions; + +// From bottom right: sometimes you just need the opposite of ^^ +export const FROM_BR = { + left: 1, + center: 0.5, + right: 0, + bottom: 0, + middle: 0.5, + top: 1 +} as const satisfies PositionFractions; + +// Multiple of fontSize to get the vertical offset between lines +export const LINE_SPACING = 1.3; + +// Multiple of fontSize to shift from the baseline +// to the cap (captical letter) line +// (to use when we don't calculate this shift from Drawing.bBox) +// This is an approximation since in reality cap height can differ +// from font to font. However, according to Wikipedia +// an "average" font might have a cap height of 70% of the em +// https://en.wikipedia.org/wiki/Em_(typography)#History +export const CAP_SHIFT = 0.70; + +// Half the cap height (distance between baseline and cap line) +// of an "average" font (for more info see above). +export const MID_SHIFT = 0.35; + +type AxisSide = NonNullable; + +/** The side facing the opposite direction, for each side name */ +export const OPPOSITE_SIDE = { + left: 'right', + right: 'left', + top: 'bottom', + bottom: 'top' +} as const satisfies Record; diff --git a/src/constants/axis_placeable_objects.js b/src/constants/axis_placeable_objects.js deleted file mode 100644 index 66bffdd77fa..00000000000 --- a/src/constants/axis_placeable_objects.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -module.exports = { - axisRefDescription: function(axisname, lower, upper) { - return [ - 'If set to a', axisname, 'axis id (e.g. *' + axisname + '* or', - '*' + axisname + '2*), the `' + axisname + '` position refers to a', - axisname, 'coordinate. If set to *paper*, the `' + axisname + '`', - 'position refers to the distance from the', lower, 'of the plotting', - 'area in normalized coordinates where *0* (*1*) corresponds to the', - lower, '(' + upper + '). If set to a', axisname, 'axis ID followed by', - '*domain* (separated by a space), the position behaves like for', - '*paper*, but refers to the distance in fractions of the domain', - 'length from the', lower, 'of the domain of that axis: e.g.,', - '*' + axisname + '2 domain* refers to the domain of the second', - axisname, 'axis and a', axisname, 'position of 0.5 refers to the', - 'point between the', lower, 'and the', upper, 'of the domain of the', - 'second', axisname, 'axis.', - ].join(' '); - } -}; diff --git a/src/constants/axis_placeable_objects.ts b/src/constants/axis_placeable_objects.ts new file mode 100644 index 00000000000..09429c8257f --- /dev/null +++ b/src/constants/axis_placeable_objects.ts @@ -0,0 +1,22 @@ +/** + * Build the description for an axis-reference attribute such as `xref` or `yref`. + * Returns the description text for the three position modes: axis, paper, and axis domain. + * + * @param axisname - The axis letter, for example `x` or `y` + * @param lower - Name of the low end of the axis, for example `left` or `bottom` + * @param upper - Name of the high end of the axis, for example `right` or `top` + */ +export function axisRefDescription(axisname: string, lower: string, upper: string) { + return [ + `If set to a ${axisname} axis id (e.g. *${axisname}* or *${axisname}2*),`, + `the \`${axisname}\` position refers to a ${axisname} coordinate.`, + `If set to *paper*, the \`${axisname}\` position refers to the distance from the`, + `${lower} of the plotting area in normalized coordinates where *0* (*1*) corresponds`, + `to the ${lower} (${upper}). If set to a ${axisname} axis ID followed by *domain*`, + `(separated by a space), the position behaves like for *paper*, but refers to the`, + `distance in fractions of the domain length from the ${lower} of the domain of that`, + `axis: e.g., *${axisname}2 domain* refers to the domain of the second ${axisname}`, + `axis and a ${axisname} position of 0.5 refers to the point between the ${lower}`, + `and the ${upper} of the domain of the second ${axisname} axis.` + ].join(' '); +} diff --git a/src/constants/delta.js b/src/constants/delta.js deleted file mode 100644 index 0e303f7c214..00000000000 --- a/src/constants/delta.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -module.exports = { - INCREASING: { - COLOR: '#3D9970', - SYMBOL: '▲' - }, - DECREASING: { - COLOR: '#FF4136', - SYMBOL: '▼' - } -}; diff --git a/src/constants/delta.ts b/src/constants/delta.ts new file mode 100644 index 00000000000..744e2cced68 --- /dev/null +++ b/src/constants/delta.ts @@ -0,0 +1,9 @@ +export const INCREASING = { + COLOR: '#3D9970', + SYMBOL: '▲' +} as const; + +export const DECREASING = { + COLOR: '#FF4136', + SYMBOL: '▼' +} as const; diff --git a/src/constants/docs.js b/src/constants/docs.js deleted file mode 100644 index b90367393e5..00000000000 --- a/src/constants/docs.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -module.exports = { - FORMAT_LINK: 'https://github.com/d3/d3-format/tree/v1.4.5#d3-format', - DATE_FORMAT_LINK: 'https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format' -}; diff --git a/src/constants/docs.ts b/src/constants/docs.ts new file mode 100644 index 00000000000..7d23c9ad2de --- /dev/null +++ b/src/constants/docs.ts @@ -0,0 +1,2 @@ +export const FORMAT_LINK = 'https://github.com/d3/d3-format/tree/v1.4.5#d3-format'; +export const DATE_FORMAT_LINK = 'https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format'; diff --git a/src/constants/filter_ops.js b/src/constants/filter_ops.js deleted file mode 100644 index e34b106df02..00000000000 --- a/src/constants/filter_ops.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -module.exports = { - COMPARISON_OPS: ['=', '!=', '<', '>=', '>', '<='], - COMPARISON_OPS2: ['=', '<', '>=', '>', '<='], - INTERVAL_OPS: ['[]', '()', '[)', '(]', '][', ')(', '](', ')['], - SET_OPS: ['{}', '}{'], - CONSTRAINT_REDUCTION: { - // for contour constraints, open/closed endpoints are equivalent - '=': '=', - - '<': '<', - '<=': '<', - - '>': '>', - '>=': '>', - - '[]': '[]', - '()': '[]', - '[)': '[]', - '(]': '[]', - - '][': '][', - ')(': '][', - '](': '][', - ')[': '][' - } -}; diff --git a/src/constants/filter_ops.ts b/src/constants/filter_ops.ts new file mode 100644 index 00000000000..1597059f19d --- /dev/null +++ b/src/constants/filter_ops.ts @@ -0,0 +1,23 @@ +export const COMPARISON_OPS = ['=', '!=', '<', '>=', '>', '<='] as const; +export const COMPARISON_OPS2 = ['=', '<', '>=', '>', '<='] as const; +export const INTERVAL_OPS = ['[]', '()', '[)', '(]', '][', ')(', '](', ')['] as const; +export const SET_OPS = ['{}', '}{'] as const; +/** An operator that `CONSTRAINT_REDUCTION` maps to its canonical form */ +export type ReducibleOp = (typeof COMPARISON_OPS2)[number] | (typeof INTERVAL_OPS)[number]; + +export const CONSTRAINT_REDUCTION = { + // For contour constraints, open/closed endpoints are equivalent + '=': '=', + '<': '<', + '<=': '<', + '>': '>', + '>=': '>', + '[]': '[]', + '()': '[]', + '[)': '[]', + '(]': '[]', + '][': '][', + ')(': '][', + '](': '][', + ')[': '][' +} as const satisfies Record; diff --git a/src/constants/gl3d_dashes.js b/src/constants/gl3d_dashes.js deleted file mode 100644 index ffa1835cb25..00000000000 --- a/src/constants/gl3d_dashes.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = { - solid: [[], 0], - dot: [[0.5, 1], 200], - dash: [[0.5, 1], 50], - longdash: [[0.5, 1], 10], - dashdot: [[0.5, 0.625, 0.875, 1], 50], - longdashdot: [[0.5, 0.7, 0.8, 1], 10] -}; diff --git a/src/constants/gl3d_dashes.ts b/src/constants/gl3d_dashes.ts new file mode 100644 index 00000000000..f060713660c --- /dev/null +++ b/src/constants/gl3d_dashes.ts @@ -0,0 +1,15 @@ +import type { Dash } from '../types/generated/schema'; + +/** Dash pattern for gl3d lines: the gl-line3d `dashes` stops, then its `dashScale` repeat count */ +type DashPattern = [number[], number]; + +const dashes = { + solid: [[], 0], + dot: [[0.5, 1], 200], + dash: [[0.5, 1], 50], + longdash: [[0.5, 1], 10], + dashdot: [[0.5, 0.625, 0.875, 1], 50], + longdashdot: [[0.5, 0.7, 0.8, 1], 10] +} as const satisfies Record; + +export default dashes; diff --git a/src/constants/gl3d_markers.js b/src/constants/gl3d_markers.ts similarity index 65% rename from src/constants/gl3d_markers.js rename to src/constants/gl3d_markers.ts index c591f73c0d0..8ad2ed2f32a 100644 --- a/src/constants/gl3d_markers.js +++ b/src/constants/gl3d_markers.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +const markers = { circle: '●', 'circle-open': '○', square: '■', @@ -9,4 +7,6 @@ module.exports = { 'diamond-open': '◇', cross: '+', x: '❌' -}; +} as const satisfies Record; + +export default markers; diff --git a/src/constants/interactions.js b/src/constants/interactions.js deleted file mode 100644 index 84cbbeb0ba8..00000000000 --- a/src/constants/interactions.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - - -module.exports = { - /** - * Timing information for interactive elements - */ - SHOW_PLACEHOLDER: 100, - HIDE_PLACEHOLDER: 1000, - - // opacity dimming fraction for points that are not in selection - DESELECTDIM: 0.2 -}; diff --git a/src/constants/interactions.ts b/src/constants/interactions.ts new file mode 100644 index 00000000000..7741a867e0e --- /dev/null +++ b/src/constants/interactions.ts @@ -0,0 +1,8 @@ +/** + * Timing information for interactive elements + */ +export const SHOW_PLACEHOLDER = 100; +export const HIDE_PLACEHOLDER = 1000; + +// Opacity dimming fraction for points that are not in selection +export const DESELECTDIM = 0.2; diff --git a/src/constants/numerical.js b/src/constants/numerical.js deleted file mode 100644 index 1edd86e97e4..00000000000 --- a/src/constants/numerical.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - - -module.exports = { - /** - * Standardize all missing data in calcdata to use undefined - * never null or NaN. - * That way we can use !==undefined, or !== BADNUM, - * to test for real data - */ - BADNUM: undefined, - - /* - * Limit certain operations to well below floating point max value - * to avoid glitches: Make sure that even when you multiply it by the - * number of pixels on a giant screen it still works - */ - FP_SAFE: Number.MAX_VALUE * 1e-4, - - /* - * conversion of date units to milliseconds - * year and month constants are marked "AVG" - * to remind us that not all years and months - * have the same length - */ - ONEMAXYEAR: 31622400000, // 366 * ONEDAY - ONEAVGYEAR: 31557600000, // 365.25 days - ONEMINYEAR: 31536000000, // 365 * ONEDAY - ONEMAXQUARTER: 7948800000, // 92 * ONEDAY - ONEAVGQUARTER: 7889400000, // 1/4 of ONEAVGYEAR - ONEMINQUARTER: 7689600000, // 89 * ONEDAY - ONEMAXMONTH: 2678400000, // 31 * ONEDAY - ONEAVGMONTH: 2629800000, // 1/12 of ONEAVGYEAR - ONEMINMONTH: 2419200000, // 28 * ONEDAY - ONEWEEK: 604800000, // 7 * ONEDAY - ONEDAY: 86400000, // 24 * ONEHOUR - ONEHOUR: 3600000, - ONEMIN: 60000, - ONESEC: 1000, - ONEMILLI: 1, - ONEMICROSEC: 0.001, - /* - * For fast conversion btwn world calendars and epoch ms, the Julian Day Number - * of the unix epoch. From calendars.instance().newDate(1970, 1, 1).toJD() - */ - EPOCHJD: 2440587.5, - - /* - * Are two values nearly equal? Compare to 1PPM - */ - ALMOST_EQUAL: 1 - 1e-6, - - /* - * If we're asked to clip a non-positive log value, how far off-screen - * do we put it? - */ - LOG_CLIP: 10, - - /* - * not a number, but for displaying numbers: the "minus sign" symbol is - * wider than the regular ascii dash "-" - */ - MINUS_SIGN: '\u2212' -}; diff --git a/src/constants/numerical.ts b/src/constants/numerical.ts new file mode 100644 index 00000000000..30f3a222bf9 --- /dev/null +++ b/src/constants/numerical.ts @@ -0,0 +1,60 @@ +/** + * Standardize all missing data in calcdata to use undefined + * never null or NaN. + * That way we can use !==undefined, or !== BADNUM, + * to test for real data + */ +export const BADNUM = undefined; + +/* + * Limit certain operations to well below floating point max value + * to avoid glitches: Make sure that even when you multiply it by the + * number of pixels on a giant screen it still works + */ +export const FP_SAFE = Number.MAX_VALUE * 1e-4; + +/* + * Conversion of date units to milliseconds + * year and month constants are marked "AVG" + * to remind us that not all years and months + * have the same length + */ +export const ONEMAXYEAR = 31622400000; // 366 * ONEDAY +export const ONEAVGYEAR = 31557600000; // 365.25 days +export const ONEMINYEAR = 31536000000; // 365 * ONEDAY +export const ONEMAXQUARTER = 7948800000; // 92 * ONEDAY +export const ONEAVGQUARTER = 7889400000; // 1/4 of ONEAVGYEAR +export const ONEMINQUARTER = 7689600000; // 89 * ONEDAY +export const ONEMAXMONTH = 2678400000; // 31 * ONEDAY +export const ONEAVGMONTH = 2629800000; // 1/12 of ONEAVGYEAR +export const ONEMINMONTH = 2419200000; // 28 * ONEDAY +export const ONEWEEK = 604800000; // 7 * ONEDAY +export const ONEDAY = 86400000; // 24 * ONEHOUR +export const ONEHOUR = 3600000; +export const ONEMIN = 60000; +export const ONESEC = 1000; +export const ONEMILLI = 1; +export const ONEMICROSEC = 0.001; + +/* + * For fast conversion btwn world calendars and epoch ms, the Julian Day Number + * of the unix epoch. From calendars.instance().newDate(1970, 1, 1).toJD() + */ +export const EPOCHJD = 2440587.5; + +/* + * Are two values nearly equal? Compare to 1PPM + */ +export const ALMOST_EQUAL = 1 - 1e-6; + +/* + * If we're asked to clip a non-positive log value, how far off-screen + * do we put it? + */ +export const LOG_CLIP = 10; + +/* + * Not a number, but for displaying numbers: the "minus sign" symbol is + * wider than the regular ascii dash "-" + */ +export const MINUS_SIGN = '\u2212'; diff --git a/src/constants/pixelated_image.js b/src/constants/pixelated_image.ts similarity index 80% rename from src/constants/pixelated_image.js rename to src/constants/pixelated_image.ts index ca4f18ed3db..20bcbb111f8 100644 --- a/src/constants/pixelated_image.js +++ b/src/constants/pixelated_image.ts @@ -1,5 +1,3 @@ -'use strict'; - // Pixelated image rendering // The actual CSS declaration is prepended with fallbacks for older browsers. // NB. IE's `-ms-interpolation-mode` works only with not with SVG @@ -7,7 +5,7 @@ // https://caniuse.com/?search=image-rendering // http://phrogz.net/tmp/canvas_image_zoom.html -exports.CSS_DECLARATIONS = [ +export const CSS_DECLARATIONS = [ ['image-rendering', 'optimizeSpeed'], ['image-rendering', '-moz-crisp-edges'], ['image-rendering', '-o-crisp-edges'], @@ -15,8 +13,6 @@ exports.CSS_DECLARATIONS = [ ['image-rendering', 'optimize-contrast'], ['image-rendering', 'crisp-edges'], ['image-rendering', 'pixelated'] -]; +] as const satisfies [string, string][]; -exports.STYLE = exports.CSS_DECLARATIONS.map(function(d) { - return d.join(': ') + '; '; -}).join(''); +export const STYLE = CSS_DECLARATIONS.map((d) => d.join(': ') + '; ').join(''); diff --git a/src/constants/xmlns_namespaces.js b/src/constants/xmlns_namespaces.js deleted file mode 100644 index 1c2e6e0a07e..00000000000 --- a/src/constants/xmlns_namespaces.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - - -exports.xmlns = 'http://www.w3.org/2000/xmlns/'; -exports.svg = 'http://www.w3.org/2000/svg'; -exports.xlink = 'http://www.w3.org/1999/xlink'; - -// the 'old' d3 quirk got fix in v3.5.7 -// https://github.com/mbostock/d3/commit/a6f66e9dd37f764403fc7c1f26be09ab4af24fed -exports.svgAttrs = { - xmlns: exports.svg, - 'xmlns:xlink': exports.xlink -}; diff --git a/src/constants/xmlns_namespaces.ts b/src/constants/xmlns_namespaces.ts new file mode 100644 index 00000000000..9485375a699 --- /dev/null +++ b/src/constants/xmlns_namespaces.ts @@ -0,0 +1,10 @@ +export const xmlns = 'http://www.w3.org/2000/xmlns/'; +export const svg = 'http://www.w3.org/2000/svg'; +export const xlink = 'http://www.w3.org/1999/xlink'; + +// The 'old' d3 quirk got fix in v3.5.7 +// https://github.com/mbostock/d3/commit/a6f66e9dd37f764403fc7c1f26be09ab4af24fed +export const svgAttrs = { + xmlns: svg, + 'xmlns:xlink': xlink +} as const; diff --git a/src/plots/cartesian/constants.js b/src/plots/cartesian/constants.js deleted file mode 100644 index 22d3070b03c..00000000000 --- a/src/plots/cartesian/constants.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; - -var counterRegex = require('../../lib/regex').counter; - -module.exports = { - idRegex: { - x: counterRegex('x', '( domain)?'), - y: counterRegex('y', '( domain)?') - }, - - attrRegex: counterRegex('[xy]axis'), - - // axis match regular expression - xAxisMatch: counterRegex('xaxis'), - yAxisMatch: counterRegex('yaxis'), - - // pattern matching axis ids and names - // note that this is more permissive than counterRegex, as - // id2name, name2id, and cleanId accept "x1" etc - AX_ID_PATTERN: /^[xyz][0-9]*( domain)?$/, - AX_NAME_PATTERN: /^[xyz]axis[0-9]*$/, - - // and for 2D subplots - SUBPLOT_PATTERN: /^x([0-9]*)y([0-9]*)$/, - - HOUR_PATTERN: 'hour', - WEEKDAY_PATTERN: 'day of week', - - // pixels to move mouse before you stop clamping to starting point - MINDRAG: 8, - - // smallest dimension allowed for a zoombox - MINZOOM: 20, - - // width of axis drag regions - DRAGGERSIZE: 20, - - // delay before a redraw (relayout) after smooth panning and zooming - REDRAWDELAY: 50, - - // last resort axis ranges for x and y axes if we have no data - DFLTRANGEX: [-1, 6], - DFLTRANGEY: [-1, 4], - - // Layers to keep trace types in the right order - // N.B. each 'unique' plot method must have its own layer - traceLayerClasses: [ - 'imagelayer', - 'heatmaplayer', - 'contourcarpetlayer', 'contourlayer', - 'funnellayer', 'waterfalllayer', 'barlayer', - 'carpetlayer', - 'violinlayer', - 'boxlayer', - 'ohlclayer', - 'scattercarpetlayer', 'scatterlayer' - ], - - clipOnAxisFalseQuery: [ - '.scatterlayer', - '.barlayer', - '.funnellayer', - '.waterfalllayer' - ], - - layerValue2layerClass: { - 'above traces': 'above', - 'below traces': 'below' - }, - - zindexSeparator: 'z', // used for zindex of cartesian subplots e.g. xy, xyz2, xyz3, etc. -}; diff --git a/src/plots/cartesian/constants.ts b/src/plots/cartesian/constants.ts new file mode 100644 index 00000000000..24c6aecdd23 --- /dev/null +++ b/src/plots/cartesian/constants.ts @@ -0,0 +1,78 @@ +import { counter as counterRegex } from '../../lib/regex'; +import type { LayoutAxis, TraceType } from '../../types/generated/schema'; + +export const idRegex = { + x: counterRegex('x', '( domain)?'), + y: counterRegex('y', '( domain)?') +} as const; + +export const attrRegex = counterRegex('[xy]axis'); + +// Axis match regular expression +export const xAxisMatch = counterRegex('xaxis'); +export const yAxisMatch = counterRegex('yaxis'); + +// Pattern matching axis ids and names +// note that this is more permissive than counterRegex, as +// id2name, name2id, and cleanId accept "x1" etc +export const AX_ID_PATTERN = /^[xyz][0-9]*( domain)?$/; +export const AX_NAME_PATTERN = /^[xyz]axis[0-9]*$/; + +// And for 2D subplots +export const SUBPLOT_PATTERN = /^x([0-9]*)y([0-9]*)$/; + +// These two become the `rangebreaks.pattern` values in the schema +export const HOUR_PATTERN = 'hour'; +export const WEEKDAY_PATTERN = 'day of week'; + +// Pixels to move mouse before you stop clamping to starting point +export const MINDRAG = 8; + +// Smallest dimension allowed for a zoombox +export const MINZOOM = 20; + +// Width of axis drag regions +export const DRAGGERSIZE = 20; + +// Delay before a redraw (relayout) after smooth panning and zooming +export const REDRAWDELAY = 50; + +// Last resort axis ranges for x and y axes if we have no data +export const DFLTRANGEX = [-1, 6] as const; +export const DFLTRANGEY = [-1, 4] as const; + +// Layers to keep trace types in the right order +// N.B. each 'unique' plot method must have its own layer +export const traceLayerClasses = [ + 'imagelayer', + 'heatmaplayer', + 'contourcarpetlayer', + 'contourlayer', + 'funnellayer', + 'waterfalllayer', + 'barlayer', + 'carpetlayer', + 'violinlayer', + 'boxlayer', + 'ohlclayer', + 'scattercarpetlayer', + 'scatterlayer' +] as const satisfies readonly `${TraceType}layer`[]; + +/** An SVG layer class holding one trace type, such as `barlayer` */ +export type TraceLayerClass = (typeof traceLayerClasses)[number]; + +export const clipOnAxisFalseQuery = [ + '.scatterlayer', + '.barlayer', + '.funnellayer', + '.waterfalllayer' +] as const satisfies readonly `.${TraceLayerClass}`[]; + +export const layerValue2layerClass = { + 'above traces': 'above', + 'below traces': 'below' +} as const satisfies Record, string>; + +// Used for zindex of cartesian subplots e.g. xy, xyz2, xyz3, etc. +export const zindexSeparator = 'z'; diff --git a/src/plots/geo/constants.js b/src/plots/geo/constants.ts similarity index 63% rename from src/plots/geo/constants.js rename to src/plots/geo/constants.ts index 6c263146c16..1731a1d4a21 100644 --- a/src/plots/geo/constants.js +++ b/src/plots/geo/constants.ts @@ -1,7 +1,16 @@ -'use strict'; +import type { ChoroplethData, GeoLayout } from '../../types/generated/schema'; -// projection names to d3 function name -exports.projNames = { +type GeoProjection = NonNullable; +/** A `geo.projection.type` value, such as `mercator` */ +export type GeoProjectionType = NonNullable; +/** A `[min, max]` range for `geo.lonaxis` or `geo.lataxis` */ +export type LonLatRange = NonNullable['range']>; +/** A `locationmode` value, such as `ISO-3` */ +export type LocationMode = NonNullable; + +// Projection names to d3 function name +// These keys become the `geo.projection.type` values in the schema +export const projNames = { airy: 'airy', aitoff: 'aitoff', 'albers usa': 'albersUsa', @@ -116,14 +125,17 @@ exports.projNames = { // 'wagner': 'wagner', wiechel: 'wiechel', 'winkel tripel': 'winkel3', - winkel3: 'winkel3', -}; + winkel3: 'winkel3' +} as const satisfies Record; + +// Name of the axes +export const axesNames = ['lonaxis', 'lataxis'] as const; -// name of the axes -exports.axesNames = ['lonaxis', 'lataxis']; +/** Angular span per projection, with `*` as the span for every other projection */ +export type ProjectionSpans = Partial> & { '*': number }; -// max longitudinal angular span (EXPERIMENTAL) -exports.lonaxisSpan = { +// Max longitudinal angular span (EXPERIMENTAL) +export const lonaxisSpan = { orthographic: 180, 'azimuthal equal area': 360, 'azimuthal equidistant': 360, @@ -132,20 +144,36 @@ exports.lonaxisSpan = { stereographic: 180, 'transverse mercator': 180, '*': 360 -}; +} as const satisfies ProjectionSpans; -// max latitudinal angular span (EXPERIMENTAL) -exports.lataxisSpan = { +// Max latitudinal angular span (EXPERIMENTAL) +export const lataxisSpan = { 'conic conformal': 150, stereographic: 179.5, '*': 180 -}; +} as const satisfies ProjectionSpans; // Projections whose math doesn't play well with fitbounds -exports.fitboundsIncompatible = new Set(['albers usa', 'craig', 'peirce quincuncial', 'satellite']); +export const fitboundsIncompatible: Set = new Set([ + 'albers usa', + 'craig', + 'peirce quincuncial', + 'satellite' +]); -// defaults for each scope -exports.scopeDefaults = { +/** Starting axis ranges and projection settings for one `geo.scope` */ +export interface ScopeDefaults { + lonaxisRange: LonLatRange; + lataxisRange: LonLatRange; + projType: GeoProjectionType; + // The schema models `projection.rotation` as an object, but this table holds [lon, lat, roll] + projRotate?: [number, number, number]; + projParallels?: NonNullable; +} + +// Defaults for each scope +// These keys become the `geo.scope` values in the schema +export const scopeDefaults = { world: { lonaxisRange: [-180, 180], lataxisRange: [-90, 90], @@ -200,67 +228,95 @@ exports.scopeDefaults = { lataxisRange: [-50, 25], projType: 'equirectangular', projRotate: [0, 0, 0] - }, -}; + } +} as const satisfies Record; -// angular pad to avoid rounding error around clip angles -exports.clipPad = 1e-3; +// Angular pad to avoid rounding error around clip angles +export const clipPad = 1e-3; -// map projection precision -exports.precision = 0.1; +// Map projection precision +export const precision = 0.1; -// default land and water fill colors -exports.landColor = '#F0DC82'; -exports.waterColor = '#3399FF'; +// Default land and water fill colors +export const landColor = '#F0DC82'; +export const waterColor = '#3399FF'; // locationmode to layer name -exports.locationmodeToLayer = { +export const locationmodeToLayer = { 'ISO-3': 'countries', 'USA-states': 'subunits', 'country names': 'countries' -}; +} as const satisfies Partial>; // SVG element for a sphere (use to frame maps) -exports.sphereSVG = {type: 'Sphere'}; +export const sphereSVG = { type: 'Sphere' } as const; // N.B. base layer names must be the same as in the topojson files -// base layer with a fill color -exports.fillLayers = { +// Base layer with a fill color +export const fillLayers = { ocean: 1, land: 1, lakes: 1 -}; +} as const satisfies Partial>; -// base layer with a only a line color -exports.lineLayers = { +// Base layer with a only a line color +export const lineLayers = { subunits: 1, countries: 1, coastlines: 1, rivers: 1, frame: 1 -}; +} as const satisfies Partial>; -exports.layers = [ +/** A base layer drawn from topojson, such as `land` or `countries` */ +export type GeoBaseLayer = keyof typeof fillLayers | keyof typeof lineLayers; + +// Draw order, back to front +export const layers = [ 'bg', - 'ocean', 'land', 'lakes', - 'subunits', 'countries', 'coastlines', 'rivers', - 'lataxis', 'lonaxis', 'frame', + 'ocean', + 'land', + 'lakes', + 'subunits', + 'countries', + 'coastlines', + 'rivers', + 'lataxis', + 'lonaxis', + 'frame', 'backplot', 'frontplot' -]; +] as const; + +/** Any layer of a geo subplot, base layers and plot layers alike */ +export type GeoLayer = (typeof layers)[number]; + +// The mapped type is homomorphic only over a type parameter, so `T` cannot be inlined here +type SameLength = { [K in keyof T]: V }; + +/** A draw order holding the same layers as `layers`: same length, and every element is a layer */ +type LayerOrder = SameLength; -exports.layersForChoropleth = [ +// Same layers as `layers`, but rivers and lakes move above the choropleth so water stays visible +export const layersForChoropleth = [ 'bg', - 'ocean', 'land', - 'subunits', 'countries', 'coastlines', - 'lataxis', 'lonaxis', 'frame', + 'ocean', + 'land', + 'subunits', + 'countries', + 'coastlines', + 'lataxis', + 'lonaxis', + 'frame', 'backplot', - 'rivers', 'lakes', + 'rivers', + 'lakes', 'frontplot' -]; +] as const satisfies LayerOrder; -exports.layerNameToAdjective = { +// Every base layer needs an adjective, because `adjective + 'color'` names a public attribute +export const layerNameToAdjective = { ocean: 'ocean', land: 'land', lakes: 'lake', @@ -269,4 +325,4 @@ exports.layerNameToAdjective = { coastlines: 'coastline', rivers: 'river', frame: 'frame' -}; +} as const satisfies Record; diff --git a/src/plots/polar/constants.js b/src/plots/polar/constants.js deleted file mode 100644 index b22c205b154..00000000000 --- a/src/plots/polar/constants.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -module.exports = { - attr: 'subplot', - name: 'polar', - - axisNames: ['angularaxis', 'radialaxis'], - axisName2dataArray: {angularaxis: 'theta', radialaxis: 'r'}, - - layerNames: [ - 'draglayer', - 'plotbg', - 'backplot', - 'angular-grid', - 'radial-grid', - 'frontplot', - 'angular-line', - 'radial-line', - 'angular-axis', - 'radial-axis' - ], - - radialDragBoxSize: 50, - angularDragBoxSize: 30, - cornerLen: 25, - cornerHalfWidth: 2, - - // pixels to move mouse before you stop clamping to starting point - MINDRAG: 8, - // smallest radial distance [px] allowed for a zoombox - MINZOOM: 20, - // distance [px] off (r=0) or (r=radius) where we transition - // from single-sided to two-sided radial zoom - OFFEDGE: 20 -}; diff --git a/src/plots/polar/constants.ts b/src/plots/polar/constants.ts new file mode 100644 index 00000000000..ff475586e97 --- /dev/null +++ b/src/plots/polar/constants.ts @@ -0,0 +1,35 @@ +export const attr = 'subplot'; +export const name = 'polar'; + +export const axisNames = ['angularaxis', 'radialaxis'] as const; + +/** The data array each axis of this subplot reads, keyed by axis name */ +type AxisDataArrays = Record<(typeof axisNames)[number], string>; + +export const axisName2dataArray = { angularaxis: 'theta', radialaxis: 'r' } as const satisfies AxisDataArrays; + +export const layerNames = [ + 'draglayer', + 'plotbg', + 'backplot', + 'angular-grid', + 'radial-grid', + 'frontplot', + 'angular-line', + 'radial-line', + 'angular-axis', + 'radial-axis' +] as const; + +export const radialDragBoxSize = 50; +export const angularDragBoxSize = 30; +export const cornerLen = 25; +export const cornerHalfWidth = 2; + +// Pixels to move mouse before you stop clamping to starting point +export const MINDRAG = 8; +// Smallest radial distance [px] allowed for a zoombox +export const MINZOOM = 20; +// Distance [px] off (r=0) or (r=radius) where we transition +// from single-sided to two-sided radial zoom +export const OFFEDGE = 20; diff --git a/src/plots/smith/constants.js b/src/plots/smith/constants.js deleted file mode 100644 index 24357fc29a5..00000000000 --- a/src/plots/smith/constants.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -module.exports = { - attr: 'subplot', - name: 'smith', - - axisNames: [ - 'realaxis', - 'imaginaryaxis' // imaginary axis should be second here so that the `tickvals` defaults could be inherited from realaxis - ], - axisName2dataArray: {imaginaryaxis: 'imag', realaxis: 'real'}, -}; diff --git a/src/plots/smith/constants.ts b/src/plots/smith/constants.ts new file mode 100644 index 00000000000..05c0410f933 --- /dev/null +++ b/src/plots/smith/constants.ts @@ -0,0 +1,13 @@ +export const attr = 'subplot'; +export const name = 'smith'; + +export const axisNames = [ + 'realaxis', + 'imaginaryaxis' // Imaginary axis should be second here so that the `tickvals` defaults could be inherited from realaxis +] as const; + + +/** The data array each axis of this subplot reads, keyed by axis name */ +type AxisDataArrays = Record<(typeof axisNames)[number], string>; + +export const axisName2dataArray = { imaginaryaxis: 'imag', realaxis: 'real' } as const satisfies AxisDataArrays; diff --git a/src/traces/bar/constants.js b/src/traces/bar/constants.js deleted file mode 100644 index 3d56185f909..00000000000 --- a/src/traces/bar/constants.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -module.exports = { - // padding in pixels around text - TEXTPAD: 3, - // 'value' and 'label' are not really necessary for bar traces, - // but they were made available to `texttemplate` (maybe by accident) - // via tokens `%{value}` and `%{label}` starting in 1.50.0, - // so let's include them in the event data also. - eventDataKeys: ['value', 'label'] -}; diff --git a/src/traces/bar/constants.ts b/src/traces/bar/constants.ts new file mode 100644 index 00000000000..406515ae40a --- /dev/null +++ b/src/traces/bar/constants.ts @@ -0,0 +1,8 @@ +// Padding in pixels around text +export const TEXTPAD = 3; + +// 'value' and 'label' are not really necessary for bar traces, +// but they were made available to `texttemplate` (maybe by accident) +// via tokens `%{value}` and `%{label}` starting in 1.50.0, +// so let's include them in the event data also. +export const eventDataKeys = ['value', 'label'] as const; diff --git a/src/traces/carpet/constants.js b/src/traces/carpet/constants.js deleted file mode 100644 index a91d793f1b5..00000000000 --- a/src/traces/carpet/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = { - RELATIVE_CULL_TOLERANCE: 1e-6 -}; diff --git a/src/traces/carpet/constants.ts b/src/traces/carpet/constants.ts new file mode 100644 index 00000000000..a421b556618 --- /dev/null +++ b/src/traces/carpet/constants.ts @@ -0,0 +1 @@ +export const RELATIVE_CULL_TOLERANCE = 1e-6; diff --git a/src/traces/contour/constants.js b/src/traces/contour/constants.js deleted file mode 100644 index fa96ec16329..00000000000 --- a/src/traces/contour/constants.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; -module.exports = { - // some constants to help with marching squares algorithm - // where does the path start for each index? - BOTTOMSTART: [1, 9, 13, 104, 713], - TOPSTART: [4, 6, 7, 104, 713], - LEFTSTART: [8, 12, 14, 208, 1114], - RIGHTSTART: [2, 3, 11, 208, 1114], - - // which way [dx,dy] do we leave a given index? - // saddles are already disambiguated - NEWDELTA: [ - null, [-1, 0], [0, -1], [-1, 0], - [1, 0], null, [0, -1], [-1, 0], - [0, 1], [0, 1], null, [0, 1], - [1, 0], [1, 0], [0, -1] - ], - - // for each saddle, the first index here is used - // for dx||dy<0, the second for dx||dy>0 - CHOOSESADDLE: { - 104: [4, 1], - 208: [2, 8], - 713: [7, 13], - 1114: [11, 14] - }, - - // after one index has been used for a saddle, which do we - // substitute to be used up later? - SADDLEREMAINDER: {1: 4, 2: 8, 4: 1, 7: 13, 8: 2, 11: 14, 13: 7, 14: 11}, - - // length of a contour, as a multiple of the plot area diagonal, per label - LABELDISTANCE: 2, - - // number of contour levels after which we start increasing the number of - // labels we draw. Many contours means they will generally be close - // together, so it will be harder to follow a long way to find a label - LABELINCREASE: 10, - - // minimum length of a contour line, as a multiple of the label length, - // at which we draw *any* labels - LABELMIN: 3, - - // max number of labels to draw on a single contour path, no matter how long - LABELMAX: 10, - - // constants for the label position cost function - LABELOPTIMIZER: { - // weight given to edge proximity - EDGECOST: 1, - // weight given to the angle off horizontal - ANGLECOST: 1, - // weight given to distance from already-placed labels - NEIGHBORCOST: 5, - // cost multiplier for labels on the same level - SAMELEVELFACTOR: 10, - // minimum distance (as a multiple of the label length) - // for labels on the same level - SAMELEVELDISTANCE: 5, - // maximum cost before we won't even place the label - MAXCOST: 100, - // number of evenly spaced points to look at in the first - // iteration of the search - INITIALSEARCHPOINTS: 10, - // number of binary search iterations after the initial wide search - ITERATIONS: 5 - } -}; diff --git a/src/traces/contour/constants.ts b/src/traces/contour/constants.ts new file mode 100644 index 00000000000..8acb0ffa0f7 --- /dev/null +++ b/src/traces/contour/constants.ts @@ -0,0 +1,65 @@ +// Some constants to help with marching squares algorithm +// where does the path start for each index? +export const BOTTOMSTART = [1, 9, 13, 104, 713] as const; +export const TOPSTART = [4, 6, 7, 104, 713] as const; +export const LEFTSTART = [8, 12, 14, 208, 1114] as const; +export const RIGHTSTART = [2, 3, 11, 208, 1114] as const; + +// Which way [dx,dy] do we leave a given index? +// saddles are already disambiguated +export const NEWDELTA = [ + null, [-1, 0], [0, -1], [-1, 0], + [1, 0], null, [0, -1], [-1, 0], + [0, 1], [0, 1], null, [0, 1], + [1, 0], [1, 0], [0, -1] +] as const satisfies (number[] | null)[]; + +// For each saddle, the first index here is used +// for dx||dy<0, the second for dx||dy>0 +export const CHOOSESADDLE = { + 104: [4, 1], + 208: [2, 8], + 713: [7, 13], + 1114: [11, 14] +} as const satisfies Record; + +// After one index has been used for a saddle, which do we +// substitute to be used up later? +export const SADDLEREMAINDER = { 1: 4, 2: 8, 4: 1, 7: 13, 8: 2, 11: 14, 13: 7, 14: 11 } as const satisfies Record; + +// Length of a contour, as a multiple of the plot area diagonal, per label +export const LABELDISTANCE = 2; + +// Number of contour levels after which we start increasing the number of +// labels we draw. Many contours means they will generally be close +// together, so it will be harder to follow a long way to find a label +export const LABELINCREASE = 10; + +// Minimum length of a contour line, as a multiple of the label length, +// at which we draw *any* labels +export const LABELMIN = 3; + +// Max number of labels to draw on a single contour path, no matter how long +export const LABELMAX = 10; + +// Constants for the label position cost function +export const LABELOPTIMIZER = { + // Weight given to edge proximity + EDGECOST: 1, + // Weight given to the angle off horizontal + ANGLECOST: 1, + // Weight given to distance from already-placed labels + NEIGHBORCOST: 5, + // Cost multiplier for labels on the same level + SAMELEVELFACTOR: 10, + // Minimum distance (as a multiple of the label length) + // for labels on the same level + SAMELEVELDISTANCE: 5, + // Maximum cost before we won't even place the label + MAXCOST: 100, + // Number of evenly spaced points to look at in the first + // iteration of the search + INITIALSEARCHPOINTS: 10, + // Number of binary search iterations after the initial wide search + ITERATIONS: 5 +} as const; diff --git a/src/traces/funnel/constants.js b/src/traces/funnel/constants.js deleted file mode 100644 index 733af38838c..00000000000 --- a/src/traces/funnel/constants.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -module.exports = { - eventDataKeys: [ - 'percentInitial', - 'percentPrevious', - 'percentTotal' - ] -}; diff --git a/src/traces/funnel/constants.ts b/src/traces/funnel/constants.ts new file mode 100644 index 00000000000..003e0dfa381 --- /dev/null +++ b/src/traces/funnel/constants.ts @@ -0,0 +1,5 @@ +export const eventDataKeys = [ + 'percentInitial', + 'percentPrevious', + 'percentTotal' +] as const; diff --git a/src/traces/histogram/constants.js b/src/traces/histogram/constants.js deleted file mode 100644 index 63b016f6966..00000000000 --- a/src/traces/histogram/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = { - eventDataKeys: ['binNumber'] -}; diff --git a/src/traces/histogram/constants.ts b/src/traces/histogram/constants.ts new file mode 100644 index 00000000000..5de0e214e4d --- /dev/null +++ b/src/traces/histogram/constants.ts @@ -0,0 +1 @@ +export const eventDataKeys = ['binNumber'] as const; diff --git a/src/traces/image/constants.js b/src/traces/image/constants.js deleted file mode 100644 index 29cc62b9128..00000000000 --- a/src/traces/image/constants.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -module.exports = { - colormodel: { - // min and max define the numerical range accepted in CSS - // If z(min|max)Dflt are not defined, z(min|max) will default to min/max - rgb: { - min: [0, 0, 0], - max: [255, 255, 255], - fmt: function(c) {return c.slice(0, 3);}, - suffix: ['', '', ''] - }, - rgba: { - min: [0, 0, 0, 0], - max: [255, 255, 255, 1], - fmt: function(c) {return c.slice(0, 4);}, - suffix: ['', '', '', ''] - }, - rgba256: { - colormodel: 'rgba', // because rgba256 is not an accept colormodel in CSS - zminDflt: [0, 0, 0, 0], - zmaxDflt: [255, 255, 255, 255], - min: [0, 0, 0, 0], - max: [255, 255, 255, 1], - fmt: function(c) {return c.slice(0, 4);}, - suffix: ['', '', '', ''] - }, - hsl: { - min: [0, 0, 0], - max: [360, 100, 100], - fmt: function(c) { - var p = c.slice(0, 3); - p[1] = p[1] + '%'; - p[2] = p[2] + '%'; - return p; - }, - suffix: ['°', '%', '%'] - }, - hsla: { - min: [0, 0, 0, 0], - max: [360, 100, 100, 1], - fmt: function(c) { - var p = c.slice(0, 4); - p[1] = p[1] + '%'; - p[2] = p[2] + '%'; - return p; - }, - suffix: ['°', '%', '%', ''] - } - } -}; diff --git a/src/traces/image/constants.ts b/src/traces/image/constants.ts new file mode 100644 index 00000000000..56eb5de8fed --- /dev/null +++ b/src/traces/image/constants.ts @@ -0,0 +1,66 @@ +import type { ImageData } from '../../types/generated/schema'; + +type ColorModelName = NonNullable; + +/** How one `colormodel` maps pixel channels onto a CSS color string */ +interface ColorModel { + /** CSS color model to use, when it differs from the plotly colormodel name */ + colormodel?: ColorModelName; + /** Default `zmin`, when the accepted CSS range is not the data range */ + zminDflt?: number[]; + /** Default `zmax`, when the accepted CSS range is not the data range */ + zmaxDflt?: number[]; + min: number[]; + max: number[]; + /** Take one pixel and return the channel values to join into a CSS color */ + fmt: (c: number[]) => (number | string)[]; + suffix: string[]; +} + +// min and max define the numerical range accepted in CSS +// If z(min|max)Dflt are not defined, z(min|max) will default to min/max +export const colormodel = { + rgb: { + min: [0, 0, 0], + max: [255, 255, 255], + fmt: (c) => c.slice(0, 3), + suffix: ['', '', ''] + }, + rgba: { + min: [0, 0, 0, 0], + max: [255, 255, 255, 1], + fmt: (c) => c.slice(0, 4), + suffix: ['', '', '', ''] + }, + rgba256: { + colormodel: 'rgba', // Because rgba256 is not an accept colormodel in CSS + zminDflt: [0, 0, 0, 0], + zmaxDflt: [255, 255, 255, 255], + min: [0, 0, 0, 0], + max: [255, 255, 255, 1], + fmt: (c) => c.slice(0, 4), + suffix: ['', '', '', ''] + }, + hsl: { + min: [0, 0, 0], + max: [360, 100, 100], + fmt: (c) => { + const p: (number | string)[] = c.slice(0, 3); + p[1] = p[1] + '%'; + p[2] = p[2] + '%'; + return p; + }, + suffix: ['°', '%', '%'] + }, + hsla: { + min: [0, 0, 0, 0], + max: [360, 100, 100, 1], + fmt: (c) => { + const p: (number | string)[] = c.slice(0, 4); + p[1] = p[1] + '%'; + p[2] = p[2] + '%'; + return p; + }, + suffix: ['°', '%', '%', ''] + } +} as const satisfies Record; diff --git a/src/traces/indicator/constants.js b/src/traces/indicator/constants.js deleted file mode 100644 index bd49dbe5ae7..00000000000 --- a/src/traces/indicator/constants.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -module.exports = { - // Defaults for delta - defaultNumberFontSize: 80, - bulletNumberDomainSize: 0.25, - bulletPadding: 0.025, - innerRadius: 0.75, - valueThickness: 0.5, // thickness of value bars relative to full thickness, - titlePadding: 5, - horizontalPadding: 10 -}; diff --git a/src/traces/indicator/constants.ts b/src/traces/indicator/constants.ts new file mode 100644 index 00000000000..64b19fe5fc7 --- /dev/null +++ b/src/traces/indicator/constants.ts @@ -0,0 +1,8 @@ +// Defaults for delta +export const defaultNumberFontSize = 80; +export const bulletNumberDomainSize = 0.25; +export const bulletPadding = 0.025; +export const innerRadius = 0.75; +export const valueThickness = 0.5; // Thickness of value bars relative to full thickness, +export const titlePadding = 5; +export const horizontalPadding = 10; diff --git a/src/traces/parcoords/constants.js b/src/traces/parcoords/constants.js deleted file mode 100644 index e276c715a51..00000000000 --- a/src/traces/parcoords/constants.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; - - -module.exports = { - maxDimensionCount: 60, // this cannot be increased without WebGL code refactoring - overdrag: 45, - verticalPadding: 2, // otherwise, horizontal lines on top or bottom are of lower width - tickDistance: 50, - canvasPixelRatio: 1, - blockLineCount: 5000, - layers: ['contextLineLayer', 'focusLineLayer', 'pickLineLayer'], - axisTitleOffset: 28, - axisExtentOffset: 10, - bar: { - width: 4, // Visible width of the filter bar - captureWidth: 10, // Mouse-sensitive width for interaction (Fitts law) - fillColor: 'magenta', // Color of the filter bar fill - fillOpacity: 1, // Filter bar fill opacity - snapDuration: 150, // tween duration in ms for brush snap for ordinal axes - snapRatio: 0.25, // ratio of bar extension relative to the distance between two adjacent ordinal values - snapClose: 0.01, // fraction of inter-value distance to snap to the closer one, even if you're not over it - strokeOpacity: 1, // Filter bar side stroke opacity - strokeWidth: 1, // Filter bar side stroke width in pixels - handleHeight: 8, // Height of the filter bar vertical resize areas on top and bottom - handleOpacity: 1, // Opacity of the filter bar vertical resize areas on top and bottom - handleOverlap: 0 // A larger than 0 value causes overlaps with the filter bar, represented as pixels - }, - cn: { - axisExtentText: 'axis-extent-text', - parcoordsLineLayers: 'parcoords-line-layers', - parcoordsLineLayer: 'parcoords-lines', - parcoords: 'parcoords', - parcoordsControlView: 'parcoords-control-view', - yAxis: 'y-axis', - axisOverlays: 'axis-overlays', - axis: 'axis', - axisHeading: 'axis-heading', - axisTitle: 'axis-title', - axisExtent: 'axis-extent', - axisExtentTop: 'axis-extent-top', - axisExtentTopText: 'axis-extent-top-text', - axisExtentBottom: 'axis-extent-bottom', - axisExtentBottomText: 'axis-extent-bottom-text', - axisBrush: 'axis-brush' - }, - id: { - filterBarPattern: 'filter-bar-pattern' - - } -}; diff --git a/src/traces/parcoords/constants.ts b/src/traces/parcoords/constants.ts new file mode 100644 index 00000000000..15e800ac8f8 --- /dev/null +++ b/src/traces/parcoords/constants.ts @@ -0,0 +1,47 @@ +export const maxDimensionCount = 60; // This cannot be increased without WebGL code refactoring +export const overdrag = 45; +export const verticalPadding = 2; // Otherwise, horizontal lines on top or bottom are of lower width +export const tickDistance = 50; +export const canvasPixelRatio = 1; +export const blockLineCount = 5000; +export const layers = ['contextLineLayer', 'focusLineLayer', 'pickLineLayer'] as const; +export const axisTitleOffset = 28; +export const axisExtentOffset = 10; + +export const bar = { + width: 4, // Visible width of the filter bar + captureWidth: 10, // Mouse-sensitive width for interaction (Fitts law) + fillColor: 'magenta', // Color of the filter bar fill + fillOpacity: 1, // Filter bar fill opacity + snapDuration: 150, // Tween duration in ms for brush snap for ordinal axes + snapRatio: 0.25, // Ratio of bar extension relative to the distance between two adjacent ordinal values + snapClose: 0.01, // Fraction of inter-value distance to snap to the closer one, even if you're not over it + strokeOpacity: 1, // Filter bar side stroke opacity + strokeWidth: 1, // Filter bar side stroke width in pixels + handleHeight: 8, // Height of the filter bar vertical resize areas on top and bottom + handleOpacity: 1, // Opacity of the filter bar vertical resize areas on top and bottom + handleOverlap: 0 // A larger than 0 value causes overlaps with the filter bar, represented as pixels +} as const; + +export const cn = { + axisExtentText: 'axis-extent-text', + parcoordsLineLayers: 'parcoords-line-layers', + parcoordsLineLayer: 'parcoords-lines', + parcoords: 'parcoords', + parcoordsControlView: 'parcoords-control-view', + yAxis: 'y-axis', + axisOverlays: 'axis-overlays', + axis: 'axis', + axisHeading: 'axis-heading', + axisTitle: 'axis-title', + axisExtent: 'axis-extent', + axisExtentTop: 'axis-extent-top', + axisExtentTopText: 'axis-extent-top-text', + axisExtentBottom: 'axis-extent-bottom', + axisExtentBottomText: 'axis-extent-bottom-text', + axisBrush: 'axis-brush' +} as const; + +export const id = { + filterBarPattern: 'filter-bar-pattern' +} as const; diff --git a/src/traces/sankey/constants.js b/src/traces/sankey/constants.js deleted file mode 100644 index c7eda8ca65b..00000000000 --- a/src/traces/sankey/constants.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -module.exports = { - nodeTextOffsetHorizontal: 4, - nodeTextOffsetVertical: 3, - nodePadAcross: 10, - sankeyIterations: 50, - forceIterations: 5, - forceTicksPerFrame: 10, - duration: 500, - ease: 'linear', - cn: { - sankey: 'sankey', - sankeyLinks: 'sankey-links', - sankeyLink: 'sankey-link', - sankeyNodeSet: 'sankey-node-set', - sankeyNode: 'sankey-node', - nodeRect: 'node-rect', - nodeLabel: 'node-label' - } -}; diff --git a/src/traces/sankey/constants.ts b/src/traces/sankey/constants.ts new file mode 100644 index 00000000000..94116c31072 --- /dev/null +++ b/src/traces/sankey/constants.ts @@ -0,0 +1,18 @@ +export const nodeTextOffsetHorizontal = 4; +export const nodeTextOffsetVertical = 3; +export const nodePadAcross = 10; +export const sankeyIterations = 50; +export const forceIterations = 5; +export const forceTicksPerFrame = 10; +export const duration = 500; +export const ease = 'linear'; + +export const cn = { + sankey: 'sankey', + sankeyLinks: 'sankey-links', + sankeyLink: 'sankey-link', + sankeyNodeSet: 'sankey-node-set', + sankeyNode: 'sankey-node', + nodeRect: 'node-rect', + nodeLabel: 'node-label' +} as const; diff --git a/src/traces/scatter/constants.js b/src/traces/scatter/constants.js deleted file mode 100644 index 4499fa5c15c..00000000000 --- a/src/traces/scatter/constants.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -module.exports = { - PTS_LINESONLY: 20, - - // fixed parameters of clustering and clipping algorithms - - // fraction of clustering tolerance "so close we don't even consider it a new point" - minTolerance: 0.2, - // how fast does clustering tolerance increase as you get away from the visible region - toleranceGrowth: 10, - - // number of viewport sizes away from the visible region - // at which we clip all lines to the perimeter - maxScreensAway: 20, - - eventDataKeys: [] -}; diff --git a/src/traces/scatter/constants.ts b/src/traces/scatter/constants.ts new file mode 100644 index 00000000000..7109ba141d5 --- /dev/null +++ b/src/traces/scatter/constants.ts @@ -0,0 +1,14 @@ +export const PTS_LINESONLY = 20; + +// Fixed parameters of clustering and clipping algorithms + +// Fraction of clustering tolerance "so close we don't even consider it a new point" +export const minTolerance = 0.2; +// How fast does clustering tolerance increase as you get away from the visible region +export const toleranceGrowth = 10; + +// Number of viewport sizes away from the visible region +// at which we clip all lines to the perimeter +export const maxScreensAway = 20; + +export const eventDataKeys = [] as const satisfies string[]; diff --git a/src/traces/scattergl/constants.js b/src/traces/scattergl/constants.js deleted file mode 100644 index fc6558406a6..00000000000 --- a/src/traces/scattergl/constants.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -var SYMBOL_SIZE = 20; - -module.exports = { - TOO_MANY_POINTS: 1e5, - - SYMBOL_SDF_SIZE: 200, - SYMBOL_SIZE: SYMBOL_SIZE, - SYMBOL_STROKE: SYMBOL_SIZE / 20, - - DOT_RE: /-dot/, - OPEN_RE: /-open/, - - DASHES: { - solid: [1], - dot: [1, 1], - dash: [4, 1], - longdash: [8, 1], - dashdot: [4, 1, 1, 1], - longdashdot: [8, 1, 1, 1] - } -}; diff --git a/src/traces/scattergl/constants.ts b/src/traces/scattergl/constants.ts new file mode 100644 index 00000000000..1fb11728471 --- /dev/null +++ b/src/traces/scattergl/constants.ts @@ -0,0 +1,19 @@ +import type { Dash } from '../../types/generated/schema'; + +export const TOO_MANY_POINTS = 1e5; + +export const SYMBOL_SDF_SIZE = 200; +export const SYMBOL_SIZE = 20; +export const SYMBOL_STROKE = SYMBOL_SIZE / 20; + +export const DOT_RE = /-dot/; +export const OPEN_RE = /-open/; + +export const DASHES = { + solid: [1], + dot: [1, 1], + dash: [4, 1], + longdash: [8, 1], + dashdot: [4, 1, 1, 1], + longdashdot: [8, 1, 1, 1] +} as const satisfies Record; diff --git a/src/traces/scattermap/constants.js b/src/traces/scattermap/constants.ts similarity index 77% rename from src/traces/scattermap/constants.js rename to src/traces/scattermap/constants.ts index 001af34023e..6519a80b26c 100644 --- a/src/traces/scattermap/constants.js +++ b/src/traces/scattermap/constants.ts @@ -1,8 +1,6 @@ -'use strict'; - // Must use one of the following fonts as the family, else default to 'Open Sans Regular' // See https://github.com/openmaptiles/fonts/blob/gh-pages/fontstacks.json -var supportedFonts = [ +const supportedFonts = [ 'Metropolis Black Italic', 'Metropolis Black', 'Metropolis Bold Italic', @@ -36,10 +34,14 @@ var supportedFonts = [ 'Klokantech Noto Sans CJK Regular', 'Klokantech Noto Sans Italic', 'Klokantech Noto Sans Regular' -]; +] as const; -module.exports = { - isSupportedFont: function(a) { - return supportedFonts.indexOf(a) !== -1; - } -}; +/** + * Test whether the tile server provides the given font family + * + * @param a - Font family name + */ +export function isSupportedFont(a: string) { + // Widen the tuple, because callers pass any font family the user set + return (supportedFonts as readonly string[]).indexOf(a) !== -1; +} diff --git a/src/traces/sunburst/constants.js b/src/traces/sunburst/constants.js deleted file mode 100644 index a39fefeab4b..00000000000 --- a/src/traces/sunburst/constants.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -module.exports = { - CLICK_TRANSITION_TIME: 750, - CLICK_TRANSITION_EASING: 'linear', - eventDataKeys: [ - // string - 'currentPath', - 'root', - 'entry', - // no need to add 'parent' here - - // percentages i.e. ratios - 'percentRoot', - 'percentEntry', - 'percentParent' - ] -}; diff --git a/src/traces/sunburst/constants.ts b/src/traces/sunburst/constants.ts new file mode 100644 index 00000000000..c8ca54d044a --- /dev/null +++ b/src/traces/sunburst/constants.ts @@ -0,0 +1,15 @@ +export const CLICK_TRANSITION_TIME = 750; +export const CLICK_TRANSITION_EASING = 'linear'; + +export const eventDataKeys = [ + // String + 'currentPath', + 'root', + 'entry', + // No need to add 'parent' here + + // Percentages i.e. ratios + 'percentRoot', + 'percentEntry', + 'percentParent' +] as const; diff --git a/src/traces/table/constants.js b/src/traces/table/constants.js deleted file mode 100644 index 5c8747c07d0..00000000000 --- a/src/traces/table/constants.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; - -module.exports = { - cellPad: 8, - columnExtentOffset: 10, - columnTitleOffset: 28, - emptyHeaderHeight: 16, - latexCheck: /^\$.*\$$/, - goldenRatio: 1.618, - lineBreaker: '
', - maxDimensionCount: 60, - overdrag: 45, - releaseTransitionDuration: 120, - releaseTransitionEase: 'cubic-out', - scrollbarCaptureWidth: 18, - scrollbarHideDelay: 1000, - scrollbarHideDuration: 1000, - scrollbarOffset: 5, - scrollbarWidth: 8, - transitionDuration: 100, - transitionEase: 'cubic-out', - uplift: 5, - wrapSpacer: ' ', - wrapSplitCharacter: ' ', - cn: { - // general class names - table: 'table', - tableControlView: 'table-control-view', - scrollBackground: 'scroll-background', - yColumn: 'y-column', - columnBlock: 'column-block', - scrollAreaClip: 'scroll-area-clip', - scrollAreaClipRect: 'scroll-area-clip-rect', - columnBoundary: 'column-boundary', - columnBoundaryClippath: 'column-boundary-clippath', - columnBoundaryRect: 'column-boundary-rect', - columnCells: 'column-cells', - columnCell: 'column-cell', - cellRect: 'cell-rect', - cellText: 'cell-text', - cellTextHolder: 'cell-text-holder', - - // scroll related class names - scrollbarKit: 'scrollbar-kit', - scrollbar: 'scrollbar', - scrollbarSlider: 'scrollbar-slider', - scrollbarGlyph: 'scrollbar-glyph', - scrollbarCaptureZone: 'scrollbar-capture-zone' - } -}; diff --git a/src/traces/table/constants.ts b/src/traces/table/constants.ts new file mode 100644 index 00000000000..6c1e83eb579 --- /dev/null +++ b/src/traces/table/constants.ts @@ -0,0 +1,47 @@ +export const cellPad = 8; +export const columnExtentOffset = 10; +export const columnTitleOffset = 28; +export const emptyHeaderHeight = 16; +export const latexCheck = /^\$.*\$$/; +export const goldenRatio = 1.618; +export const lineBreaker = '
'; +export const maxDimensionCount = 60; +export const overdrag = 45; +export const releaseTransitionDuration = 120; +export const releaseTransitionEase = 'cubic-out'; +export const scrollbarCaptureWidth = 18; +export const scrollbarHideDelay = 1000; +export const scrollbarHideDuration = 1000; +export const scrollbarOffset = 5; +export const scrollbarWidth = 8; +export const transitionDuration = 100; +export const transitionEase = 'cubic-out'; +export const uplift = 5; +export const wrapSpacer = ' '; +export const wrapSplitCharacter = ' '; + +export const cn = { + // General class names + table: 'table', + tableControlView: 'table-control-view', + scrollBackground: 'scroll-background', + yColumn: 'y-column', + columnBlock: 'column-block', + scrollAreaClip: 'scroll-area-clip', + scrollAreaClipRect: 'scroll-area-clip-rect', + columnBoundary: 'column-boundary', + columnBoundaryClippath: 'column-boundary-clippath', + columnBoundaryRect: 'column-boundary-rect', + columnCells: 'column-cells', + columnCell: 'column-cell', + cellRect: 'cell-rect', + cellText: 'cell-text', + cellTextHolder: 'cell-text-holder', + + // Scroll related class names + scrollbarKit: 'scrollbar-kit', + scrollbar: 'scrollbar', + scrollbarSlider: 'scrollbar-slider', + scrollbarGlyph: 'scrollbar-glyph', + scrollbarCaptureZone: 'scrollbar-capture-zone' +} as const; diff --git a/src/traces/treemap/constants.js b/src/traces/treemap/constants.js deleted file mode 100644 index 1437a7f18ff..00000000000 --- a/src/traces/treemap/constants.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -module.exports = { - CLICK_TRANSITION_TIME: 750, - CLICK_TRANSITION_EASING: 'poly', - eventDataKeys: [ - // string - 'currentPath', - 'root', - 'entry', - // no need to add 'parent' here - - // percentages i.e. ratios - 'percentRoot', - 'percentEntry', - 'percentParent' - ], - gapWithPathbar: 1 // i.e. one pixel -}; diff --git a/src/traces/treemap/constants.ts b/src/traces/treemap/constants.ts new file mode 100644 index 00000000000..f3bad7ad37d --- /dev/null +++ b/src/traces/treemap/constants.ts @@ -0,0 +1,17 @@ +export const CLICK_TRANSITION_TIME = 750; +export const CLICK_TRANSITION_EASING = 'poly'; + +export const eventDataKeys = [ + // String + 'currentPath', + 'root', + 'entry', + // No need to add 'parent' here + + // Percentages i.e. ratios + 'percentRoot', + 'percentEntry', + 'percentParent' +] as const; + +export const gapWithPathbar = 1; // i.e. one pixel diff --git a/src/traces/waterfall/constants.js b/src/traces/waterfall/constants.js deleted file mode 100644 index 8562101b091..00000000000 --- a/src/traces/waterfall/constants.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -module.exports = { - eventDataKeys: [ - 'initial', - 'delta', - 'final' - ] -}; diff --git a/src/traces/waterfall/constants.ts b/src/traces/waterfall/constants.ts new file mode 100644 index 00000000000..eee5c04ed96 --- /dev/null +++ b/src/traces/waterfall/constants.ts @@ -0,0 +1,5 @@ +export const eventDataKeys = [ + 'initial', + 'delta', + 'final' +] as const; From 6728a86d642d853debb23e9bc86acf9a3a1018e1 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Mon, 14 Sep 2026 15:27:56 -0600 Subject: [PATCH 2/4] Update imports per TS conversions --- src/traces/indicator/attributes.js | 2 +- src/traces/indicator/defaults.js | 2 +- src/traces/ohlc/attributes.js | 2 +- src/traces/ohlc/hover.js | 2 +- src/traces/scatter3d/attributes.js | 4 ++-- src/traces/scatter3d/convert.js | 4 ++-- src/traces/scatter3d/index.js | 2 +- src/traces/waterfall/defaults.js | 2 +- src/traces/waterfall/hover.js | 2 +- test/jasmine/tests/indicator_test.js | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/traces/indicator/attributes.js b/src/traces/indicator/attributes.js index 8516878c8b7..481ea815256 100644 --- a/src/traces/indicator/attributes.js +++ b/src/traces/indicator/attributes.js @@ -8,7 +8,7 @@ var colorAttrs = require('../../components/color/attributes'); var domainAttrs = require('../../plots/domain').attributes; var axesAttrs = require('../../plots/cartesian/layout_attributes'); var templatedArray = require('../../plot_api/plot_template').templatedArray; -var delta = require('../../constants/delta.js'); +var delta = require('../../constants/delta'); var descriptionOnlyNumbers = require('../../plots/cartesian/axis_format_attributes').descriptionOnlyNumbers; var textFontAttrs = fontAttrs({ diff --git a/src/traces/indicator/defaults.js b/src/traces/indicator/defaults.js index 98b47cb79ac..9e2cbde408e 100644 --- a/src/traces/indicator/defaults.js +++ b/src/traces/indicator/defaults.js @@ -5,7 +5,7 @@ var attributes = require('./attributes'); var handleDomainDefaults = require('../../plots/domain').defaults; var Template = require('../../plot_api/plot_template'); var handleArrayContainerDefaults = require('../../plots/array_container_defaults'); -var cn = require('./constants.js'); +var cn = require('./constants'); var handleTickValueDefaults = require('../../plots/cartesian/tick_value_defaults'); var handleTickMarkDefaults = require('../../plots/cartesian/tick_mark_defaults'); diff --git a/src/traces/ohlc/attributes.js b/src/traces/ohlc/attributes.js index cfc5199f10c..2aafd550753 100644 --- a/src/traces/ohlc/attributes.js +++ b/src/traces/ohlc/attributes.js @@ -6,7 +6,7 @@ var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').ax const { hovertemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes'); var dash = require('../../components/drawing/attributes').dash; var fxAttrs = require('../../components/fx/attributes'); -var delta = require('../../constants/delta.js'); +var delta = require('../../constants/delta'); var INCREASING_COLOR = delta.INCREASING.COLOR; var DECREASING_COLOR = delta.DECREASING.COLOR; diff --git a/src/traces/ohlc/hover.js b/src/traces/ohlc/hover.js index e82aef39f9d..d4682477c00 100644 --- a/src/traces/ohlc/hover.js +++ b/src/traces/ohlc/hover.js @@ -5,7 +5,7 @@ var Lib = require('../../lib'); var Fx = require('../../components/fx'); var Color = require('../../components/color'); var fillText = require('../../lib').fillText; -var delta = require('../../constants/delta.js'); +var delta = require('../../constants/delta'); var DIRSYMBOL = { increasing: delta.INCREASING.SYMBOL, diff --git a/src/traces/scatter3d/attributes.js b/src/traces/scatter3d/attributes.js index 12998d8cfd2..7191d73c1b6 100644 --- a/src/traces/scatter3d/attributes.js +++ b/src/traces/scatter3d/attributes.js @@ -6,9 +6,9 @@ var colorAttributes = require('../../components/colorscale/attributes'); var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat; const { hovertemplateAttrs, texttemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes'); var baseAttrs = require('../../plots/attributes'); -var DASHES = require('../../constants/gl3d_dashes'); +var DASHES = require('../../constants/gl3d_dashes').default; -var MARKER_SYMBOLS = require('../../constants/gl3d_markers'); +var MARKER_SYMBOLS = require('../../constants/gl3d_markers').default; var extendFlat = require('../../lib/extend').extendFlat; var overrideAll = require('../../plot_api/edit_types').overrideAll; var sortObjectKeys = require('../../lib/sort_object_keys').default; diff --git a/src/traces/scatter3d/convert.js b/src/traces/scatter3d/convert.js index fafa4898216..019d362e5fe 100644 --- a/src/traces/scatter3d/convert.js +++ b/src/traces/scatter3d/convert.js @@ -10,8 +10,8 @@ var Lib = require('../../lib'); var str2RgbaArray = require('../../lib/str2rgbarray'); var formatColor = require('../../lib/gl_format_color').formatColor; var makeBubbleSizeFn = require('../scatter/make_bubble_size_func'); -var DASH_PATTERNS = require('../../constants/gl3d_dashes'); -var MARKER_SYMBOLS = require('../../constants/gl3d_markers'); +var DASH_PATTERNS = require('../../constants/gl3d_dashes').default; +var MARKER_SYMBOLS = require('../../constants/gl3d_markers').default; var Axes = require('../../plots/cartesian/axes'); var appendArrayPointValue = require('../../components/fx/helpers').appendArrayPointValue; diff --git a/src/traces/scatter3d/index.js b/src/traces/scatter3d/index.js index bda0bcb9119..cf9d44689da 100644 --- a/src/traces/scatter3d/index.js +++ b/src/traces/scatter3d/index.js @@ -3,7 +3,7 @@ module.exports = { plot: require('./convert'), attributes: require('./attributes'), - markerSymbols: require('../../constants/gl3d_markers'), + markerSymbols: require('../../constants/gl3d_markers').default, supplyDefaults: require('./defaults'), colorbar: [ { diff --git a/src/traces/waterfall/defaults.js b/src/traces/waterfall/defaults.js index 203f7af7ce2..8d501ba9904 100644 --- a/src/traces/waterfall/defaults.js +++ b/src/traces/waterfall/defaults.js @@ -8,7 +8,7 @@ var handleXYDefaults = require('../scatter/xy_defaults'); var handlePeriodDefaults = require('../scatter/period_defaults'); var attributes = require('./attributes'); var Color = require('../../components/color'); -var delta = require('../../constants/delta.js'); +var delta = require('../../constants/delta'); var INCREASING_COLOR = delta.INCREASING.COLOR; var DECREASING_COLOR = delta.DECREASING.COLOR; diff --git a/src/traces/waterfall/hover.js b/src/traces/waterfall/hover.js index 23f38c232d1..0e972d15aef 100644 --- a/src/traces/waterfall/hover.js +++ b/src/traces/waterfall/hover.js @@ -3,7 +3,7 @@ var hoverLabelText = require('../../plots/cartesian/axes').hoverLabelText; var opacity = require('../../components/color').opacity; var hoverOnBars = require('../bar/hover').hoverOnBars; -var delta = require('../../constants/delta.js'); +var delta = require('../../constants/delta'); var DIRSYMBOL = { increasing: delta.INCREASING.SYMBOL, diff --git a/test/jasmine/tests/indicator_test.js b/test/jasmine/tests/indicator_test.js index f5cec7083f4..299743164ad 100644 --- a/test/jasmine/tests/indicator_test.js +++ b/test/jasmine/tests/indicator_test.js @@ -11,7 +11,7 @@ var supplyAllDefaults = require('../assets/supply_defaults'); // var calc = require('../../../src/traces/indicator/calc').calc; var customAssertions = require('../assets/custom_assertions.js'); var indicatorAttrs = require('../../../src/traces/indicator/attributes.js'); -var cn = require('../../../src/traces/indicator/constants.js'); +var cn = require('../../../src/traces/indicator/constants'); describe('Indicator defaults', function() { function _supply(trace, layout) { From abf4d0498e8a97e0adf9a1b7f49274829a14fedf Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Mon, 14 Sep 2026 15:33:15 -0600 Subject: [PATCH 3/4] Update docstring formatting --- src/lib/clean_number.ts | 2 +- src/lib/mod.ts | 8 +++--- src/lib/regex.ts | 16 ++++++------ src/lib/sort_object_keys.ts | 2 +- src/plots/map/get_map_fit_bounds.ts | 2 +- src/types/core/api.d.ts | 38 ++++++++++++++--------------- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/lib/clean_number.ts b/src/lib/clean_number.ts index 7a09394bfa9..0a348e8e578 100644 --- a/src/lib/clean_number.ts +++ b/src/lib/clean_number.ts @@ -10,7 +10,7 @@ const JUNK = /^['"%,$#\s']+|[, ]|['"%,$#\s']+$/g; * Remove common leading and trailing cruft from a value and coerce it to a number. * Always returns either a number or BADNUM. * - * @param v - value to clean; strings have leading/trailing junk characters stripped before numeric coercion + * @param v - Value to clean; strings have leading/trailing junk characters stripped before numeric coercion */ function cleanNumber(v: any): number | undefined { if (typeof v === 'string') v = v.replace(JUNK, ''); diff --git a/src/lib/mod.ts b/src/lib/mod.ts index 3da79bd27d9..0317952fa17 100644 --- a/src/lib/mod.ts +++ b/src/lib/mod.ts @@ -4,8 +4,8 @@ * Sanitized modulus function that always returns in the range [0, d) * rather than (-d, 0] if v is negative. * - * @param v - dividend - * @param d - divisor (the modulus); assumed positive + * @param v - Dividend + * @param d - Divisor (the modulus); assumed positive */ export function mod(v: number, d: number) { const out = v % d; @@ -16,8 +16,8 @@ export function mod(v: number, d: number) { * Sanitized modulus function that always returns in the range [-d/2, d/2] * rather than (-d, 0] if v is negative. * - * @param v - dividend - * @param d - divisor (the modulus); assumed positive + * @param v - Dividend + * @param d - Divisor (the modulus); assumed positive */ export function modHalf(v: number, d: number) { return Math.abs(v) > d / 2 ? v - Math.round(v / d) * d : v; diff --git a/src/lib/regex.ts b/src/lib/regex.ts index 9dc24007b44..d63c3bf7d97 100644 --- a/src/lib/regex.ts +++ b/src/lib/regex.ts @@ -3,16 +3,16 @@ const NUMBER_REGEX = '([2-9]|[1-9][0-9]+)?'; /** - * make a regex for matching counter ids/names ie xaxis, xaxis2, xaxis10... + * Make a regex for matching counter ids/names, for example xaxis, xaxis2, xaxis10 * - * @param head - the head of the pattern, eg 'x' matches 'x', 'x2', 'x10' etc. - * 'xy' is a special case for cartesian subplots: it matches 'x2y3' etc - * @param tail - a fixed piece after the id - * eg counterRegex('scene', '.annotations') for scene2.annotations etc. - * @param openEnded - if true, the string may continue past the match. - * @param matchBeginning - if false, the string may start before the match. + * @param head - The head of the pattern, for example 'x' matches 'x', 'x2', 'x10'. + * 'xy' is a special case for cartesian subplots: it matches 'x2y3'. + * @param tail - A fixed piece after the id. + * For example, counterRegex('scene', '.annotations') for scene2.annotations. + * @param openEnded - If true, the string may continue past the match + * @param matchBeginning - If false, the string may start before the match */ -export function counter(head: string, tail: string = '', openEnded: boolean, matchBeginning: boolean) { +export function counter(head: string, tail: string = '', openEnded?: boolean, matchBeginning?: boolean) { const fullTail = tail + (openEnded ? '' : '$'); const startWithPrefix = matchBeginning === false ? '' : '^'; return head === 'xy' diff --git a/src/lib/sort_object_keys.ts b/src/lib/sort_object_keys.ts index 9984da1c737..9a7660e52e1 100644 --- a/src/lib/sort_object_keys.ts +++ b/src/lib/sort_object_keys.ts @@ -3,7 +3,7 @@ /** * Return the keys of an object in lexicographic (default `Array.prototype.sort`) order. * - * @param obj - object whose own enumerable keys will be listed and sorted + * @param obj - Object whose own enumerable keys will be listed and sorted */ function sortObjectKeys(obj: Record) { return Object.keys(obj).sort(); diff --git a/src/plots/map/get_map_fit_bounds.ts b/src/plots/map/get_map_fit_bounds.ts index 6df7f28f1f5..2560292692e 100644 --- a/src/plots/map/get_map_fit_bounds.ts +++ b/src/plots/map/get_map_fit_bounds.ts @@ -24,7 +24,7 @@ interface FitBoundsTrace extends Pick { * that isn't implemented here. * * @param fullData - The full data array (post supply-defaults) - * @param subplotId - e.g. `'map'`, `'map2'` + * @param subplotId - Subplot id, for example `'map'` or `'map2'` */ export function getMapFitBounds(fullData: FitBoundsTrace[], subplotId: string): LonLatBox | null { const coordinates: [number, number][] = []; diff --git a/src/types/core/api.d.ts b/src/types/core/api.d.ts index aa2f4bf38b0..4f9f73d2ffb 100644 --- a/src/types/core/api.d.ts +++ b/src/types/core/api.d.ts @@ -183,11 +183,11 @@ export interface ValidateTemplateResult { /** * Create a new plot at `root`. Replaces any existing plot. * - * @param root - graph div id or element - * @param data - trace data array - * @param layout - layout overrides - * @param config - config overrides - * @returns the graph div once the plot has rendered + * @param root - Graph div id or element + * @param data - Trace data array + * @param layout - Layout overrides + * @param config - Config overrides + * @returns The graph div once the plot has rendered */ export function newPlot( root: Root, @@ -199,9 +199,9 @@ export function newPlot( * Create a new plot at `root` from a figure-shaped object containing * `data`/`layout`/`config`/`frames`. Replaces any existing plot. * - * @param root - graph div id or element - * @param figure - figure-shaped object - * @returns the graph div once the plot has rendered + * @param root - Graph div id or element + * @param figure - Figure-shaped object + * @returns The graph div once the plot has rendered */ export function newPlot( root: Root, @@ -217,17 +217,17 @@ export function purge(root: Root): void; /** * Update trace properties (style) on the existing plot. * - * @param aobj - update object whose keys are attribute paths - * @param traces - trace index/indices to update (defaults to all) + * @param aobj - Update object whose keys are attribute paths + * @param traces - Trace index/indices to update (defaults to all) */ export function restyle(root: Root, aobj: Data, traces?: number[] | number): Promise; /** * Update both trace and layout properties in a single call. * - * @param traceUpdate - per-trace updates - * @param layoutUpdate - layout updates - * @param traces - trace index/indices `traceUpdate` applies to + * @param traceUpdate - Per-trace updates + * @param layoutUpdate - Layout updates + * @param traces - Trace index/indices `traceUpdate` applies to */ export function update( root: Root, @@ -239,8 +239,8 @@ export function update( /** * Add one or more traces to an existing plot. * - * @param traces - trace(s) to add - * @param newIndices - position(s) in `data` where the traces should land + * @param traces - Trace(s) to add + * @param newIndices - Position(s) in `data` where the traces should land */ export function addTraces( root: Root, @@ -254,8 +254,8 @@ export function deleteTraces(root: Root, indices: number[] | number): Promise Date: Mon, 14 Sep 2026 15:51:22 -0600 Subject: [PATCH 4/4] Update rivers/lake order in choropleth layers --- src/plots/geo/constants.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plots/geo/constants.ts b/src/plots/geo/constants.ts index 1731a1d4a21..352e78b87f8 100644 --- a/src/plots/geo/constants.ts +++ b/src/plots/geo/constants.ts @@ -298,7 +298,8 @@ type SameLength = { [K in keyof T]: V }; /** A draw order holding the same layers as `layers`: same length, and every element is a layer */ type LayerOrder = SameLength; -// Same layers as `layers`, but rivers and lakes move above the choropleth so water stays visible +// Same layers as `layers`, but lakes and rivers move above the choropleth so water stays visible. +// They keep their order relative to each other, so rivers draw over lakes either way. export const layersForChoropleth = [ 'bg', 'ocean', @@ -310,8 +311,8 @@ export const layersForChoropleth = [ 'lonaxis', 'frame', 'backplot', - 'rivers', 'lakes', + 'rivers', 'frontplot' ] as const satisfies LayerOrder;