diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/examples/index.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/examples/index.js new file mode 100644 index 000000000000..ea87996a3bb6 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/examples/index.js @@ -0,0 +1,42 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var uniform = require( '@stdlib/random/uniform' ); +var Float64Vector = require( '@stdlib/ndarray/vector/float64' ); +var Scatterplot = require( './../lib' ); + +var a = new Float64Vector( [ 10.0, 20.0, 30.0, 40.0, 50.0 ] ); +var b = new Float64Vector( [ 20.0, 30.0, 40.0, 50.0, 60.0 ] ); + +var y = uniform( [ 100, 5 ], a, b ); + +var chart = new Scatterplot( y, { + 'symbols': [ 'o', 'square' ], + 'symbolOpacity': [ 1.0, 0.4 ], + 'symbolSize': [ 100, 50 ], + 'edgeColors': [ '#000' ], + 'edgeWidth': [ 1 ], + 'legend': true +}); +console.log( chart.toJSON() ); + +// Render "hollow" symbols by "unsetting" the symbol colors: +chart.colors = void 0; +console.log( chart.toJSON() ); diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/change_event.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/change_event.js new file mode 100644 index 000000000000..269fa636e9cb --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/change_event.js @@ -0,0 +1,41 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Returns a new change event object. +* +* @private +* @param {string} property - property name +* @returns {Object} event object +*/ +function event( property ) { // eslint-disable-line stdlib/no-redeclare + return { + 'type': 'update', + 'source': 'visualization', + 'property': property + }; +} + + +// EXPORTS // + +module.exports = event; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/get.js new file mode 100644 index 000000000000..29aa892fb8c1 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/get.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbol colors. +* +* ## Notes +* +* - If symbol colors are "unset", the function returns `undefined`. +* +* @private +* @returns {(Array|void)} colors +*/ +function get() { + var v = this[ prop.private ]; + if ( v === void 0 ) { + return v; + } + return copy( v ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/properties.js new file mode 100644 index 000000000000..2790499a9a07 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'colors' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/set.js new file mode 100644 index 000000000000..892f7380d337 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/colors/set.js @@ -0,0 +1,101 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbol colors. +* +* ## Notes +* +* - Providing `undefined` "unsets" symbol colors, in which case symbols are rendered without a fill (i.e., as "hollow" symbols). +* +* @private +* @param {(Array|string|void)} value - input value +* @throws {TypeError} must be a string, an array of strings, or undefined +* @returns {void} +*/ +function set( value ) { + var isStr; + var curr; + + curr = this[ prop.private ]; + + // Case: unset the symbol colors... + if ( value === void 0 ) { + if ( curr === void 0 ) { + return; + } + debug( 'Current value: [%s]. New value: undefined.', join( curr, ', ' ) ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Clear the edge color range, as the scale should no longer resolve values: + this.colorScale.range = []; + return; + } + isStr = isString( value ); + if ( !isStr && !isStringArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a string, an array of strings, or undefined. Value: `%s`.', prop.name, value ) ); + } + if ( isStr ) { + value = [ value ]; + } + if ( curr === void 0 ) { + debug( 'Current value: undefined. New value: [%s].', join( value, ', ' ) ); + } else if ( hasEqualValues( value, curr ) ) { + return; + } else { + debug( 'Current value: [%s]. New value: [%s].', join( curr, ', ' ), join( value, ', ' ) ); + } + // Perform a defensive copy as we will be caching the specified symbol colors: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Update the edge color range: + this.colorScale.range = value; +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/defaults.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/defaults.js new file mode 100644 index 000000000000..7a37b3000512 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/defaults.js @@ -0,0 +1,69 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var category10 = require( '@stdlib/plot/color-schemes/category10' ); + + +// MAIN // + +/** +* Returns defaults. +* +* @private +* @returns {Object} defaults +* +* @example +* var obj = defaults(); +* // returns {...} +*/ +function defaults() { + return { + // Symbol colors (note: `undefined` indicates that symbols should not have a fill): + 'colors': category10(), + + // Symbol edge colors (note: `undefined` indicates that symbols should not have edges): + 'edgeColors': void 0, + + // Symbol edge opacity (note: `undefined` indicates that symbol edges should inherit the symbol opacity): + 'edgeOpacity': void 0, + + // Symbol edge width(s) (in pixels) (note: `undefined` indicates that symbol edges should use the default edge width): + 'edgeWidth': void 0, + + // Boolean indicating whether to display a legend: + 'legend': false, + + // Symbol(s): + 'symbols': [ 'circle' ], + + // Symbol opacity (note: default to semi-transparent symbols in order to convey whether data points lie beneath a given point, while remaining sufficiently opaque to avoid accessibility concerns): + 'symbolOpacity': [ 0.6 ], + + // Symbol size(s) (in pixels squared): + 'symbolSize': [ 100 ] + }; +} + + +// EXPORTS // + +module.exports = defaults; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/get.js new file mode 100644 index 000000000000..fead5c25029d --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/get.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbol edge colors. +* +* ## Notes +* +* - If symbol edges are "unset", the function returns `undefined`. +* +* @private +* @returns {(Array|void)} colors +*/ +function get() { + var v = this[ prop.private ]; + if ( v === void 0 ) { + return v; + } + return copy( v ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/properties.js new file mode 100644 index 000000000000..e7b252eb59fd --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'edgeColors' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/set.js new file mode 100644 index 000000000000..c28fd1f79430 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-colors/set.js @@ -0,0 +1,101 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isStringArray = require( '@stdlib/assert/is-string-array' ).primitives; +var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbol edge colors. +* +* ## Notes +* +* - Providing `undefined` "unsets" symbol edge colors, in which case symbols are rendered without edges. +* +* @private +* @param {(Array|string|void)} value - input value +* @throws {TypeError} must be a string, an array of strings, or undefined +* @returns {void} +*/ +function set( value ) { + var isStr; + var curr; + + curr = this[ prop.private ]; + + // Case: unset the symbol edge colors... + if ( value === void 0 ) { + if ( curr === void 0 ) { + return; + } + debug( 'Current value: [%s]. New value: undefined.', join( curr, ', ' ) ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Clear the edge color range, as the scale should no longer resolve values: + this.edgeColorScale.range = []; + return; + } + isStr = isString( value ); + if ( !isStr && !isStringArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a string, an array of strings, or undefined. Value: `%s`.', prop.name, value ) ); + } + if ( isStr ) { + value = [ value ]; + } + if ( curr === void 0 ) { + debug( 'Current value: undefined. New value: [%s].', join( value, ', ' ) ); + } else if ( hasEqualValues( value, curr ) ) { + return; + } else { + debug( 'Current value: [%s]. New value: [%s].', join( curr, ', ' ), join( value, ', ' ) ); + } + // Perform a defensive copy as we will be caching the specified symbol edge colors: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Update the edge color range: + this.edgeColorScale.range = value; +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/get.js new file mode 100644 index 000000000000..e4ef353839ef --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/get.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbol edge opacities. +* +* ## Notes +* +* - If symbol edge opacities are "unset", the function returns `undefined`. +* +* @private +* @returns {(Array|void)} opacities +*/ +function get() { + var v = this[ prop.private ]; + if ( v === void 0 ) { + return v; + } + return copy( v ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/properties.js new file mode 100644 index 000000000000..7776075ecd47 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'edgeOpacity' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/set.js new file mode 100644 index 000000000000..382f04eaf036 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-opacity/set.js @@ -0,0 +1,101 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isProbabilityArray = require( '@stdlib/assert/is-probability-array' ).primitives; +var isProbability = require( '@stdlib/assert/is-probability' ).isPrimitive; +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbol edge opacities. +* +* ## Notes +* +* - Providing `undefined` "unsets" symbol edge opacities, in which case symbol edges inherit the symbol opacity. +* +* @private +* @param {(Array|number|void)} value - input value +* @throws {TypeError} must be a number, an array of numbers, or undefined +* @returns {void} +*/ +function set( value ) { + var isNum; + var curr; + + curr = this[ prop.private ]; + + // Case: unset the symbol edge opacities... + if ( value === void 0 ) { + if ( curr === void 0 ) { + return; + } + debug( 'Current value: [%s]. New value: undefined.', join( curr, ', ' ) ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Clear the edge opacity range, as the scale should no longer resolve values: + this.edgeOpacityScale.range = []; + return; + } + isNum = isProbability( value ); + if ( !isNum && !isProbabilityArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a number, an array of numbers on the interval [0,1], or undefined. Value: `%s`.', prop.name, value ) ); + } + if ( isNum ) { + value = [ value ]; + } + if ( curr === void 0 ) { + debug( 'Current value: undefined. New value: [%s].', join( value, ', ' ) ); + } else if ( hasEqualValues( value, curr ) ) { + return; + } else { + debug( 'Current value: [%s]. New value: [%s].', join( curr, ', ' ), join( value, ', ' ) ); + } + // Perform a defensive copy as we will be caching the specified symbol edge opacities: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Update the edge opacity range: + this.edgeOpacityScale.range = value; +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/get.js new file mode 100644 index 000000000000..149c83915bb4 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/get.js @@ -0,0 +1,52 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbol edge widths (in pixels). +* +* ## Notes +* +* - If symbol edge widths are "unset", the function returns `undefined`. +* +* @private +* @returns {(Array|void)} widths +*/ +function get() { + var v = this[ prop.private ]; + if ( v === void 0 ) { + return v; + } + return copy( v ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/properties.js new file mode 100644 index 000000000000..ad420c49af67 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'edgeWidth' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/set.js new file mode 100644 index 000000000000..586be36a985c --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/edge-width/set.js @@ -0,0 +1,101 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isNumberArray = require( '@stdlib/assert/is-number-array' ).primitives; +var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbol edge widths (in pixels). +* +* ## Notes +* +* - Providing `undefined` "unsets" symbol edge widths, in which case symbol edges are rendered using the default edge width. +* +* @private +* @param {(Array|number|void)} value - input value +* @throws {TypeError} must be a number, an array of numbers, or undefined +* @returns {void} +*/ +function set( value ) { + var isNum; + var curr; + + curr = this[ prop.private ]; + + // Case: unset the symbol edge widths... + if ( value === void 0 ) { + if ( curr === void 0 ) { + return; + } + debug( 'Current value: [%s]. New value: undefined.', join( curr, ', ' ) ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Clear the edge width range, as the scale should no longer resolve values: + this.edgeWidthScale.range = []; + return; + } + isNum = isNumber( value ); + if ( !isNum && !isNumberArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a number, an array of numbers, or undefined. Value: `%s`.', prop.name, value ) ); + } + if ( isNum ) { + value = [ value ]; + } + if ( curr === void 0 ) { + debug( 'Current value: undefined. New value: [%s].', join( value, ', ' ) ); + } else if ( hasEqualValues( value, curr ) ) { + return; + } else { + debug( 'Current value: [%s]. New value: [%s].', join( curr, ', ' ), join( value, ', ' ) ); + } + // Perform a defensive copy as we will be caching the specified symbol edge widths: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Update the edge width range: + this.edgeWidthScale.range = value; +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/index.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/index.js new file mode 100644 index 000000000000..65ccde15a407 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/index.js @@ -0,0 +1,42 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Scatterplot constructor. +* +* @module @stdlib/plot/charts/scatter/ctor +* +* @example +* var Scatterplot = require( '@stdlib/plot/charts/scatter/ctor' ); +* +* var chart = new Scatterplot(); +* // returns +* +* // TODO: update example +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/is_edge_symbol.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/is_edge_symbol.js new file mode 100644 index 000000000000..942b70aceac8 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/is_edge_symbol.js @@ -0,0 +1,62 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var contains = require( '@stdlib/array/base/assert/contains' ); +var symbol2alias = require( '@stdlib/plot/base/symbol2alias' ); + + +// VARIABLES // + +// List of symbols which lack a "face". +var EDGE_SYMBOLS = [ + 'asterisk', + 'cross', + 'line', + 'stroke', + 'x' +]; + + +// MAIN // + +/** +* Tests whether a symbol lacks a "face" and is thus drawn entirely from its edge. +* +* @private +* @param {string} symbol - symbol alias or shorthand +* @returns {boolean} boolean indicating whether a symbol lacks a face +* +* @example +* var bool = isEdgeSymbol( 'x' ); +* // returns true +* +* bool = isEdgeSymbol( 'o' ); +* // returns false +*/ +function isEdgeSymbol( symbol ) { + return contains( EDGE_SYMBOLS, symbol2alias( symbol ) ); +} + + +// EXPORTS // + +module.exports = isEdgeSymbol; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/get.js new file mode 100644 index 000000000000..a54c76188171 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/get.js @@ -0,0 +1,43 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns a boolean indicating whether to display a chart legend. +* +* @private +* @returns {boolean} boolean flag +*/ +function get() { + return this[ prop.private ]; +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/properties.js new file mode 100644 index 000000000000..2d94c431aafa --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'legend' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/set.js new file mode 100644 index 000000000000..08af5b675c4a --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/legend/set.js @@ -0,0 +1,64 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive; +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets a boolean flag indicating whether to display a chart legend. +* +* @private +* @param {boolean} value - input value +* @throws {TypeError} must be a boolean +* @returns {void} +*/ +function set( value ) { + if ( !isBoolean( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a boolean. Value: `%s`.', prop.name, value ) ); + } + if ( value !== this[ prop.private ] ) { + debug( 'Current value: %s. New value: %s.', this[ prop.private ], value ); + this[ prop.private ] = value; + if ( value ) { + this.config.legends = [ this._chartLegend ]; + return; + } + this.config.legends = []; + } +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/main.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/main.js new file mode 100644 index 000000000000..cc5217b61a3e --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/main.js @@ -0,0 +1,1100 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable max-lines, no-restricted-syntax, no-invalid-this, stdlib/no-empty-lines-between-requires */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isFunction = require( '@stdlib/assert/is-function' ); +var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' ); +var isCollection = require( '@stdlib/assert/is-collection' ); +var isObject = require( '@stdlib/assert/is-object' ); +var setNonEnumerableReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var setNonEnumerableReadOnlyAccessor = require( '@stdlib/utils/define-nonenumerable-read-only-accessor' ); // eslint-disable-line id-length +var setReadOnlyAccessor = require( '@stdlib/utils/define-read-only-accessor' ); +var setReadWriteAccessor = require( '@stdlib/utils/define-read-write-accessor' ); +var hasProp = require( '@stdlib/assert/has-property' ); +var inherit = require( '@stdlib/utils/inherit' ); +var objectAssignIn = require( '@stdlib/object/assign-in' ); +var slice = require( '@stdlib/array/base/slice' ); +var transformErrorMessage = require( '@stdlib/plot/vega/base/transform-validation-message' ); +var symbols2shapes = require( '@stdlib/plot/base/symbols2shapes' ); +var QuantitativeChart = require( '@stdlib/plot/charts/base/quantitative' ); +var DataSource = require( '@stdlib/plot/vega/mark/data-source' ); +var Value = require( '@stdlib/plot/vega/value/ctor' ); +var OrdinalScale = require( '@stdlib/plot/vega/scale/ordinal' ); +var SymbolEncodingSet = require( '@stdlib/plot/vega/mark/symbol/encoding-set' ); +var SymbolEncoding = require( '@stdlib/plot/vega/mark/symbol/encoding' ); +var SymbolMark = require( '@stdlib/plot/vega/mark/symbol/ctor' ); +var Legend = require( '@stdlib/plot/vega/legend/ctor' ); +var spec2svg = require( '@stdlib/plot/vega/base/spec2svg' ); +var format = require( '@stdlib/string/format' ); +var objectKeys = require( '@stdlib/utils/keys' ); +var isEdgeSymbol = require( './is_edge_symbol.js' ); +var properties = require( './properties.json' ); +var defaults = require( './defaults.js' ); + +// Note: keep the following in alphabetical order according to the `require` path... +var getColors = require( './colors/get.js' ); +var setColors = require( './colors/set.js' ); + +var getEdgeColors = require( './edge-colors/get.js' ); +var setEdgeColors = require( './edge-colors/set.js' ); +var getEdgeOpacity = require( './edge-opacity/get.js' ); +var setEdgeOpacity = require( './edge-opacity/set.js' ); +var getEdgeWidth = require( './edge-width/get.js' ); +var setEdgeWidth = require( './edge-width/set.js' ); + +var getLegend = require( './legend/get.js' ); +var setLegend = require( './legend/set.js' ); + +var getSymbolOpacity = require( './symbol-opacity/get.js' ); +var setSymbolOpacity = require( './symbol-opacity/set.js' ); +var getSymbols = require( './symbols/get.js' ); +var setSymbols = require( './symbols/set.js' ); +var getSymbolSize = require( './symbol-size/get.js' ); +var setSymbolSize = require( './symbol-size/set.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:main' ); + +var SCALE_TO_INDEX = { + 'x': 0, + 'y': 1, + 'color': 2, + 'opacity': 3, + 'shape': 4, + 'size': 5, + 'edgeColor': 6, + 'edgeOpacity': 7, + 'edgeWidth': 8 +}; +var SCALE_TO_DEFAULT_NAME = { + 'color': 'colorScale', + 'opacity': 'symbolOpacityScale', + 'shape': 'symbolsScale', + 'size': 'symbolSizeScale', + 'edgeColor': 'edgeColorScale', + 'edgeOpacity': 'edgeOpacityScale', + 'edgeWidth': 'edgeWidthScale' +}; +var INTERNAL_ORDINAL_SCALES = [ + 'color', + 'opacity', + 'shape', + 'size', + 'edgeColor', + 'edgeOpacity', + 'edgeWidth' +]; + +// List of symbol mark encoding channels which are resolved from ordinal scales and whose presence depends on which chart properties have been set... +var ORDINAL_ENCODING_CHANNELS = [ + 'fill', + 'fillOpacity', + 'shape', + 'size', + 'stroke', + 'strokeOpacity', + 'strokeWidth' +]; + + +// FUNCTIONS // + +/** +* Extract a property value from each element of an object array. +* +* @private +* @param {Array} arr - input array +* @param {string} prop - property name +* @returns {Array} output array +*/ +function pluck( arr, prop ) { // TODO: use `array/base/pluck` once implemented (ref: https://github.com/stdlib-js/stdlib/pull/5376) + var out; + var i; + + out = []; + for ( i = 0; i < arr.length; i++ ) { + out.push( arr[ i ][ prop ] ); + } + return out; +} + +/** +* Returns the scale data associated with the provided scale identifier. +* +* @private +* @param {Array} data - scale data +* @param {string} id - identifier +* @returns {*} scale data +*/ +function getScale( data, id ) { + return data[ SCALE_TO_INDEX[ id ] ]; +} + +/** +* Returns the default name for a specified scale identifier. +* +* @private +* @param {string} id - identifier +* @returns {string} default name +*/ +function scale2default( id ) { + return SCALE_TO_DEFAULT_NAME[ id ]; +} + +/** +* Returns a field value reference. +* +* @private +* @param {string} scale - scale name +* @param {string} field - field name +* @returns {Value} value reference +*/ +function fieldValue( scale, field ) { + return new Value({ + 'scale': scale, + 'field': field + }); +} + +/** +* Returns an ordinal value reference. +* +* @private +* @param {string} scale - scale name +* @param {*} value - value +* @returns {Value} value reference +*/ +function ordinalValue( scale, value ) { + return new Value({ + 'scale': scale, + 'value': value + }); +} + +/** +* Returns a symbol mark encoding for a specified dataset. +* +* @private +* @param {string} name - dataset name +* @param {Array} scales - scale names +* @param {Object} channels - object mapping encoding channels to scale names +* @returns {SymbolEncoding} symbol mark encoding +*/ +function encoding( name, scales, channels ) { + var keys; + var opts; + var i; + + opts = { + 'x': fieldValue( getScale( scales, 'x' ), 'x' ), + 'y': fieldValue( getScale( scales, 'y' ), 'y' ) + }; + keys = objectKeys( channels ); + for ( i = 0; i < keys.length; i++ ) { + opts[ keys[ i ] ] = ordinalValue( channels[ keys[ i ] ], name ); + } + return new SymbolEncoding({ + 'update': new SymbolEncodingSet( opts ) + }); +} + +/** +* Returns a symbol mark for a specified dataset. +* +* @private +* @param {string} name - dataset name +* @param {Array} scales - scale names +* @param {Object} channels - object mapping encoding channels to scale names +* @returns {SymbolMark} symbol mark +*/ +function symbolMark( name, scales, channels ) { + return new SymbolMark({ + 'from': new DataSource({ + 'data': name + }), + 'encode': encoding( name, scales, channels ) + }); +} + +/** +* Updates a symbol mark. +* +* @private +* @param {SymbolMark} mark - symbol mark +* @param {string} name - dataset name +* @param {Array} scales - scale names +* @param {Object} channels - object mapping encoding channels to scale names +* @returns {SymbolMark} symbol mark +*/ +function updateSymbolMark( mark, name, scales, channels ) { + var encoding; + var scale; + var ch; + var v; + var i; + + mark.from.data = name; + + encoding = mark.encode.update; + encoding.x.scale = getScale( scales, 'x' ); + encoding.y.scale = getScale( scales, 'y' ); + + for ( i = 0; i < ORDINAL_ENCODING_CHANNELS.length; i++ ) { + ch = ORDINAL_ENCODING_CHANNELS[ i ]; + scale = channels[ ch ]; + + // Case: the channel should no longer be encoded (e.g., after "unsetting" symbol edge colors)... + if ( scale === void 0 ) { + encoding[ ch ] = void 0; + continue; + } + v = encoding[ ch ]; + + // Case: the channel was not previously encoded (e.g., after setting symbol edge colors)... + if ( v === void 0 ) { + encoding[ ch ] = ordinalValue( scale, name ); + continue; + } + v.scale = scale; + v.value = name; + } + return mark; +} + + +// MAIN // + +/** +* Scatterplot constructor. +* +* @constructor +* @param {(ndarrayLike|Collection)} [x] - x-values +* @param {(ndarrayLike|Collection)} [y] - y-values +* @param {Options} [options] - constructor options +* @param {string} [options.background] - background color +* @param {Object} [options.channels={'x':'x','y':'y'}] - object mapping chart data field names to encoding channels ('x', 'y', and 'z') +* @param {(string|Array|void)} [options.colors] - symbol colors (`undefined` renders symbols without a fill) +* @param {(string|Array|void)} [options.edgeColors] - symbol edge colors (`undefined` renders symbols without edges) +* @param {(number|Array|void)} [options.edgeOpacity] - symbol edge opacity (`undefined` inherits the symbol opacity) +* @param {(number|Array|void)} [options.edgeWidth] - symbol edge width(s) (in pixels) +* @param {ArrayLikeObject} [options.data=[]] - chart data +* @param {string} [options.description=''] - chart description +* @param {number} [options.height=480] - chart height (in pixels) +* @param {Array} [options.labels=[]] - data labels +* @param {Object} [options.padding] - chart padding +* @param {number} [options.padding.bottom=0] - chart bottom padding (in pixels) +* @param {number} [options.padding.left=0] - chart left padding (in pixels) +* @param {number} [options.padding.right=0] - chart right padding (in pixels) +* @param {number} [options.padding.top=0] - chart top padding (in pixels) +* @param {(string|Array)} [options.symbols=['circle']] - symbol(s) +* @param {(number|Array)} [options.symbolOpacity=[0.6]] - symbol opacity +* @param {(number|Array)} [options.symbolSize=[100]] - symbol size(s) in pixels squared +* @param {Object} [options.theme] - chart theme +* @param {(string|Array)} [options.title=''] - chart title +* @param {string} [options.viewer] - default chart viewer +* @param {number} [options.width=600] - chart width (in pixels) +* @param {(string|Array)} [options.xTitle='x'] - x-axis label +* @param {(string|Object)} [options.xFormat] - x-axis tick format +* @param {number} [options.xMax] - maximum value of the x-axis domain +* @param {number} [options.xMin] - minimum value of the x-axis domain +* @param {string} [options.xScaleType='linear'] - x-axis scale type +* @param {(number|string|Object)} [options.xTickCount] - number of x-axis tick marks +* @param {(string|Object)} [options.yFormat] - y-axis tick format +* @param {number} [options.yMax] - maximum value of the y-axis domain +* @param {number} [options.yMin] - minimum value of the y-axis domain +* @param {string} [options.yScaleType='linear'] - y-axis scale type +* @param {(number|string|Object)} [options.yTickCount] - number of y-axis tick marks +* @param {(string|Array)} [options.yTitle='y'] - y-axis label +* @throws {TypeError} must provide a valid first argument +* @throws {TypeError} must provide a valid second argument +* @throws {TypeError} options argument must be an object +* @throws {Error} must provide valid options +* @returns {Scatterplot} scatterplot instance +* +* @example +* var plot = new Scatterplot(); +* // returns +*/ +function Scatterplot( x, y, options ) { + var scales; + var nargs; + var opts; + var k; + var v; + var s; + var i; + + nargs = arguments.length; + if ( !( this instanceof Scatterplot ) ) { + if ( nargs < 1 ) { + return new Scatterplot(); + } + if ( nargs === 1 ) { + return new Scatterplot( x ); + } + if ( nargs === 2 ) { + return new Scatterplot( x, y ); + } + return new Scatterplot( x, y, options ); + } + opts = defaults(); + + // Set internal properties according to the default configuration... + for ( i = 0; i < properties.length; i++ ) { + k = properties[ i ]; + if ( hasProp( opts, k ) ) { + this[ '_'+k ] = opts[ k ]; + } + } + // Case: new Scatterplot( arg ) + if ( nargs === 1 ) { + // Case: new Scatterplot( ndarray ) + if ( isndarrayLike( x ) ) { + opts.data = [ x ]; + } + // Case: new Scatterplot( collection ) + else if ( isCollection( x ) ) { + opts.data = [ x ]; + } + // Case: new Scatterplot( options ) + else if ( isObject( x ) ) { + opts = objectAssignIn( opts, x ); + } + // Case: new Scatterplot( ??? ) + else { + throw new TypeError( format( 'invalid argument. First argument must be either an array-like object, an ndarray, or an options argument. Value: `%s`.', x ) ); + } + } + // Case: new Scatterplot( arg1, arg2 ) + else if ( nargs === 2 ) { + // Case: new Scatterplot( ndarray, ??? ) + if ( isndarrayLike( x ) ) { + // Case: new Scatterplot( ndarray, ndarray ) + if ( isndarrayLike( y ) ) { + opts.data = [ x, y ]; + } + // Case: new Scatterplot( ndarray, collection ) + else if ( isCollection( y ) ) { + for ( i = 0; i < y.length; i++ ) { + if ( !isndarrayLike( y[ i ] ) ) { + throw new TypeError( 'invalid argument. Second argument must be an ndarray or an array of ndarrays.' ); + } + } + opts.data = [ x, y ]; + } + // Case: new Scatterplot( ndarray, options ) + else if ( isObject( y ) ) { + opts = objectAssignIn( opts, y ); + opts.data = [ x ]; // always override `opts.data` if it exists + } + // Case: new Scatterplot( ndarray, ??? ) + else { + throw new TypeError( format( 'invalid argument. Second argument must be either an ndarray, an array of ndarrays, or an options argument. Value: `%s`.', y ) ); + } + } + // Case: new Scatterplot( collection, ??? ) + else if ( isCollection( x ) ) { + // Case: new Scatterplot( collection, ndarray ) + if ( isndarrayLike( y ) ) { + for ( i = 0; i < x.length; i++ ) { + if ( !isndarrayLike( x[ i ] ) ) { + throw new TypeError( 'invalid argument. First argument must be an ndarray or an array of ndarrays.' ); + } + } + opts.data = [ x, y ]; + } + // Case: new Scatterplot( collection, collection ) + else if ( isCollection( y ) ) { + opts.data = [ x, y ]; + } + // Case: new Scatterplot( collection, options ) + else if ( isObject( y ) ) { + opts = objectAssignIn( opts, y ); + opts.data = [ x ]; // always override `opts.data` if it exists + } + // Case: new Scatterplot( collection, ??? ) + else { + throw new TypeError( format( 'invalid argument. First argument must be either an array-like object, an ndarray, or an options argument. Value: `%s`.', y ) ); + } + } + // Case: new Scatterplot( ???, ??? ) + else { + throw new TypeError( format( 'invalid argument. First argument must be either an array-like object or an ndarray. Value: `%s`.', x ) ); + } + } + // Case: new Scatterplot( x, y, options ) + else if ( nargs > 2 ) { + if ( !isObject( options ) ) { + throw new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) ); + } + opts = objectAssignIn( opts, options ); + + // Case: new Scatterplot( ndarray, ???, options ) + if ( isndarrayLike( x ) ) { + // Case: new Scatterplot( ndarray, ndarray, options ) + if ( isndarrayLike( y ) ) { + opts.data = [ x, y ]; // always override `opts.data` if it exists + } + // Case: new Scatterplot( ndarray, collection, options ) + else if ( isCollection( y ) ) { + for ( i = 0; i < y.length; i++ ) { + if ( !isndarrayLike( y[ i ] ) ) { + throw new TypeError( 'invalid argument. Second argument must be an ndarray or an array of ndarrays.' ); + } + } + opts.data = [ x, y ]; // always override `opts.data` if it exists + } + // Case: new Scatterplot( ndarray, ???, options ) + else { + throw new TypeError( format( 'invalid argument. Second argument must be an ndarray or an array of ndarrays.' ) ); + } + } + // Case: new Scatterplot( collection, ???, options ) + else if ( isCollection( x ) ) { + // Case: new Scatterplot( collection, ndarray, options ) + if ( isndarrayLike( y ) ) { + for ( i = 0; i < x.length; i++ ) { + if ( !isndarrayLike( x[ i ] ) ) { + throw new TypeError( 'invalid argument. First argument must be an ndarray or an array of ndarrays.' ); + } + } + opts.data = [ x, y ]; // always override `opts.data` if it exists + } + // Case: new Scatterplot( collection, collection, options ) + else if ( isCollection( y ) ) { + opts.data = [ x, y ]; // always override `opts.data` if it exists + } + // Case: new Scatterplot( collection, ???, options ) + else { + throw new TypeError( format( 'invalid argument. Second argument must be an array-like object or an ndarray.' ) ); + } + } + // Case: new Scatterplot( ???, ???, options ) + else { + throw new TypeError( format( 'invalid argument. First argument must be an array-like object or an ndarray. Value: `%s`.', x ) ); + } + } + QuantitativeChart.call( this, opts ); + + // Initialize internal encoding scales... + scales = this.config.scales; + for ( i = 0; i < INTERNAL_ORDINAL_SCALES.length; i++ ) { + s = new OrdinalScale({ + 'name': scale2default( INTERNAL_ORDINAL_SCALES[ i ] ) + }); + scales.push( s ); + } + this.config.scales = scales; + + // Initialize a legend instance: + this._chartLegend = new Legend({ + 'fill': 'colorScale', + 'shape': 'symbolsScale', + 'size': 'symbolSizeScale', + 'opacity': 'symbolOpacityScale', + + // FIXME: rather than hardcode defaults, create a default scatterplot theme which inherits from the quantitative chart theme + 'orient': 'bottom', + 'direction': 'horizontal', + 'offset': 10, // px + 'padding': 5, // px + 'columnPadding': 20 // px + }); + + // Validate provided options by attempting to assign option values to corresponding fields... + for ( i = 0; i < properties.length; i++ ) { + k = properties[ i ]; + if ( !hasProp( opts, k ) ) { + continue; + } + v = opts[ k ]; + try { + this[ k ] = v; + } catch ( err ) { + debug( 'Encountered an error. Error: %s', err.message ); + + // FIXME: retain thrown error type + throw new Error( transformErrorMessage( err.message ) ); + } + } + return this; +} + +/* +* Inherit from the `QuantitativeChart` prototype. +*/ +inherit( Scatterplot, QuantitativeChart ); + +/** +* Constructor name. +* +* @private +* @name name +* @memberof Scatterplot +* @readonly +* @type {string} +*/ +setNonEnumerableReadOnly( Scatterplot, 'name', 'Scatterplot' ); + +/** +* Generates a list of mark objects. +* +* @private +* @name _marks +* @memberof Scatterplot.prototype +* @type {Array} +*/ +setNonEnumerableReadOnlyAccessor( Scatterplot.prototype, '_marks', function getMarks() { + var scaleNames; + var dataNames; + var symbols; + var scales; + var marks; + var data; + var M; + var N; + var i; + + // Resolve visualization datasets: + data = this.config.data; + N = data.length; + + // If no data, no marks to generate... + if ( N === 0 ) { + return []; + } + // Resolve the list of dataset names: + dataNames = pluck( data, 'name' ); + + // Resolve the visualization scales: + scales = this.config.scales; + scaleNames = pluck( scales, 'name' ); + + // Resolve existing visualization marks: + marks = this.config.marks; + M = marks.length; + + // If we have fewer datasets than marks, prune the marks array... + if ( M > N ) { + // Note that, by pruning the marks array, we effectively invalidate the removed mark encoding instances, as any changes to them will no longer propagate back to the chart; the pruned mark encodings can, however, be explicitly rebound... + marks = slice( marks, 0, N ); + M = N; + } + // Update internal encoding scales: + this._updateScales( dataNames, scales ); + + // Update the chart legend, as which channels a legend should display depends on which chart properties have been set: + this._updateLegend(); + + // Resolve the symbol assigned to each dataset, noting that, as symbols are resolved from an ordinal scale, symbols cycle when provided fewer symbols than datasets... + symbols = this._symbols; + + // Update existing marks (note: reusing existing marks is important in order to avoid triggering an infinite loop of "change" events)... + for ( i = 0; i < M; i++ ) { + updateSymbolMark( marks[ i ], dataNames[ i ], scaleNames, this._resolveChannels( scaleNames, symbols[ i%symbols.length ] ) ); + } + // Create new marks... + for ( i = M; i < N; i++ ) { + marks.push( symbolMark( dataNames[ i ], scaleNames, this._resolveChannels( scaleNames, symbols[ i%symbols.length ] ) ) ); + } + return marks; +}); + +/** +* Updates internal encoding scales. +* +* @private +* @name _updateScales +* @memberof Scatterplot.prototype +* @type {Function} +* @param {Array} names - data set names +* @param {Array} scales - list of scales +*/ +setNonEnumerableReadOnly( Scatterplot.prototype, '_updateScales', function updateScales( names, scales ) { + var s; + + // Note: for "unset" properties, we assign an empty range, as the corresponding scale should not resolve values and is not referenced by any mark encoding... + s = getScale( scales, 'color' ); + s.domain = names; + s.range = ( this._colors === void 0 ) ? [] : this._colors; + + s = getScale( scales, 'opacity' ); + s.domain = names; + s.range = this._symbolOpacity; + + s = getScale( scales, 'shape' ); + s.domain = names; + s.range = symbols2shapes( this._symbols ); + + s = getScale( scales, 'size' ); + s.domain = names; + s.range = this._symbolSize; + + s = getScale( scales, 'edgeColor' ); + s.domain = names; + s.range = ( this._edgeColors === void 0 ) ? [] : this._edgeColors; + + s = getScale( scales, 'edgeOpacity' ); + s.domain = names; + s.range = ( this._edgeOpacity === void 0 ) ? [] : this._edgeOpacity; + + s = getScale( scales, 'edgeWidth' ); + s.domain = names; + s.range = ( this._edgeWidth === void 0 ) ? [] : this._edgeWidth; +}); + +/** +* Resolves the ordinal encoding channels for a dataset having a specified symbol. +* +* ## Notes +* +* - The method returns an object mapping symbol mark encoding channels to the names of the scales from which channel values should be resolved. Channels which should not be encoded are omitted, thus allowing a symbol to, e.g., be rendered without a fill or without an edge. +* - A symbol which lacks a "face" (e.g., `x` and `line`) is drawn entirely from its edge. Accordingly, for such symbols, edge properties take precedence over their fill counterparts, and we encode both the fill and the stroke in order to support both closed (e.g., `x`) and open (e.g., `line`) symbol paths. +* +* @private +* @name _resolveChannels +* @memberof Scatterplot.prototype +* @type {Function} +* @param {Array} scales - scale names +* @param {string} symbol - symbol assigned to a dataset +* @returns {Object} object mapping encoding channels to scale names +*/ +setNonEnumerableReadOnly( Scatterplot.prototype, '_resolveChannels', function resolveChannels( scales, symbol ) { + var opacity; + var color; + var out; + + out = { + 'shape': getScale( scales, 'shape' ), + 'size': getScale( scales, 'size' ) + }; + if ( this._edgeWidth !== void 0 ) { + out.strokeWidth = getScale( scales, 'edgeWidth' ); + } + // Case: the symbol lacks a face, and thus edge properties take precedence over their fill counterparts... + if ( isEdgeSymbol( symbol ) ) { + if ( this._edgeColors === void 0 ) { + color = ( this._colors === void 0 ) ? void 0 : getScale( scales, 'color' ); + } else { + color = getScale( scales, 'edgeColor' ); + } + // Case: neither symbol colors nor symbol edge colors are set, and thus the symbol has no color to encode... + if ( color === void 0 ) { + return out; + } + if ( this._edgeOpacity === void 0 ) { + opacity = getScale( scales, 'opacity' ); + } else { + opacity = getScale( scales, 'edgeOpacity' ); + } + out.fill = color; + out.fillOpacity = opacity; + out.stroke = color; + out.strokeOpacity = opacity; + return out; + } + if ( this._colors !== void 0 ) { + out.fill = getScale( scales, 'color' ); + out.fillOpacity = getScale( scales, 'opacity' ); + } + if ( this._edgeColors !== void 0 ) { + out.stroke = getScale( scales, 'edgeColor' ); + } + if ( this._edgeOpacity !== void 0 ) { + out.strokeOpacity = getScale( scales, 'edgeOpacity' ); + } + return out; +}); + +/** +* Updates the chart legend. +* +* ## Notes +* +* - Which channels a legend should display depends on which chart properties have been set. E.g., if symbol colors have been "unset" in order to render "hollow" symbols, a legend should convey symbol edge colors, rather than symbol fill colors. +* +* @private +* @name _updateLegend +* @memberof Scatterplot.prototype +* @type {Function} +*/ +setNonEnumerableReadOnly( Scatterplot.prototype, '_updateLegend', function updateLegend() { + var legend = this._chartLegend; + + legend.fill = ( this._colors === void 0 ) ? void 0 : 'colorScale'; + legend.stroke = ( this._edgeColors === void 0 ) ? void 0 : 'edgeColorScale'; + legend.strokeWidth = ( this._edgeWidth === void 0 ) ? void 0 : 'edgeWidthScale'; + + // Case: symbols are "hollow", and thus a legend should convey the edge opacity, rather than the (unused) fill opacity... + if ( this._colors === void 0 && this._edgeOpacity !== void 0 ) { + legend.opacity = 'edgeOpacityScale'; + } else { + legend.opacity = 'symbolOpacityScale'; + } +}); + +/** +* Symbol colors. +* +* ## Notes +* +* - Assigning `undefined` "unsets" symbol colors, in which case symbols are rendered without a fill (i.e., as "hollow" symbols). +* +* @name colors +* @memberof Scatterplot.prototype +* @type {(Array|void)} +* +* @example +* var chart = new Scatterplot({ +* 'colors': [ '#000', 'steelblue' ] +* }); +* // returns +* +* var v = chart.colors; +* // returns [ '#000', 'steelblue' ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'colors', getColors, setColors ); + +/** +* Symbol edge colors. +* +* ## Notes +* +* - Assigning `undefined` "unsets" symbol edge colors, in which case symbols are rendered without edges. +* - For symbols which lack a "face" (e.g., `x` and `line`), symbol edge colors take precedence over symbol colors. +* +* @name edgeColors +* @memberof Scatterplot.prototype +* @type {(Array|void)} +* @default undefined +* +* @example +* var chart = new Scatterplot({ +* 'edgeColors': [ '#000', 'steelblue' ] +* }); +* // returns +* +* var v = chart.edgeColors; +* // returns [ '#000', 'steelblue' ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'edgeColors', getEdgeColors, setEdgeColors ); + +/** +* Symbol edge opacity. +* +* ## Notes +* +* - Assigning `undefined` "unsets" symbol edge opacities, in which case symbol edges inherit the symbol opacity. +* +* @name edgeOpacity +* @memberof Scatterplot.prototype +* @type {(Array|void)} +* @default undefined +* +* @example +* var chart = new Scatterplot({ +* 'edgeColors': [ '#000' ], +* 'edgeOpacity': [ 1.0, 0.5 ] +* }); +* // returns +* +* var v = chart.edgeOpacity; +* // returns [ 1.0, 0.5 ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'edgeOpacity', getEdgeOpacity, setEdgeOpacity ); + +/** +* Symbol edge width(s) (in pixels). +* +* ## Notes +* +* - Assigning `undefined` "unsets" symbol edge widths, in which case symbol edges are rendered using the default edge width. +* +* @name edgeWidth +* @memberof Scatterplot.prototype +* @type {(Array|void)} +* @default undefined +* +* @example +* var chart = new Scatterplot({ +* 'edgeColors': [ '#000' ], +* 'edgeWidth': [ 1, 2 ] +* }); +* // returns +* +* var v = chart.edgeWidth; +* // returns [ 1, 2 ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'edgeWidth', getEdgeWidth, setEdgeWidth ); + +/** +* Boolean indicating whether to display a chart legend. +* +* @name legend +* @memberof Scatterplot.prototype +* @type {boolean} +* @default false +* +* @example +* var chart = new Scatterplot({ +* 'legend': true +* }); +* // returns +* +* var v = chart.legend; +* // returns true +*/ +setReadWriteAccessor( Scatterplot.prototype, 'legend', getLegend, setLegend ); + +/** +* Symbol color scale. +* +* @name colorScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.colorScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'colorScale', function getColorScale() { + return getScale( this.config.scales, 'color' ); +}); + +/** +* Symbol edge color scale. +* +* @name edgeColorScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.edgeColorScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'edgeColorScale', function getEdgeColorScale() { + return getScale( this.config.scales, 'edgeColor' ); +}); + +/** +* Symbol edge opacity scale. +* +* @name edgeOpacityScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.edgeOpacityScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'edgeOpacityScale', function getEdgeOpacityScale() { + return getScale( this.config.scales, 'edgeOpacity' ); +}); + +/** +* Symbol edge width scale. +* +* @name edgeWidthScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.edgeWidthScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'edgeWidthScale', function getEdgeWidthScale() { + return getScale( this.config.scales, 'edgeWidth' ); +}); + +/** +* Symbol(s). +* +* @name symbols +* @memberof Scatterplot.prototype +* @type {Array} +* @default [ 'circle' ] +* +* @example +* var chart = new Scatterplot({ +* 'symbols': [ 'circle', 'square' ] +* }); +* // returns +* +* var v = chart.symbols; +* // returns [ 'circle', 'square' ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'symbols', getSymbols, setSymbols ); + +/** +* Symbol scale. +* +* @name symbolsScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.symbolsScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'symbolsScale', function getSymbolsScale() { + return getScale( this.config.scales, 'shape' ); +}); + +/** +* Symbol opacity. +* +* @name symbolOpacity +* @memberof Scatterplot.prototype +* @type {Array} +* @default [ 0.6 ] +* +* @example +* var chart = new Scatterplot({ +* 'symbolOpacity': [ 1.0, 0.5 ] +* }); +* // returns +* +* var v = chart.symbolOpacity; +* // returns [ 1.0, 0.5 ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'symbolOpacity', getSymbolOpacity, setSymbolOpacity ); + +/** +* Symbol opacity scale. +* +* @name symbolOpacityScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.symbolOpacityScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'symbolOpacityScale', function getSymbolOpacityScale() { + return getScale( this.config.scales, 'opacity' ); +}); + +/** +* Symbol size(s) (in pixels squared). +* +* @name symbolSize +* @memberof Scatterplot.prototype +* @type {Array} +* @default [ 100 ] +* +* @example +* var chart = new Scatterplot({ +* 'symbolSize': [ 100, 200 ] +* }); +* // returns +* +* var v = chart.symbolSize; +* // returns [ 100, 200 ] +*/ +setReadWriteAccessor( Scatterplot.prototype, 'symbolSize', getSymbolSize, setSymbolSize ); + +/** +* Symbol size scale. +* +* @name symbolSizeScale +* @memberof Scatterplot.prototype +* @type {Scale} +* +* @example +* var chart = new Scatterplot(); +* // returns +* +* var v = chart.symbolSizeScale; +* // returns +*/ +setReadOnlyAccessor( Scatterplot.prototype, 'symbolSizeScale', function getSymbolSizeScale() { + return getScale( this.config.scales, 'size' ); +}); + +/** +* Renders a chart. +* +* @name render +* @memberof Scatterplot.prototype +* @type {Function} +* @param {Function} clbk - callback to invoke after rendering the chart +* @throws {TypeError} must provide a function +* +* @example +* // TODO: add example +*/ +setNonEnumerableReadOnly( Scatterplot.prototype, 'render', function render( clbk ) { + if ( !isFunction( clbk ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', clbk ) ); + } + spec2svg( this.toJSON(), this.config.config, clbk ); +}); + +/** +* Serializes a chart to a JSON object. +* +* ## Notes +* +* - This method is implicitly invoked by `JSON.stringify`. +* +* @name toJSON +* @memberof Scatterplot.prototype +* @type {Function} +* @returns {Object} JSON object +* +* @example +* var chart = new Scatterplot(); +* +* var v = chart.toJSON(); +* // returns {...} +*/ +setNonEnumerableReadOnly( Scatterplot.prototype, 'toJSON', function toJSON() { + this.config.marks = this._marks; + return QuantitativeChart.prototype.toJSON.call( this ); +}); + + +// EXPORTS // + +module.exports = Scatterplot; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/properties.json b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/properties.json new file mode 100644 index 000000000000..40547b775765 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/properties.json @@ -0,0 +1,10 @@ +[ + "colors", + "edgeColors", + "edgeOpacity", + "edgeWidth", + "legend", + "symbols", + "symbolOpacity", + "symbolSize" +] diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/get.js new file mode 100644 index 000000000000..f4a2bcc2344f --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/get.js @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbol opacities. +* +* @private +* @returns {Array} opacities +*/ +function get() { + return copy( this[ prop.private ] ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/properties.js new file mode 100644 index 000000000000..f294acc264bd --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'symbolOpacity' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/set.js new file mode 100644 index 000000000000..0b41c657bdba --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-opacity/set.js @@ -0,0 +1,75 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isProbabilityArray = require( '@stdlib/assert/is-probability-array' ).primitives; +var isProbability = require( '@stdlib/assert/is-probability' ).isPrimitive; +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbol opacities. +* +* @private +* @param {(Array|number)} value - input value +* @throws {TypeError} must be a number or an array of numbers +* @returns {void} +*/ +function set( value ) { + var isNum = isProbability( value ); + if ( !isNum && !isProbabilityArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a number or an array of numbers on the interval [0,1]. Value: `%s`.', prop.name, value ) ); + } + if ( isNum ) { + value = [ value ]; + } + if ( !hasEqualValues( value, this[ prop.private ] ) ) { + debug( 'Current value: [%s]. New value: [%s].', join( this[ prop.private ], ', ' ), join( value, ', ' ) ); + + // Perform a defensive copy as we will be caching the specified symbol opacities: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Update the symbol opacity range: + this.symbolOpacityScale.range = value; + } +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/get.js new file mode 100644 index 000000000000..f3013adc0303 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/get.js @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbol sizes (in pixels squared). +* +* @private +* @returns {Array} sizes +*/ +function get() { + return copy( this[ prop.private ] ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/properties.js new file mode 100644 index 000000000000..3cc1aa8eec5d --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'symbolSize' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/set.js new file mode 100644 index 000000000000..1389e401f271 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbol-size/set.js @@ -0,0 +1,75 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isNumberArray = require( '@stdlib/assert/is-number-array' ).primitives; +var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbol sizes (in pixels squared). +* +* @private +* @param {(Array|number)} value - input value +* @throws {TypeError} must be a number or an array of numbers +* @returns {void} +*/ +function set( value ) { + var isNum = isNumber( value ); + if ( !isNum && !isNumberArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a number or an array of numbers. Value: `%s`.', prop.name, value ) ); + } + if ( isNum ) { + value = [ value ]; + } + if ( !hasEqualValues( value, this[ prop.private ] ) ) { + debug( 'Current value: [%s]. New value: [%s].', join( this[ prop.private ], ', ' ), join( value, ', ' ) ); + + // Perform a defensive copy as we will be caching the specified symbol sizes: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Update the symbol size range: + this.symbolSizeScale.range = value; + } +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/get.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/get.js new file mode 100644 index 000000000000..7d1f7d2caaac --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/get.js @@ -0,0 +1,44 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var copy = require( '@stdlib/array/base/copy' ); +var prop = require( './properties.js' ); + + +// MAIN // + +/** +* Returns the symbols. +* +* @private +* @returns {Array} symbols +*/ +function get() { + return copy( this[ prop.private ] ); +} + + +// EXPORTS // + +module.exports = get; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/properties.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/properties.js new file mode 100644 index 000000000000..67947a9093d6 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/properties.js @@ -0,0 +1,33 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var property2object = require( '@stdlib/plot/vega/base/property2object' ); + + +// MAIN // + +var obj = property2object( 'symbols' ); + + +// EXPORTS // + +module.exports = obj; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/set.js b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/set.js new file mode 100644 index 000000000000..0594c7d4b000 --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/lib/symbols/set.js @@ -0,0 +1,76 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-invalid-this */ + +'use strict'; + +// MODULES // + +var logger = require( 'debug' ); +var isSymbolArray = require( '@stdlib/plot/base/assert/is-symbol-array' ); +var isSymbol = require( '@stdlib/plot/base/assert/is-symbol' ); +var hasEqualValues = require( '@stdlib/array/base/assert/has-equal-values' ); +var copy = require( '@stdlib/array/base/copy' ); +var join = require( '@stdlib/array/base/join' ); +var symbols2shapes = require( '@stdlib/plot/base/symbols2shapes' ); +var format = require( '@stdlib/string/format' ); +var prop = require( './properties.js' ); + + +// VARIABLES // + +var debug = logger( 'scatterplot:set:'+prop.name ); + + +// MAIN // + +/** +* Sets symbols. +* +* @private +* @param {(Array|string)} value - input value +* @throws {TypeError} must be a string or an array of strings +* @returns {void} +*/ +function set( value ) { + var isStr = isSymbol( value ); + if ( !isStr && !isSymbolArray( value ) ) { + throw new TypeError( format( 'invalid assignment. `%s` must be a symbol or an array of symbols. Value: `%s`.', prop.name, value ) ); + } + if ( isStr ) { + value = [ value ]; + } + if ( !hasEqualValues( value, this[ prop.private ] ) ) { + debug( 'Current value: [%s]. New value: [%s].', join( this[ prop.private ], ', ' ), join( value, ', ' ) ); + + // Perform a defensive copy as we will be caching the specified symbols: + value = copy( value ); + + // Cache the value before updating the scale to ensure consistent state: + this[ prop.private ] = value; + + // Convert the symbols to symbol mark shapes: + this.symbolsScale.range = symbols2shapes( value ); + } +} + + +// EXPORTS // + +module.exports = set; diff --git a/lib/node_modules/@stdlib/plot/charts/scatter/ctor/package.json b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/package.json new file mode 100644 index 000000000000..22959c85b26c --- /dev/null +++ b/lib/node_modules/@stdlib/plot/charts/scatter/ctor/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/plot/charts/scatter", + "version": "0.0.0", + "description": "Scatterplot constructor.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "doc": "./docs", + "example": "./examples", + "lib": "./lib", + "test": "./test" + }, + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "plot", + "figure", + "fig", + "graph", + "chart", + "diagram", + "data", + "visualize", + "visualization", + "dataviz", + "explore", + "exploratory", + "analysis", + "quantitative", + "scatter" + ] +}