diff --git a/draftlogs/7945_change.md b/draftlogs/7945_change.md new file mode 100644 index 00000000000..1ae16af1b70 --- /dev/null +++ b/draftlogs/7945_change.md @@ -0,0 +1 @@ +- Rename `quiver` trace attributes for clarity and consistency: `sizeref` -> `lengthfactor`, `sizemode` -> `lengthmode`, `anglemode` -> `uvref` [[#7945](https://github.com/plotly/plotly.js/issues/7945)] diff --git a/src/traces/quiver/attributes.js b/src/traces/quiver/attributes.js index 27d9e269935..6951ee99e96 100644 --- a/src/traces/quiver/attributes.js +++ b/src/traces/quiver/attributes.js @@ -14,7 +14,7 @@ var attrs = { valType: 'data_array', editType: 'calc+clearAxisTypes', anim: true, - description: 'Sets the x coordinates of the arrow locations.' + description: 'Sets the x coordinates of the vector arrow locations.' }, x0: scatterAttrs.x0, dx: scatterAttrs.dx, @@ -22,7 +22,7 @@ var attrs = { valType: 'data_array', editType: 'calc+clearAxisTypes', anim: true, - description: 'Sets the y coordinates of the arrow locations.' + description: 'Sets the y coordinates of the vector arrow locations.' }, y0: scatterAttrs.y0, dy: scatterAttrs.dy, @@ -30,46 +30,47 @@ var attrs = { valType: 'data_array', editType: 'calc', anim: true, - description: 'Sets the x components of the arrow vectors.' + description: 'Sets the x components of the vector arrows.' }, v: { valType: 'data_array', editType: 'calc', anim: true, - description: 'Sets the y components of the arrow vectors.' + description: 'Sets the y components of the vector arrows.' }, - anglemode: { + uvref: { valType: 'enumerated', values: ['paper', 'data'], - dflt: 'axis', + dflt: 'data', editType: 'calc', description: [ - 'Sets the mode used to determine the angle of the arrow vectors.', + 'Determines how the u/v vector components are interpreted.', 'If *paper*, u/v are interpreted in pixel coordinates and the rendered vector angle', - 'does not change regardless of the axes scales.', + 'does not change regardless of the axis scales.', 'If *data*, u/v are interpreted in data coordinates and the rendered vector angle', 'may change, e.g. if zooming in along a single axis' ].join(' ') }, - sizemode: { + lengthmode: { valType: 'enumerated', values: ['scaled', 'raw'], editType: 'calc', dflt: 'scaled', description: [ - 'Determines whether arrows are drawn according to their raw lengths,', - 'or scaled based on the maximum vector length and point density. Note: When `anglemode` is *data*', - 'arrows are alwyas scaled and `sizemode` *raw* is ignored.', + 'Determines whether vector arrows are drawn according to their raw lengths,', + 'or scaled based on the maximum vector length and point density. Note: When `uvref` is *paper*', + 'vectors are always scaled and `lengthmode` *raw* is ignored.' ].join(' ') }, - sizeref: { + lengthfactor: { valType: 'number', min: 0, editType: 'calc', dflt: 1, description: [ - 'Adjusts the arrow size scaling. The arrow length is determined by the vector norm multiplied by `sizeref`,', - 'optionally normalized when `sizemode` is *scaled* (`sizeref` is applied after scaling).' + 'Adjusts the drawn length of the vector arrows. The arrow length is determined by', + 'the values of u and v, then optionally rescaled when `lengthmode` is *scaled*,', + 'then multiplied by `lengthfactor`.', ].join(' ') }, anchor: { @@ -78,9 +79,9 @@ var attrs = { dflt: 'tail', editType: 'calc', description: [ - 'Sets the arrows\' anchor with respect to their (x,y) positions.', + 'Sets the vector arrows\' anchor with respect to their (x,y) positions.', 'Use *tail* to place (x,y) at the base, *tip* to place (x,y) at the head,', - 'or *center* to center the arrow on (x,y).' + 'or *center* to center the vector arrow on (x,y).' ].join(' ') }, xhoverformat: axisHoverFormat('x'), @@ -107,7 +108,7 @@ var attrs = { arrowsize: extendFlat({}, annotationAttrs.arrowsize, { editType: 'calc', description: [ - 'Sets the size of the arrow head relative to `marker.line.width`.', + 'Sets the size of the vector arrowhead relative to `marker.line.width`.', 'A value of 1 (default) gives a head about 3x as wide as the line.' ].join(' ') }), @@ -117,7 +118,7 @@ var attrs = { min: 0, dflt: 2, editType: 'style', - description: 'Sets the width (in px) of the arrow lines.' + description: 'Sets the width (in px) of the vector arrow lines.' }, dash: dash, editType: 'style' diff --git a/src/traces/quiver/calc.js b/src/traces/quiver/calc.js index 2b7e6b7253a..03c42c982e8 100644 --- a/src/traces/quiver/calc.js +++ b/src/traces/quiver/calc.js @@ -33,8 +33,8 @@ module.exports = function calc(gd, trace) { const uArr = trace.u || []; const vArr = trace.v || []; - const anglemode = trace.anglemode; - const sizemode = trace.sizemode; + const uvref = trace.uvref; + const lengthmode = trace.lengthmode; const anchor = trace.anchor; const isTip = anchor === 'tip'; const isCenter = anchor === 'center'; @@ -54,7 +54,7 @@ module.exports = function calc(gd, trace) { var nValid = 0; // First pass: build calcdata, and keep track of the maximum and minimum vector norm in the trace, - // to be used for sizemode 'scaled' (max norm only) and for magnitude-based colorscale range + // to be used for lengthmode 'scaled' (max norm only) and for magnitude-based colorscale range for(var i = 0; i < len; i++) { var cdi = cd[i] = { i: i }; var xValid = isNumeric(xVals[i]); @@ -109,19 +109,19 @@ module.exports = function calc(gd, trace) { // Store maxNorm for use by plot step trace._maxNorm = normMax; - if (sizemode === 'scaled' || anglemode === 'paper') { - // Ignore sizemode 'raw' if anglemode is set to 'paper': always scale + if (lengthmode === 'scaled' || uvref === 'paper') { + // Ignore lengthmode 'raw' if uvref is set to 'paper': always scale // Compute point density of the entire trace: Area of bounding box // divided by number of points. This is used to scale arrows in - // 'scaled' sizemode. + // 'scaled' lengthmode. // TODO: How to handle the case where there is just one point in a trace, // or all points have the same x or y value? This will give a boxArea of 0. // For now I'm going to just normalize to a vector of unit length (1) in that case, // but that's not a great solution const boxArea = (xMax - xMin) * (yMax - yMin); const pointDensity = boxArea / len; - // Now, compute the scale factor for scaled size mode + // Now, compute the scale factor for scaled length mode // The scale factor should be such that // _maxNorm * _scaleFactor = Math.sqrt(_pointDensity) // Therefore: _scaleFactor = Math.sqrt(_pointDensity) / _maxNorm @@ -130,16 +130,16 @@ module.exports = function calc(gd, trace) { } else { trace._scaleFactor = Math.sqrt(pointDensity) / trace._maxNorm; } - // Note: If anglemode === 'paper', this scale factor must be + // Note: If uvref === 'paper', this scale factor must be // multiplied by Math.sqrt(xa._m * ya._m), but we can't do that quite yet // since the axis scales are not fully determined. Do it in plot step instead. - } else { // sizemode === 'raw' - // For raw sizemode, scale factor is always 1 + } else { // lengthmode === 'raw' + // For raw lengthmode, scale factor is always 1 trace._scaleFactor = 1; } - // Multiply scale factor by sizeref - trace._scaleFactor *= trace.sizeref; + // Multiply computed scale factor by lengthfactor attr + trace._scaleFactor *= trace.lengthfactor; // Now we need to compute the arrow geometry for axis autorange const xTipPositions = new Array(len); @@ -148,7 +148,7 @@ module.exports = function calc(gd, trace) { const yTailPositions = new Array(len); var arrowLenX, arrowLenY; // Compute the x- and y-positions of the tip of each arrow, - // assuming anglemode === 'data' (i.e. u/v are in data coordinates) + // assuming uvref === 'data' (i.e. u/v are in data coordinates) for(var i = 0; i < len; i++) { var cdi = cd[i]; arrowLenX = cdi._u * trace._scaleFactor; @@ -171,12 +171,12 @@ module.exports = function calc(gd, trace) { } } - if (anglemode === 'data') { - // If anglemode is 'data', we can use the arrow tip positions directly to expand the axes ranges + if (uvref === 'data') { + // If uvref is 'data', we can use the arrow tip positions directly to expand the axes ranges trace._extremes[xa._id] = Axes.findExtremes(xa, xTipPositions.concat(xTailPositions), {padded: true}); trace._extremes[ya._id] = Axes.findExtremes(ya, yTipPositions.concat(yTailPositions), {padded: true}); - } else { // anglemode === 'paper' - // TODO: For now, just do the same thing as for anglemode === 'data', but this is not correct. + } else { // uvref === 'paper' + // TODO: For now, just do the same thing as for uvref === 'data', but this is not correct. // We actually need more sophisticated logic here, since this will give a bad result // if the data aspect ratio is very different from the plot aspect ratio. trace._extremes[xa._id] = Axes.findExtremes(xa, xTipPositions.concat(xTailPositions), {padded: true}); diff --git a/src/traces/quiver/defaults.js b/src/traces/quiver/defaults.js index 43ba6973803..a74d4d92a82 100644 --- a/src/traces/quiver/defaults.js +++ b/src/traces/quiver/defaults.js @@ -30,11 +30,11 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout for(var j = 0; j < len; j++) traceOut.v[j] = 0; } - coerce('anglemode'); + coerce('uvref'); // Sizing API inspired by cone, but not identical - coerce('sizemode'); - coerce('sizeref'); + coerce('lengthmode'); + coerce('lengthfactor'); coerce('anchor'); // Arrow styling diff --git a/src/traces/quiver/plot.js b/src/traces/quiver/plot.js index 55ff64b43b6..37226831ee0 100644 --- a/src/traces/quiver/plot.js +++ b/src/traces/quiver/plot.js @@ -103,13 +103,11 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition // Use maxNorm precomputed in calc const maxNorm = trace._maxNorm || 0; - const anglemode = trace.anglemode; - const sizemode = trace.sizemode; - const sizeref = trace.sizeref; + const uvref = trace.uvref; const anchor = trace.anchor; - // Adjust scale factor if anglemode is 'paper' - const scaleFactor = (anglemode === 'paper') ? trace._scaleFactor * Math.sqrt(Math.abs(xa._m * ya._m)) : trace._scaleFactor; + // Adjust scale factor if uvref is 'paper' + const scaleFactor = (uvref === 'paper') ? trace._scaleFactor * Math.sqrt(Math.abs(xa._m * ya._m)) : trace._scaleFactor; const markerArrowsize = trace.marker.arrowsize; // Update line segments @@ -123,12 +121,12 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition } // Compute pixel location of vector tip, *relative to* vector base (before scaling). - // If anglemode is 'paper', then u/v are interpreted in pixel coordinates, so we can use them directly. - // If anglemode is 'data', then u/v are interpreted in data coordinates, so we need to convert them to pixel coordinates. + // If uvref is 'paper', then u/v are interpreted in pixel coordinates, so we can use them directly. + // If uvref is 'data', then u/v are interpreted in data coordinates, so we need to convert them to pixel coordinates. // TODO: This probably doesn't work for log axes, but let's ignore log axes for now // since I'm not sure they make sense for quiver plots anyway - const pu = ((anglemode === 'paper') ? cdi._u * Math.sign(xa._m) : d3.round(xa._m * cdi._u)) * scaleFactor; - const pv = ((anglemode === 'paper') ? cdi._v * Math.sign(ya._m) : d3.round(ya._m * cdi._v)) * scaleFactor; + const pu = ((uvref === 'paper') ? cdi._u * Math.sign(xa._m) : d3.round(xa._m * cdi._u)) * scaleFactor; + const pv = ((uvref === 'paper') ? cdi._v * Math.sign(ya._m) : d3.round(ya._m * cdi._v)) * scaleFactor; // Compute arrow in data space // Check whether arrowsize was set explicitly in the input trace diff --git a/src/types/generated/schema.d.ts b/src/types/generated/schema.d.ts index a0fe3258807..84848ae045e 100644 --- a/src/types/generated/schema.d.ts +++ b/src/types/generated/schema.d.ts @@ -6680,15 +6680,10 @@ export interface PieData { export interface QuiverData { /** - * Sets the arrows' anchor with respect to their (x,y) positions. Use *tail* to place (x,y) at the base, *tip* to place (x,y) at the head, or *center* to center the arrow on (x,y). + * Sets the vector arrows' anchor with respect to their (x,y) positions. Use *tail* to place (x,y) at the base, *tip* to place (x,y) at the head, or *center* to center the vector arrow on (x,y). * @default 'tail' */ anchor?: 'tip' | 'tail' | 'center'; - /** - * Sets the mode used to determine the angle of the arrow vectors. If *paper*, u/v are interpreted in pixel coordinates and the rendered vector angle does not change regardless of the axes scales. If *data*, u/v are interpreted in data coordinates and the rendered vector angle may change, e.g. if zooming in along a single axis - * @default 'axis' - */ - anglemode?: 'paper' | 'data'; /** Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, *scatter* traces also appends customdata items in the markers DOM elements */ customdata?: Datum[] | Datum[][] | TypedArray; /** @@ -6729,9 +6724,20 @@ export interface QuiverData { * Minimum: 0 */ legendwidth?: number; + /** + * Adjusts the drawn length of the vector arrows. The arrow length is determined by the values of u and v, then optionally rescaled when `lengthmode` is *scaled*, then multiplied by `lengthfactor`. + * @default 1 + * Minimum: 0 + */ + lengthfactor?: number; + /** + * Determines whether vector arrows are drawn according to their raw lengths, or scaled based on the maximum vector length and point density. Note: When `uvref` is *paper* vectors are always scaled and `lengthmode` *raw* is ignored. + * @default 'scaled' + */ + lengthmode?: 'scaled' | 'raw'; marker?: { /** - * Sets the size of the arrow head relative to `marker.line.width`. A value of 1 (default) gives a head about 3x as wide as the line. + * Sets the size of the vector arrowhead relative to `marker.line.width`. A value of 1 (default) gives a head about 3x as wide as the line. * @default 1 * Minimum: 0.3 */ @@ -6775,7 +6781,7 @@ export interface QuiverData { */ dash?: Dash; /** - * Sets the width (in px) of the arrow lines. + * Sets the width (in px) of the vector arrow lines. * @default 2 * Minimum: 0 */ @@ -6817,17 +6823,6 @@ export interface QuiverData { * @default true */ showlegend?: boolean; - /** - * Determines whether arrows are drawn according to their raw lengths, or scaled based on the maximum vector length and point density. Note: When `anglemode` is *data* arrows are alwyas scaled and `sizemode` *raw* is ignored. - * @default 'scaled' - */ - sizemode?: 'scaled' | 'raw'; - /** - * Adjusts the arrow size scaling. The arrow length is determined by the vector norm multiplied by `sizeref`, optionally normalized when `sizemode` is *scaled* (`sizeref` is applied after scaling). - * @default 1 - * Minimum: 0 - */ - sizeref?: number; /** Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates. If trace `hoverinfo` contains a *text* flag and *hovertext* is not set, these elements will be seen in the hover labels. */ text?: string | string[]; /** Sets the text font. */ @@ -6838,7 +6833,7 @@ export interface QuiverData { */ textposition?: 'top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right' | ('top left' | 'top center' | 'top right' | 'middle left' | 'middle center' | 'middle right' | 'bottom left' | 'bottom center' | 'bottom right')[]; type?: 'quiver'; - /** Sets the x components of the arrow vectors. */ + /** Sets the x components of the vector arrows. */ u?: Datum[] | Datum[][] | TypedArray; /** Sets the hover text formatting rule for `u` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. */ uhoverformat?: string; @@ -6854,7 +6849,12 @@ export interface QuiverData { }; textfont?: Font; }; - /** Sets the y components of the arrow vectors. */ + /** + * Determines how the u/v vector components are interpreted. If *paper*, u/v are interpreted in pixel coordinates and the rendered vector angle does not change regardless of the axis scales. If *data*, u/v are interpreted in data coordinates and the rendered vector angle may change, e.g. if zooming in along a single axis + * @default 'data' + */ + uvref?: 'paper' | 'data'; + /** Sets the y components of the vector arrows. */ v?: Datum[] | Datum[][] | TypedArray; /** Sets the hover text formatting rule for `v` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. */ vhoverformat?: string; @@ -6863,7 +6863,7 @@ export interface QuiverData { * @default true */ visible?: true | false | 'legendonly'; - /** Sets the x coordinates of the arrow locations. */ + /** Sets the x coordinates of the vector arrow locations. */ x?: Datum[] | Datum[][] | TypedArray; /** * Alternate to `x`. Builds a linear space of x coordinates. Use with `dx` where `x0` is the starting coordinate and `dx` the step. @@ -6877,7 +6877,7 @@ export interface QuiverData { xaxis?: string; /** Sets the hover text formatting rule for `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: *%h* for half of the year as a decimal number as well as *%{n}f* for fractional seconds with n digits. For example, *2016-10-13 09:15:23.456* with tickformat *%H~%M~%S.%2f* would display *09~15~23.46*By default the values are formatted using `xaxis.hoverformat`. */ xhoverformat?: string; - /** Sets the y coordinates of the arrow locations. */ + /** Sets the y coordinates of the vector arrow locations. */ y?: Datum[] | Datum[][] | TypedArray; /** * Alternate to `y`. Builds a linear space of y coordinates. Use with `dy` where `y0` is the starting coordinate and `dy` the step. diff --git a/test/image/baselines/quiver_lengthmode.png b/test/image/baselines/quiver_lengthmode.png new file mode 100644 index 00000000000..633c59bff7e Binary files /dev/null and b/test/image/baselines/quiver_lengthmode.png differ diff --git a/test/image/baselines/quiver_sizemode.png b/test/image/baselines/quiver_sizemode.png deleted file mode 100644 index 35a1160b3cd..00000000000 Binary files a/test/image/baselines/quiver_sizemode.png and /dev/null differ diff --git a/test/image/mocks/quiver_anchor.json b/test/image/mocks/quiver_anchor.json index ff1eb3bd12b..d858c740434 100644 --- a/test/image/mocks/quiver_anchor.json +++ b/test/image/mocks/quiver_anchor.json @@ -7,7 +7,7 @@ "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 1, 1, 1, 1, 1, 1, 1, 1], "v": [1, 1, 1, 1, 1, 1, 1, 1, 1], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail", "marker": { "color": "#4466ee", @@ -23,7 +23,7 @@ "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 1, 1, 1, 1, 1, 1, 1, 1], "v": [1, 1, 1, 1, 1, 1, 1, 1, 1], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tip", "marker": { "color": "#ee3344", @@ -39,7 +39,7 @@ "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 1, 1, 1, 1, 1, 1, 1, 1], "v": [1, 1, 1, 1, 1, 1, 1, 1, 1], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "center", "marker": { "color": "#8811cc", diff --git a/test/image/mocks/quiver_categorical.json b/test/image/mocks/quiver_categorical.json index f5b9b629c7a..fd5b3ce90a6 100644 --- a/test/image/mocks/quiver_categorical.json +++ b/test/image/mocks/quiver_categorical.json @@ -9,7 +9,7 @@ "text": ["A", "B", "C", "D", "E", "F", "G", "H", "I"], "textposition": "top center", "textfont": { "size": 12 }, - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail", "marker": { "line": {"width": 2} diff --git a/test/image/mocks/quiver_colorscale.json b/test/image/mocks/quiver_colorscale.json index bfa3e432279..32c3fe09d9d 100644 --- a/test/image/mocks/quiver_colorscale.json +++ b/test/image/mocks/quiver_colorscale.json @@ -6,9 +6,9 @@ "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 2, 3, 1, 2, 3, 1, 2, 3], "v": [1, 1, 1, 2, 2, 2, 3, 3, 3], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail", - "anglemode": "paper", + "uvref": "paper", "marker": { "showscale": true, "colorbar": { diff --git a/test/image/mocks/quiver_custom-colorscale.json b/test/image/mocks/quiver_custom-colorscale.json index 30f407331da..68f740b6aea 100644 --- a/test/image/mocks/quiver_custom-colorscale.json +++ b/test/image/mocks/quiver_custom-colorscale.json @@ -20,7 +20,7 @@ }, "line": {"width": 2} }, - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail" } ], diff --git a/test/image/mocks/quiver_sizemode.json b/test/image/mocks/quiver_lengthmode.json similarity index 82% rename from test/image/mocks/quiver_sizemode.json rename to test/image/mocks/quiver_lengthmode.json index f328399af18..ff809635027 100644 --- a/test/image/mocks/quiver_sizemode.json +++ b/test/image/mocks/quiver_lengthmode.json @@ -7,7 +7,7 @@ "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 2, 3, 1, 2, 3, 1, 2, 3], "v": [1, 1, 1, 1, 1, 1, 1, 1, 1], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail", "marker": { "color": "red", @@ -18,13 +18,13 @@ }, { "type": "quiver", - "name": "raw (sizeref=1.2)", + "name": "raw (lengthfactor=1.2)", "x": [0, 1, 2, 0, 1, 2, 0, 1, 2], "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 2, 3, 1, 2, 3, 1, 2, 3], "v": [1, 1, 1, 1, 1, 1, 1, 1, 1], - "sizemode": "raw", - "sizeref": 1.2, + "lengthmode": "raw", + "lengthfactor": 1.2, "anchor": "tail", "marker": { "color": "blue", @@ -35,13 +35,13 @@ }, { "type": "quiver", - "name": "raw (sizeref=0.6)", + "name": "raw (lengthfactor=0.6)", "x": [0, 1, 2, 0, 1, 2, 0, 1, 2], "y": [0, 0, 0, 1, 1, 1, 2, 2, 2], "u": [1, 2, 3, 1, 2, 3, 1, 2, 3], "v": [1, 1, 1, 1, 1, 1, 1, 1, 1], - "sizemode": "raw", - "sizeref": 0.6, + "lengthmode": "raw", + "lengthfactor": 0.6, "anchor": "tail", "marker": { "color": "green", @@ -64,7 +64,7 @@ }, "xaxis2": { "domain": [0.35, 0.65], - "title": {"text": "raw (sizeref=1.2)"} + "title": {"text": "raw (lengthfactor=1.2)"} }, "yaxis2": { "domain": [0, 1], @@ -72,7 +72,7 @@ }, "xaxis3": { "domain": [0.7, 1], - "title": {"text": "raw (sizeref=0.6)"} + "title": {"text": "raw (lengthfactor=0.6)"} }, "yaxis3": { "domain": [0, 1], diff --git a/test/image/mocks/quiver_multi-trace.json b/test/image/mocks/quiver_multi-trace.json index 08fb36bf386..b711d4c5e46 100644 --- a/test/image/mocks/quiver_multi-trace.json +++ b/test/image/mocks/quiver_multi-trace.json @@ -7,7 +7,7 @@ "y": [0, 0, 0, 1, 1, 1], "u": [1, 1.5, 2, 1, 1.5, 2], "v": [0.5, 1, 0.5, 1, 1.5, 1], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail", "marker": { "color": "red", @@ -21,7 +21,7 @@ "y": [0, 0, 0, 1, 1, 1], "u": [-1, -1.5, -2, -1, -1.5, -2], "v": [1, 0.5, 1, 0.5, 1, 0.5], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "tail", "marker": { "color": "blue", diff --git a/test/image/mocks/quiver_wind.json b/test/image/mocks/quiver_wind.json index 71bb062a139..d3474b38eea 100644 --- a/test/image/mocks/quiver_wind.json +++ b/test/image/mocks/quiver_wind.json @@ -23,7 +23,7 @@ 0.8, 1.2, 1.5, 1.8, 2, 1.8, 1.5, 0.5, 0.8, 1.2, 1.5, 1.8, 1.5, 1.2, 0.2, 0.5, 0.8, 1.2, 1.5, 1.2, 0.8], - "sizemode": "scaled", + "lengthmode": "scaled", "anchor": "center", "marker": { "colorscale": "Jet", diff --git a/test/jasmine/tests/quiver_test.js b/test/jasmine/tests/quiver_test.js index 7acffc73e12..1e4ad401b5d 100644 --- a/test/jasmine/tests/quiver_test.js +++ b/test/jasmine/tests/quiver_test.js @@ -95,11 +95,17 @@ describe('Test quiver defaults', function() { expect(gd._fullData[0].v).toEqual([0, 0, 0]); }); - it('should set sizemode and sizeref defaults correctly', function() { + it('should set lengthmode and lengthfactor defaults correctly', function() { gd = makeGD(); supplyAllDefaults(gd); - expect(gd._fullData[0].sizemode).toBe('scaled'); - expect(gd._fullData[0].sizeref).toBe(1); + expect(gd._fullData[0].lengthmode).toBe('scaled'); + expect(gd._fullData[0].lengthfactor).toBe(1); + }); + + it('should set uvref default to data', function() { + gd = makeGD(); + supplyAllDefaults(gd); + expect(gd._fullData[0].uvref).toBe('data'); }); it('should set anchor default to tail', function() { @@ -220,13 +226,13 @@ describe('Test quiver interactions', function() { y: [1, 2], u: [1, 0], v: [0, 1], - sizeref: 0.5 + lengthfactor: 0.5 }]).then(function() { - expect(gd._fullData[0].sizeref).toBe(0.5); - return Plotly.restyle(gd, 'sizeref', 1.5); + expect(gd._fullData[0].lengthfactor).toBe(0.5); + return Plotly.restyle(gd, 'lengthfactor', 1.5); }) .then(function() { - expect(gd._fullData[0].sizeref).toBe(1.5); + expect(gd._fullData[0].lengthfactor).toBe(1.5); return Plotly.restyle(gd, 'anchor', 'tip'); }) .then(function() { @@ -293,25 +299,25 @@ describe('Test quiver interactions', function() { .then(done, done.fail); }); - it('should handle sizemode changes', function(done) { + it('should handle lengthmode changes', function(done) { Plotly.newPlot(gd, [{ type: 'quiver', x: [0, 1, 2], y: [0, 1, 2], u: [1, 2, 3], v: [1, 2, 3], - sizemode: 'scaled', - sizeref: 0.5 + lengthmode: 'scaled', + lengthfactor: 0.5 }]).then(function() { - expect(gd._fullData[0].sizemode).toBe('scaled'); - return Plotly.restyle(gd, 'sizemode', 'raw'); + expect(gd._fullData[0].lengthmode).toBe('scaled'); + return Plotly.restyle(gd, 'lengthmode', 'raw'); }) .then(function() { - expect(gd._fullData[0].sizemode).toBe('raw'); - return Plotly.restyle(gd, 'sizemode', 'scaled'); + expect(gd._fullData[0].lengthmode).toBe('raw'); + return Plotly.restyle(gd, 'lengthmode', 'scaled'); }) .then(function() { - expect(gd._fullData[0].sizemode).toBe('scaled'); + expect(gd._fullData[0].lengthmode).toBe('scaled'); }) .then(done, done.fail); }); diff --git a/test/plot-schema.json b/test/plot-schema.json index f5623e929be..89a48f82fbb 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -49859,7 +49859,7 @@ "animatable": true, "attributes": { "anchor": { - "description": "Sets the arrows' anchor with respect to their (x,y) positions. Use *tail* to place (x,y) at the base, *tip* to place (x,y) at the head, or *center* to center the arrow on (x,y).", + "description": "Sets the vector arrows' anchor with respect to their (x,y) positions. Use *tail* to place (x,y) at the base, *tip* to place (x,y) at the head, or *center* to center the vector arrow on (x,y).", "dflt": "tail", "editType": "calc", "valType": "enumerated", @@ -49869,16 +49869,6 @@ "center" ] }, - "anglemode": { - "description": "Sets the mode used to determine the angle of the arrow vectors. If *paper*, u/v are interpreted in pixel coordinates and the rendered vector angle does not change regardless of the axes scales. If *data*, u/v are interpreted in data coordinates and the rendered vector angle may change, e.g. if zooming in along a single axis", - "dflt": "axis", - "editType": "calc", - "valType": "enumerated", - "values": [ - "paper", - "data" - ] - }, "customdata": { "description": "Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, *scatter* traces also appends customdata items in the markers DOM elements", "editType": "calc", @@ -50194,9 +50184,26 @@ "min": 0, "valType": "number" }, + "lengthfactor": { + "description": "Adjusts the drawn length of the vector arrows. The arrow length is determined by the values of u and v, then optionally rescaled when `lengthmode` is *scaled*, then multiplied by `lengthfactor`.", + "dflt": 1, + "editType": "calc", + "min": 0, + "valType": "number" + }, + "lengthmode": { + "description": "Determines whether vector arrows are drawn according to their raw lengths, or scaled based on the maximum vector length and point density. Note: When `uvref` is *paper* vectors are always scaled and `lengthmode` *raw* is ignored.", + "dflt": "scaled", + "editType": "calc", + "valType": "enumerated", + "values": [ + "scaled", + "raw" + ] + }, "marker": { "arrowsize": { - "description": "Sets the size of the arrow head relative to `marker.line.width`. A value of 1 (default) gives a head about 3x as wide as the line.", + "description": "Sets the size of the vector arrowhead relative to `marker.line.width`. A value of 1 (default) gives a head about 3x as wide as the line.", "dflt": 1, "editType": "calc", "min": 0.3, @@ -50879,7 +50886,7 @@ "editType": "style", "role": "object", "width": { - "description": "Sets the width (in px) of the arrow lines.", + "description": "Sets the width (in px) of the vector arrow lines.", "dflt": 2, "editType": "style", "min": 0, @@ -50962,23 +50969,6 @@ "editType": "style", "valType": "boolean" }, - "sizemode": { - "description": "Determines whether arrows are drawn according to their raw lengths, or scaled based on the maximum vector length and point density. Note: When `anglemode` is *data* arrows are alwyas scaled and `sizemode` *raw* is ignored.", - "dflt": "scaled", - "editType": "calc", - "valType": "enumerated", - "values": [ - "scaled", - "raw" - ] - }, - "sizeref": { - "description": "Adjusts the arrow size scaling. The arrow length is determined by the vector norm multiplied by `sizeref`, optionally normalized when `sizemode` is *scaled* (`sizeref` is applied after scaling).", - "dflt": 1, - "editType": "calc", - "min": 0, - "valType": "number" - }, "text": { "arrayOk": true, "description": "Sets text elements associated with each (x,y) pair. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y) coordinates. If trace `hoverinfo` contains a *text* flag and *hovertext* is not set, these elements will be seen in the hover labels.", @@ -51105,7 +51095,7 @@ "type": "quiver", "u": { "anim": true, - "description": "Sets the x components of the arrow vectors.", + "description": "Sets the x components of the vector arrows.", "editType": "calc", "valType": "data_array" }, @@ -51158,9 +51148,19 @@ "role": "object" } }, + "uvref": { + "description": "Determines how the u/v vector components are interpreted. If *paper*, u/v are interpreted in pixel coordinates and the rendered vector angle does not change regardless of the axis scales. If *data*, u/v are interpreted in data coordinates and the rendered vector angle may change, e.g. if zooming in along a single axis", + "dflt": "data", + "editType": "calc", + "valType": "enumerated", + "values": [ + "paper", + "data" + ] + }, "v": { "anim": true, - "description": "Sets the y components of the arrow vectors.", + "description": "Sets the y components of the vector arrows.", "editType": "calc", "valType": "data_array" }, @@ -51183,7 +51183,7 @@ }, "x": { "anim": true, - "description": "Sets the x coordinates of the arrow locations.", + "description": "Sets the x coordinates of the vector arrow locations.", "editType": "calc+clearAxisTypes", "valType": "data_array" }, @@ -51208,7 +51208,7 @@ }, "y": { "anim": true, - "description": "Sets the y coordinates of the arrow locations.", + "description": "Sets the y coordinates of the vector arrow locations.", "editType": "calc+clearAxisTypes", "valType": "data_array" },