AbstractStaticspannedHow an axis's extent reads: a span, or the one value it never leaves.
5 to 5 is true and says nothing. A rug plot's cross axis prints it
because both bindings read a rug as a point trace with a constant on that
axis (#1132); a parallel-coordinates column that never varies prints it
because the column really is constant; a one-bin histogram prints it
because there is one bin. In every case the reader is told a range and
handed a point.
That constant is also why pitch carries nothing on such an axis: every sample sonifies at the bottom of the range, because the range has no height. Saying so is the smallest thing that removes the surprise -- a reader who has been told the axis does not move knows the identical tones are the chart rather than a fault -- and it needs no new announcement convention, because these are stats that already existed and were merely uninformative (#1136).
What it deliberately does not do is change what pitch means mid-chart. Mapping it to a varying axis instead would hand a reader who has learnt "pitch is y" a chart where pitch is x, unannounced, which is the kind of silent mode change #855 and #947 were both about. That option, and a trace type of its own, are still open on #1132.
Not for every a to b in a description. A choropleth's jump, a flow's
source and target, and a ridgeline's narrowest and widest modes are a
pair or a path rather than one axis's extent, and constant x would be
the wrong sentence for all three.
The axis minimum
The axis maximum
How each end reads: the default rounding, or the axis's own format where the layer declares one
constant <value> when the axis never moves, <min> to <max> otherwise
StaticsafeSafely finds the minimum value from an array of numbers. Returns Infinity for empty arrays (mathematically correct: empty set has no minimum). This prevents subtle bugs where 0 might be confused with actual data.
Array of numbers to find minimum from
The minimum value or Infinity if array is empty
StaticsafeSafely finds the maximum value from an array of numbers. Returns -Infinity for empty arrays (mathematically correct: empty set has no maximum). This prevents subtle bugs where 0 might be confused with actual data.
Array of numbers to find maximum from
The maximum value or -Infinity if array is empty
StaticminFinds the minimum value from a 2D array of numbers.
2D array of numbers
The minimum value across all nested arrays
StaticmaxFinds the maximum value from a 2D array of numbers.
2D array of numbers
The maximum value across all nested arrays
StaticminFinds min and max from an array in a single pass. More efficient than separate min/max calls for large arrays. Returns { min: Infinity, max: -Infinity } for empty arrays.
Array of numbers
Object with min and max properties
StaticminFinds min and max from a 2D array in a single pass.
2D array of numbers
Object with min and max properties
StaticspannedHow an axis's extent reads when the extent may not exist.
safeMin and safeMax answer Infinity and -Infinity for
an empty array by design, and a non-finite coordinate makes both NaN.
Handing either pair to spanned produces the string
Infinity to -Infinity or NaN to NaN, and a string is exactly what the
description dialog's own non-finite blanking cannot catch -- it tests
numbers, so the placeholder sails through and is printed and spoken.
missing is the word the announcements already use for a value that is
not there (see FormatUtil.wrapFormat), so the two surfaces agree.
A genuinely constant axis is not this case: constant 0 is finite, true,
and spanned's to say.
The axis minimum
The axis maximum
How each end reads, as spanned takes it
The span, or missing when there is no finite extent
StaticpearsonPearson's product-moment correlation over paired samples, or null when the pairs cannot support the claim.
What a sighted reader takes from a scatter cloud before any individual point: whether it tilts up, tilts down, or does not tilt. A reader who walks 150 points one at a time has heard 150 numbers and still not been told the relationship they were plotted to show.
Two-pass and mean-centred rather than the textbook one-pass form
(sum(xy) - n*meanX*meanY), which cancels catastrophically when the values
are large beside their spread -- a Manhattan plot's genomic positions on x,
or epoch-millisecond timestamps -- and can return an r outside [-1, 1] or
a negative radicand. Two passes over an in-memory array cost nothing beside
the sorts a trace has already paid to build itself.
Pairs where either coordinate is non-finite are skipped rather than
treated as zero: a missing y is not a y of 0, and traces deliberately keep
gaps as NaN. Null comes back when:
r would be +/-1 by construction and say nothing about the data;r is 0/0. An axis that does not
move cannot correlate with anything, and the description says so
already, in the constant span spanned gives it;Clamped to [-1, 1] because float error routinely yields 1.0000000000000002 on a perfect line, which would print as that and fall outside every strength band a caller tests.
The x coordinate of each pair
The y coordinate of each pair, index-aligned with xs
Pearson's r in [-1, 1], or null when there is nothing to claim
StaticshareCounts as whole percentages of their total, adjusted so they add up to 100.
Largest-remainder apportionment, not four independent roundings. The shares of a scatter's quadrants are read out one after another, and a reader who adds 20, 18, 43 and 20 to 101 has no way to see that the extra point is rounding rather than a chart they have misunderstood -- the arithmetic is the only check they have. Rounding each share on its own lands off 100 routinely: three counts of one in seven give 14, 14, 14 and then 57, which sums to 99.
The unit is handed to whichever share has the largest discarded fraction, which is the standard rule and the one that moves each share least.
Equal counts get equal shares. They have equal fractions, so with fewer units left than equal counts the rule split them: four points each of eleven came out 37% and 36%, and the summary named one quadrant as holding the most. Each set of equal counts, largest fraction first, takes a unit apiece only when the units left cover all of it, and a set that would be split is passed over for the next. The next takes it only when that leaves its share no higher than any larger count's: a set passed over keeps its floor, and handing its unit on to a smaller count with the same floor read 271 points of a thousand as 28% beside 274 at 27%. When no set fits -- three equal thirds -- the shares add up to less than 100 rather than read two equal counts as different, or a smaller count as the larger share.
An empty set of counts, or one summing to zero, comes back as zeroes: there is no share of nothing, and the caller decides whether to say so.
The counts to apportion. Negative entries are not expected and are counted as given.
One whole percentage per count, equal for equal counts and never larger for a smaller count, summing to 100 unless equal counts make that impossible.
StaticpairedHow many pairs pearson was able to use -- both coordinates finite.
Reported alongside r so a reader is told the sample the coefficient was
actually computed over, which on a layer with gaps is not the point count
the summary states above it.
The x coordinate of each pair
The y coordinate of each pair, index-aligned with xs
The number of usable pairs
StaticnearlyWhether two numbers are the same but for float noise: they differ by no more than a billionth of the larger of them, or of 1 when both are smaller than that.
A number computed as a quotient or a difference carries the rounding of what it was computed from, so two numbers equal on paper can differ in the last bit: 22.15 placed on an axis from 10.4 to 33.9 is 0.49999999999999994, and 50 placed on an axis from 0 to 100 is 0.5. A billionth, the margin a percentile band's widths are compared within, is far above that noise and far below any difference a reader could see or hear.
One number
The other
True when the two are the same but for float noise
StaticclampClamps a value into the inclusive [min, max] range.
The value to clamp
Lower bound (inclusive)
Upper bound (inclusive)
StaticinterpolateLinearly maps a value from one numeric range to another.
Collapses to toMin when the source range is zero-width to avoid NaN.
The value in the source range
Lower bound of the source range
Upper bound of the source range
Lower bound of the target range
Upper bound of the target range
Mathematical utility functions for common operations across the codebase. These utilities help reduce code duplication while maintaining type safety.