From 47cd8fa0cde9a29e03bd36a85709b4b4221e1182 Mon Sep 17 00:00:00 2001 From: Lexachoc <20377719+Lexachoc@users.noreply.github.com> Date: Mon, 28 Sep 2026 23:30:43 +0200 Subject: [PATCH 1/5] add fillpattern for scatterternary --- src/traces/scatterternary/attributes.js | 305 ++-- src/traces/scatterternary/defaults.js | 194 +-- src/types/generated/schema.d.ts | 2 + test/image/baselines/ternary_fill_pattern.png | Bin 0 -> 58164 bytes test/image/mocks/ternary_fill_pattern.json | 87 ++ test/jasmine/tests/scatterternary_test.js | 1270 +++++++++-------- test/plot-schema.json | 74 + 7 files changed, 1092 insertions(+), 840 deletions(-) create mode 100644 test/image/baselines/ternary_fill_pattern.png create mode 100644 test/image/mocks/ternary_fill_pattern.json diff --git a/src/traces/scatterternary/attributes.js b/src/traces/scatterternary/attributes.js index 315c04c4144..f4a087248fc 100644 --- a/src/traces/scatterternary/attributes.js +++ b/src/traces/scatterternary/attributes.js @@ -1,152 +1,153 @@ -'use strict'; - -const { hovertemplateAttrs, texttemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes'); -var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); -var scatterAttrs = require('../scatter/attributes'); -var baseAttrs = require('../../plots/attributes'); -var colorScaleAttrs = require('../../components/colorscale/attributes'); -var dash = require('../../components/drawing/attributes').dash; - -var extendFlat = require('../../lib/extend').extendFlat; - -var scatterMarkerAttrs = scatterAttrs.marker; -var scatterLineAttrs = scatterAttrs.line; -var scatterMarkerLineAttrs = scatterMarkerAttrs.line; - -module.exports = { - a: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Sets the quantity of component `a` in each data point.', - 'If `a`, `b`, and `c` are all provided, they need not be', - 'normalized, only the relative values matter. If only two', - 'arrays are provided they must be normalized to match', - '`ternary.sum`.' - ].join(' ') - }, - b: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Sets the quantity of component `a` in each data point.', - 'If `a`, `b`, and `c` are all provided, they need not be', - 'normalized, only the relative values matter. If only two', - 'arrays are provided they must be normalized to match', - '`ternary.sum`.' - ].join(' ') - }, - c: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Sets the quantity of component `a` in each data point.', - 'If `a`, `b`, and `c` are all provided, they need not be', - 'normalized, only the relative values matter. If only two', - 'arrays are provided they must be normalized to match', - '`ternary.sum`.' - ].join(' ') - }, - sum: { - valType: 'number', - dflt: 0, - min: 0, - editType: 'calc', - description: [ - 'The number each triplet should sum to,', - 'if only two of `a`, `b`, and `c` are provided.', - 'This overrides `ternary.sum` to normalize this specific', - 'trace, but does not affect the values displayed on the axes.', - '0 (or missing) means to use ternary.sum' - ].join(' ') - }, - mode: extendFlat({}, scatterAttrs.mode, { dflt: 'markers' }), - text: extendFlat({}, scatterAttrs.text, { - description: [ - 'Sets text elements associated with each (a,b,c) point.', - 'If a single string, the same string appears over', - 'all the data points.', - 'If an array of strings, the items are mapped in order to', - 'the data points in (a,b,c).', - 'If trace `hoverinfo` contains a *text* flag and *hovertext* is not set,', - 'these elements will be seen in the hover labels.' - ].join(' ') - }), - texttemplate: texttemplateAttrs({ editType: 'plot' }, { keys: ['a', 'b', 'c', 'text'] }), - texttemplatefallback: templatefallbackAttrs({ editType: 'plot' }), - hovertext: extendFlat({}, scatterAttrs.hovertext, { - description: [ - 'Sets hover text elements associated with each (a,b,c) point.', - 'If a single string, the same string appears over', - 'all the data points.', - 'If an array of strings, the items are mapped in order to', - 'the data points in (a,b,c).', - 'To be seen, trace `hoverinfo` must contain a *text* flag.' - ].join(' ') - }), - line: { - color: scatterLineAttrs.color, - width: scatterLineAttrs.width, - dash: dash, - backoff: scatterLineAttrs.backoff, - shape: extendFlat({}, scatterLineAttrs.shape, { values: ['linear', 'spline'] }), - smoothing: scatterLineAttrs.smoothing, - editType: 'calc' - }, - connectgaps: scatterAttrs.connectgaps, - cliponaxis: scatterAttrs.cliponaxis, - fill: extendFlat({}, scatterAttrs.fill, { - values: ['none', 'toself', 'tonext'], - dflt: 'none', - description: [ - 'Sets the area to fill with a solid color.', - 'Use with `fillcolor` if not *none*.', - 'scatterternary has a subset of the options available to scatter.', - '*toself* connects the endpoints of the trace (or each segment', - 'of the trace if it has gaps) into a closed shape.', - '*tonext* fills the space between two traces if one completely', - 'encloses the other (eg consecutive contour lines), and behaves like', - '*toself* if there is no trace before it. *tonext* should not be', - 'used if one trace does not enclose the other.' - ].join(' ') - }), - fillcolor: makeFillcolorAttr(), - marker: extendFlat( - { - symbol: scatterMarkerAttrs.symbol, - opacity: scatterMarkerAttrs.opacity, - angle: scatterMarkerAttrs.angle, - angleref: scatterMarkerAttrs.angleref, - standoff: scatterMarkerAttrs.standoff, - maxdisplayed: scatterMarkerAttrs.maxdisplayed, - size: scatterMarkerAttrs.size, - sizeref: scatterMarkerAttrs.sizeref, - sizemin: scatterMarkerAttrs.sizemin, - sizemode: scatterMarkerAttrs.sizemode, - line: extendFlat( - { - width: scatterMarkerLineAttrs.width, - dash: scatterMarkerLineAttrs.dash, - editType: 'calc' - }, - colorScaleAttrs('marker.line') - ), - gradient: scatterMarkerAttrs.gradient, - editType: 'calc' - }, - colorScaleAttrs('marker') - ), - - textfont: scatterAttrs.textfont, - textposition: scatterAttrs.textposition, - - selected: scatterAttrs.selected, - unselected: scatterAttrs.unselected, - - hoverinfo: extendFlat({}, baseAttrs.hoverinfo, { - flags: ['a', 'b', 'c', 'text', 'name'] - }), - hoveron: scatterAttrs.hoveron, - hovertemplate: hovertemplateAttrs(), - hovertemplatefallback: templatefallbackAttrs() -}; +'use strict'; + +const { hovertemplateAttrs, texttemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes'); +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); +var scatterAttrs = require('../scatter/attributes'); +var baseAttrs = require('../../plots/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); +var dash = require('../../components/drawing/attributes').dash; + +var extendFlat = require('../../lib/extend').extendFlat; + +var scatterMarkerAttrs = scatterAttrs.marker; +var scatterLineAttrs = scatterAttrs.line; +var scatterMarkerLineAttrs = scatterMarkerAttrs.line; + +module.exports = { + a: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Sets the quantity of component `a` in each data point.', + 'If `a`, `b`, and `c` are all provided, they need not be', + 'normalized, only the relative values matter. If only two', + 'arrays are provided they must be normalized to match', + '`ternary.sum`.' + ].join(' ') + }, + b: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Sets the quantity of component `a` in each data point.', + 'If `a`, `b`, and `c` are all provided, they need not be', + 'normalized, only the relative values matter. If only two', + 'arrays are provided they must be normalized to match', + '`ternary.sum`.' + ].join(' ') + }, + c: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Sets the quantity of component `a` in each data point.', + 'If `a`, `b`, and `c` are all provided, they need not be', + 'normalized, only the relative values matter. If only two', + 'arrays are provided they must be normalized to match', + '`ternary.sum`.' + ].join(' ') + }, + sum: { + valType: 'number', + dflt: 0, + min: 0, + editType: 'calc', + description: [ + 'The number each triplet should sum to,', + 'if only two of `a`, `b`, and `c` are provided.', + 'This overrides `ternary.sum` to normalize this specific', + 'trace, but does not affect the values displayed on the axes.', + '0 (or missing) means to use ternary.sum' + ].join(' ') + }, + mode: extendFlat({}, scatterAttrs.mode, { dflt: 'markers' }), + text: extendFlat({}, scatterAttrs.text, { + description: [ + 'Sets text elements associated with each (a,b,c) point.', + 'If a single string, the same string appears over', + 'all the data points.', + 'If an array of strings, the items are mapped in order to', + 'the data points in (a,b,c).', + 'If trace `hoverinfo` contains a *text* flag and *hovertext* is not set,', + 'these elements will be seen in the hover labels.' + ].join(' ') + }), + texttemplate: texttemplateAttrs({ editType: 'plot' }, { keys: ['a', 'b', 'c', 'text'] }), + texttemplatefallback: templatefallbackAttrs({ editType: 'plot' }), + hovertext: extendFlat({}, scatterAttrs.hovertext, { + description: [ + 'Sets hover text elements associated with each (a,b,c) point.', + 'If a single string, the same string appears over', + 'all the data points.', + 'If an array of strings, the items are mapped in order to', + 'the data points in (a,b,c).', + 'To be seen, trace `hoverinfo` must contain a *text* flag.' + ].join(' ') + }), + line: { + color: scatterLineAttrs.color, + width: scatterLineAttrs.width, + dash: dash, + backoff: scatterLineAttrs.backoff, + shape: extendFlat({}, scatterLineAttrs.shape, { values: ['linear', 'spline'] }), + smoothing: scatterLineAttrs.smoothing, + editType: 'calc' + }, + connectgaps: scatterAttrs.connectgaps, + cliponaxis: scatterAttrs.cliponaxis, + fill: extendFlat({}, scatterAttrs.fill, { + values: ['none', 'toself', 'tonext'], + dflt: 'none', + description: [ + 'Sets the area to fill with a solid color.', + 'Use with `fillcolor` if not *none*.', + 'scatterternary has a subset of the options available to scatter.', + '*toself* connects the endpoints of the trace (or each segment', + 'of the trace if it has gaps) into a closed shape.', + '*tonext* fills the space between two traces if one completely', + 'encloses the other (eg consecutive contour lines), and behaves like', + '*toself* if there is no trace before it. *tonext* should not be', + 'used if one trace does not enclose the other.' + ].join(' ') + }), + fillcolor: makeFillcolorAttr(), + fillpattern: scatterAttrs.fillpattern, + marker: extendFlat( + { + symbol: scatterMarkerAttrs.symbol, + opacity: scatterMarkerAttrs.opacity, + angle: scatterMarkerAttrs.angle, + angleref: scatterMarkerAttrs.angleref, + standoff: scatterMarkerAttrs.standoff, + maxdisplayed: scatterMarkerAttrs.maxdisplayed, + size: scatterMarkerAttrs.size, + sizeref: scatterMarkerAttrs.sizeref, + sizemin: scatterMarkerAttrs.sizemin, + sizemode: scatterMarkerAttrs.sizemode, + line: extendFlat( + { + width: scatterMarkerLineAttrs.width, + dash: scatterMarkerLineAttrs.dash, + editType: 'calc' + }, + colorScaleAttrs('marker.line') + ), + gradient: scatterMarkerAttrs.gradient, + editType: 'calc' + }, + colorScaleAttrs('marker') + ), + + textfont: scatterAttrs.textfont, + textposition: scatterAttrs.textposition, + + selected: scatterAttrs.selected, + unselected: scatterAttrs.unselected, + + hoverinfo: extendFlat({}, baseAttrs.hoverinfo, { + flags: ['a', 'b', 'c', 'text', 'name'] + }), + hoveron: scatterAttrs.hoveron, + hovertemplate: hovertemplateAttrs(), + hovertemplatefallback: templatefallbackAttrs() +}; diff --git a/src/traces/scatterternary/defaults.js b/src/traces/scatterternary/defaults.js index 6be1e2d0363..a10297c8da3 100644 --- a/src/traces/scatterternary/defaults.js +++ b/src/traces/scatterternary/defaults.js @@ -1,96 +1,98 @@ -'use strict'; - -var Lib = require('../../lib'); - -var constants = require('../scatter/constants'); -var subTypes = require('../scatter/subtypes'); -var handleMarkerDefaults = require('../scatter/marker_defaults'); -var handleLineDefaults = require('../scatter/line_defaults'); -var handleLineShapeDefaults = require('../scatter/line_shape_defaults'); -var handleTextDefaults = require('../scatter/text_defaults'); -var handleFillColorDefaults = require('../scatter/fillcolor_defaults'); - -var attributes = require('./attributes'); - -module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { - function coerce(attr, dflt) { - return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); - } - - var a = coerce('a'); - var b = coerce('b'); - var c = coerce('c'); - var len; - - // allow any one array to be missing, len is the minimum length of those - // present. Note that after coerce data_array's are either Arrays (which - // are truthy even if empty) or undefined. As in scatter, an empty array - // is different from undefined, because it can signify that this data is - // not known yet but expected in the future - if (a) { - len = a.length; - if (b) { - len = Math.min(len, b.length); - if (c) len = Math.min(len, c.length); - } else if (c) len = Math.min(len, c.length); - else len = 0; - } else if (b && c) { - len = Math.min(b.length, c.length); - } - - if (!len) { - traceOut.visible = false; - return; - } - - traceOut._length = len; - - coerce('sum'); - - coerce('text'); - coerce('hovertext'); - if (traceOut.hoveron !== 'fills') { - coerce('hovertemplate'); - coerce('hovertemplatefallback'); - } - - var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines'; - coerce('mode', defaultMode); - - if (subTypes.hasMarkers(traceOut)) { - handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, { gradient: true }); - } - - if (subTypes.hasLines(traceOut)) { - handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, { backoff: true }); - handleLineShapeDefaults(traceIn, traceOut, coerce); - coerce('connectgaps'); - } - - if (subTypes.hasText(traceOut)) { - coerce('texttemplate'); - coerce('texttemplatefallback'); - handleTextDefaults(traceIn, traceOut, layout, coerce); - } - - var dfltHoverOn = []; - - if (subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) { - coerce('cliponaxis'); - coerce('marker.maxdisplayed'); - dfltHoverOn.push('points'); - } - - coerce('fill'); - if (traceOut.fill !== 'none') { - handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce); - if (!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce); - } - - if (traceOut.fill === 'tonext' || traceOut.fill === 'toself') { - dfltHoverOn.push('fills'); - } - coerce('hoveron', dfltHoverOn.join('+') || 'points'); - - Lib.coerceSelectionMarkerOpacity(traceOut, coerce); -}; +'use strict'; + +var Lib = require('../../lib'); +var coercePattern = require('../../lib').coercePattern; + +var constants = require('../scatter/constants'); +var subTypes = require('../scatter/subtypes'); +var handleMarkerDefaults = require('../scatter/marker_defaults'); +var handleLineDefaults = require('../scatter/line_defaults'); +var handleLineShapeDefaults = require('../scatter/line_shape_defaults'); +var handleTextDefaults = require('../scatter/text_defaults'); +var handleFillColorDefaults = require('../scatter/fillcolor_defaults'); + +var attributes = require('./attributes'); + +module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { + function coerce(attr, dflt) { + return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); + } + + var a = coerce('a'); + var b = coerce('b'); + var c = coerce('c'); + var len; + + // allow any one array to be missing, len is the minimum length of those + // present. Note that after coerce data_array's are either Arrays (which + // are truthy even if empty) or undefined. As in scatter, an empty array + // is different from undefined, because it can signify that this data is + // not known yet but expected in the future + if (a) { + len = a.length; + if (b) { + len = Math.min(len, b.length); + if (c) len = Math.min(len, c.length); + } else if (c) len = Math.min(len, c.length); + else len = 0; + } else if (b && c) { + len = Math.min(b.length, c.length); + } + + if (!len) { + traceOut.visible = false; + return; + } + + traceOut._length = len; + + coerce('sum'); + + coerce('text'); + coerce('hovertext'); + if (traceOut.hoveron !== 'fills') { + coerce('hovertemplate'); + coerce('hovertemplatefallback'); + } + + var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines'; + coerce('mode', defaultMode); + + if (subTypes.hasMarkers(traceOut)) { + handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, { gradient: true }); + } + + if (subTypes.hasLines(traceOut)) { + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, { backoff: true }); + handleLineShapeDefaults(traceIn, traceOut, coerce); + coerce('connectgaps'); + } + + if (subTypes.hasText(traceOut)) { + coerce('texttemplate'); + coerce('texttemplatefallback'); + handleTextDefaults(traceIn, traceOut, layout, coerce); + } + + var dfltHoverOn = []; + + if (subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) { + coerce('cliponaxis'); + coerce('marker.maxdisplayed'); + dfltHoverOn.push('points'); + } + + coerce('fill'); + if (traceOut.fill !== 'none') { + handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce); + if (!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce); + coercePattern(coerce, 'fillpattern', traceOut.fillcolor, false); + } + + if (traceOut.fill === 'tonext' || traceOut.fill === 'toself') { + dfltHoverOn.push('fills'); + } + coerce('hoveron', dfltHoverOn.join('+') || 'points'); + + Lib.coerceSelectionMarkerOpacity(traceOut, coerce); +}; diff --git a/src/types/generated/schema.d.ts b/src/types/generated/schema.d.ts index 5283911ff43..99d24233f32 100644 --- a/src/types/generated/schema.d.ts +++ b/src/types/generated/schema.d.ts @@ -9559,6 +9559,8 @@ export interface ScatterternaryData { fill?: 'none' | 'toself' | 'tonext'; /** Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. */ fillcolor?: Color; + /** Sets the pattern within the marker. */ + fillpattern?: Pattern; /** * Determines what trace information appears on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. * @default 'all' diff --git a/test/image/baselines/ternary_fill_pattern.png b/test/image/baselines/ternary_fill_pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..e3a2df343fa74c2884ddd69bbe56b1a39bd94432 GIT binary patch literal 58164 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 z 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 g(9qCRi)jzdlKruH#)?Q4aE3Component B: 0.1111111
Component C: 0.5555556' - ); - - expect(scatterPointData[0].xLabelVal).toBeUndefined(); - expect(scatterPointData[0].yLabelVal).toBeUndefined(); - expect(scatterPointData[0].text).toEqual('C'); - - Plotly.restyle(gd, { - text: null, - hovertext: [['apple', 'banana', 'orange']] - }) - .then(function() { - scatterPointData = _hover(gd, xval, yval, hovermode); - - expect(scatterPointData[0].extraText).toEqual( - 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' - ); - - expect(scatterPointData[0].xLabelVal).toBeUndefined(); - expect(scatterPointData[0].yLabelVal).toBeUndefined(); - expect(scatterPointData[0].text).toEqual('orange'); - }) - .then(done, done.fail); - }); - - it('should pass along hovertemplate on hover', function(done) { - var xval = 0.42; - var yval = 0.37; - var hovermode = 'closest'; - var scatterPointData; - Plotly.restyle(gd, { - hovertemplate: 'tpl' - }) - .then(function() { - scatterPointData = _hover(gd, xval, yval, hovermode); - expect(scatterPointData[0].hovertemplate).toEqual('tpl'); - expect(scatterPointData[0].aLabel).toBe('0.3333333'); - expect(scatterPointData[0].bLabel).toBe('0.1111111'); - expect(scatterPointData[0].cLabel).toBe('0.5555556'); - }) - .then(done, done.fail); - }); - - it('should always display hoverlabel when hovertemplate is defined', function(done) { - var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_simple.json')); - - Plotly.newPlot(gd, fig) - .then(function() { - return Plotly.restyle(gd, { - hovertemplate: '%{a}, %{b}, %{c}', - name: '', - text: null, - hovertext: null - }); - }) - .then(function() { - check([380, 210], ['0.5, 0.25, 0.25']); - }) - .then(done, done.fail); - }); -}); - -describe('Test scatterternary *cliponaxis*', function() { - afterEach(destroyGraphDiv); - - it('should show/hide point/text/errorbars in clipped and non-clipped layers', function(done) { - var gd = createGraphDiv(); - var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_markers.json')); - // use simple markers here - delete fig.data[0].marker; - - function _assert(layerClips, nodeDisplays, lineClips) { - var frontLayer = d3Select('.frontplot'); - var scatterLayer = d3Select('.scatterlayer'); - - assertClip(frontLayer, layerClips[0], 1, 'front layer'); - assertClip(scatterLayer, layerClips[1], 1, 'scatter layer'); - - assertNodeDisplay( - scatterLayer.selectAll('.point'), - nodeDisplays, - 'scatter points' - ); - assertNodeDisplay( - scatterLayer.selectAll('.textpoint'), - nodeDisplays, - 'scatter text points' - ); - - assertClip( - scatterLayer.selectAll('.js-line'), - lineClips[0], lineClips[1], - 'line clips' - ); - } - - Plotly.newPlot(gd, fig) - .then(function() { - _assert( - [false, false], - [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.restyle(gd, 'visible', 'legendonly'); - }) - .then(function() { - _assert( - [false, false], - [], - [false, 0] - ); - return Plotly.restyle(gd, {visible: true, cliponaxis: null}); - }) - .then(function() { - _assert( - [true, false], - [null, null, null, null, null, null, null, null, null, null, null], - [false, 1] - ); - return Plotly.restyle(gd, 'cliponaxis', false); - }) - .then(function() { - _assert( - [false, false], - [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, 'ternary.aaxis.min', 20); - }) - .then(function() { - _assert( - [false, false], - [null, 'none', null, 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, 'ternary.baxis.min', 40); - }) - .then(function() { - _assert( - [false, false], - ['none', 'none', 'none', 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, 'ternary.caxis.min', 30); - }) - .then(function() { - _assert( - [false, false], - ['none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, { - 'ternary.aaxis.min': null, - 'ternary.baxis.min': null, - 'ternary.caxis.min': null - }); - }) - .then(function() { - _assert( - [false, false], - [null, null, null, null, null, null, null, null, null, null, null], - [true, 1] - ); - }) - .then(done, done.fail); - }); -}); - -describe('Test scatterternary texttemplate:', function() { - checkTextTemplate([{ - type: 'scatterternary', - a: [3, 2, 5], - b: [2, 5, 2], - c: [5, 2, 2 ], - mode: 'markers+text', - text: ['A', 'B', 'C'] - }], 'g.textpoint', [ - ['%{text} (%{a:.1f}, %{b:.1f}, %{c:.1f})', ['A (3.0, 2.0, 5.0)', 'B (2.0, 5.0, 2.0)', 'C (5.0, 2.0, 2.0)']] - ]); - - checkTextTemplate({ - data: [{ - type: 'scatterternary', - mode: 'text', - a: [3, 2, 5], - b: [2, 5, 2], - c: [5, 2, 2] - }], - layout: { - ternary: { - aaxis: { tickprefix: '*', ticksuffix: '*' }, - baxis: { tickprefix: '$', ticksuffix: ' !', tickformat: '.2f'}, - caxis: { tickprefix: '#', ticksuffix: '^'} - } - } - }, '.textpoint', [ - ['%{a} is %{b} is %{c}', [ - '*0.3* is $0.20 ! is #0.5^', - '*0.2222222* is $0.56 ! is #0.2222222^', - '*0.5555556* is $0.22 ! is #0.2222222^' - ]] - ]); -}); +var Plotly = require('../../../lib/index'); +var Lib = require('../../../src/lib'); +var ScatterTernary = require('../../../src/traces/scatterternary'); + +var d3Select = require('../../strict-d3').select; +var d3SelectAll = require('../../strict-d3').selectAll; +var createGraphDiv = require('../assets/create_graph_div'); +var destroyGraphDiv = require('../assets/destroy_graph_div'); + +var customAssertions = require('../assets/custom_assertions'); +var supplyAllDefaults = require('../assets/supply_defaults'); + +var mouseEvent = require('../assets/mouse_event'); +var assertHoverLabelContent = customAssertions.assertHoverLabelContent; +var checkTextTemplate = require('../assets/check_texttemplate'); + +var assertClip = customAssertions.assertClip; +var assertNodeDisplay = customAssertions.assertNodeDisplay; + +describe('scatterternary defaults', function() { + 'use strict'; + + var supplyDefaults = ScatterTernary.supplyDefaults; + + var traceIn, traceOut; + + var defaultColor = '#444'; + var layout = {}; + + beforeEach(function() { + traceOut = {}; + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (base case)', function() { + traceIn = { + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'c\' is missing case)', function() { + traceIn = { + a: [1, 2, 3], + b: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'b\' is missing case)', function() { + traceIn = { + a: [1, 2, 3], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\' is missing case)', function() { + traceIn = { + b: [1, 2, 3], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'b\ and \'c\' are missing case)', function() { + traceIn = { + a: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\ and \'c\' are missing case)', function() { + traceIn = { + b: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\ and \'b\' are missing case)', function() { + traceIn = { + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (all are missing case)', function() { + traceIn = {}; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should not truncate data arrays to the same length (\'c\' is shortest case)', function() { + // this is handled at the calc step now via _length. + traceIn = { + a: [1, 2, 3], + b: [1, 2], + c: [1] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.a).toEqual([1, 2, 3]); + expect(traceOut.b).toEqual([1, 2]); + expect(traceOut.c).toEqual([1]); + expect(traceOut._length).toBe(1); + }); + + it('should not truncate data arrays to the same length (\'a\' is shortest case)', function() { + // this is handled at the calc step now via _length. + traceIn = { + a: [1], + b: [1, 2, 3], + c: [1, 2] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.a).toEqual([1]); + expect(traceOut.b).toEqual([1, 2, 3]); + expect(traceOut.c).toEqual([1, 2]); + expect(traceOut._length).toBe(1); + }); + + it('should not truncate data arrays to the same length (\'a\' is shortest case)', function() { + // this is handled at the calc step now via _length. + traceIn = { + a: [1, 2], + b: [1], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.a).toEqual([1, 2]); + expect(traceOut.b).toEqual([1]); + expect(traceOut.c).toEqual([1, 2, 3]); + expect(traceOut._length).toBe(1); + }); + + it('is set visible: false if a, b, or c is empty', function() { + var trace0 = { + a: [1, 2], + b: [2, 1], + c: [2, 2] + }; + + ['a', 'b', 'c'].forEach(function(letter) { + traceIn = Lib.extendDeep({}, trace0); + traceIn[letter] = []; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false, letter); + }); + }); + + it('should include \'name\' in \'hoverinfo\' default if multi trace graph', function() { + traceIn = { + type: 'scatterternary', + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3] + }; + + var gd = {data: [traceIn, {}]}; + supplyAllDefaults(gd); + + expect(gd._fullData[0].hoverinfo).toBe('all'); + }); + + it('should not include \'name\' in \'hoverinfo\' default if single trace graph', function() { + traceIn = { + type: 'scatterternary', + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3] + }; + + var gd = {data: [traceIn]}; + supplyAllDefaults(gd); + + expect(gd._fullData[0].hoverinfo).toBe('a+b+c+text'); + }); + + it('should correctly assign \'hoveron\' default', function() { + traceIn = { + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3], + mode: 'lines+markers', + fill: 'tonext' + }; + + // fills and markers, you get both hover types + // you need visible: true here, as that normally gets set + // outside of the module supplyDefaults + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.hoveron).toBe('points+fills'); + + // but with only lines (or just fill) and fill tonext or toself + // you get fills + traceIn.mode = 'lines'; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.hoveron).toBe('fills'); + + // without a fill you always get points. For scatterternary, unlike + // scatter, every allowed fill but 'none' is an area fill (rather than + // a vertical / horizontal fill) so they all should default to + // hoveron points. + traceIn.fill = 'none'; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.hoveron).toBe('points'); + }); + + it('should coerce \'fillpattern\' defaults with *replace* fillpattern.fillmode', function() { + traceIn = { + a: [3, 1, 1], + b: [1, 3, 1], + c: [1, 1, 3], + mode: 'lines', + fill: 'toself', + fillcolor: 'green', + fillpattern: {shape: '+'} + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern.shape).toBe('+'); + expect(traceOut.fillpattern.fillmode).toBe('replace'); + expect(traceOut.fillpattern.bgcolor).toBeUndefined('transparent background'); + expect(traceOut.fillpattern.fgcolor).toBe('green'); + expect(traceOut.fillpattern.fgopacity).toBe(1); + expect(traceOut.fillpattern.size).toBe(8); + expect(traceOut.fillpattern.solidity).toBe(0.3); + }); + + it('should coerce \'fillpattern\' defaults with *overlay* fillpattern.fillmode', function() { + traceIn = { + a: [3, 1, 1], + b: [1, 3, 1], + c: [1, 1, 3], + mode: 'lines', + fill: 'toself', + fillcolor: 'green', + fillpattern: { + fillmode: 'overlay', + shape: '+' + } + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern.shape).toBe('+'); + expect(traceOut.fillpattern.bgcolor).toBe('green'); + expect(traceOut.fillpattern.fgcolor).toBe('rgb(255, 255, 255)'); + expect(traceOut.fillpattern.fgopacity).toBe(0.5); + }); + + it('should support a custom \'fillpattern.path\'', function() { + traceIn = { + a: [1, 2, 3], + b: [3, 2, 1], + c: [2, 2, 2], + mode: 'lines', + fill: 'toself', + fillcolor: 'green', + fillpattern: { + path: 'M0,0L8,0L8,4L0,4Z', + size: 12, + bgcolor: 'blue', + fgcolor: 'red', + fgopacity: 0.6 + } + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern.path).toBe('M0,0L8,0L8,4L0,4Z'); + expect(traceOut.fillpattern.size).toBe(12); + expect(traceOut.fillpattern.bgcolor).toBe('blue'); + expect(traceOut.fillpattern.fgcolor).toBe('red'); + expect(traceOut.fillpattern.fgopacity).toBe(0.6); + expect(traceOut.fillpattern.solidity).toBeUndefined(); + }); + + it('should not coerce \'fillpattern\' when \'fill\' is *none*', function() { + traceIn = { + a: [1, 2, 3], + b: [3, 2, 1], + c: [2, 2, 2], + mode: 'lines', + fill: 'none', + fillpattern: {shape: '+'} + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern).toBeUndefined(); + }); +}); + +describe('scatterternary calc', function() { + 'use strict'; + + var calc = ScatterTernary.calc; + + var gd, trace, cd; + + beforeEach(function() { + gd = { + _fullLayout: { + ternary: { sum: 1 } + } + }; + + trace = { + subplot: 'ternary', + sum: 1, + _length: 3 + }; + }); + + function get(cd, component) { + return cd.map(function(v) { + return v[component]; + }); + } + + it('should fill in missing component (case \'c\')', function() { + trace.a = [0.1, 0.3, 0.6]; + trace.b = [0.3, 0.6, 0.1]; + + cd = calc(gd, trace); + expect(get(cd, 'c')).toBeCloseToArray([0.6, 0.1, 0.3]); + }); + + it('should fill in missing component (case \'b\')', function() { + trace.a = [0.1, 0.3, 0.6]; + trace.c = [0.1, 0.3, 0.2]; + + cd = calc(gd, trace); + expect(get(cd, 'b')).toBeCloseToArray([0.8, 0.4, 0.2]); + }); + + it('should fill in missing component (case \'a\')', function() { + trace.b = [0.1, 0.3, 0.6]; + trace.c = [0.8, 0.4, 0.1]; + + cd = calc(gd, trace); + expect(get(cd, 'a')).toBeCloseToArray([0.1, 0.3, 0.3]); + }); + + it('should skip over non-numeric values', function() { + trace.a = [0.1, 'a', 0.6]; + trace.b = [0.1, 0.3, null]; + trace.c = [8, 0.4, 0.1]; + + cd = calc(gd, trace).map(function(obj) { delete obj.i; return obj; }); + + expect(objectToArray(cd[0])).toBeCloseToArray([ + 0.963414634, 0.012195121, 0.012195121, 0.012195121, 0.975609756 + ]); + expect(cd[1]).toEqual({ x: false, y: false }); + expect(cd[2]).toEqual({ x: false, y: false }); + }); + + function objectToArray(obj) { + return Object.keys(obj).map(function(k) { + return obj[k]; + }); + } +}); + +describe('scatterternary plot and hover', function() { + 'use strict'; + + var mock = require('../../image/mocks/ternary_simple.json'); + + afterAll(destroyGraphDiv); + + beforeAll(function(done) { + var gd = createGraphDiv(); + var mockCopy = Lib.extendDeep({}, mock); + + Plotly.newPlot(gd, mockCopy.data, mockCopy.layout).then(done); + }); + + it('should put scatterternary trace in \'frontplot\' node', function() { + var nodes = d3Select('.frontplot').selectAll('.scatter'); + + expect(nodes.size()).toEqual(1); + }); + + it('should generate one line path per trace', function() { + var nodes = d3SelectAll('path.js-line'); + + expect(nodes.size()).toEqual(mock.data.length); + }); + + it('should generate as many points as there are data points', function() { + var nodes = d3SelectAll('path.point'); + + expect(nodes.size()).toEqual(mock.data[0].a.length); + }); +}); + +describe('scatterternary hover', function() { + 'use strict'; + + var gd; + + function check(pos, content) { + mouseEvent('mousemove', pos[0], pos[1]); + + assertHoverLabelContent({ + nums: content[0], + name: content[1] + }); + } + + beforeAll(function(done) { + gd = createGraphDiv(); + var data = [{ + type: 'scatterternary', + a: [0.1, 0.2, 0.3], + b: [0.3, 0.2, 0.1], + c: [0.1, 0.4, 0.5], + text: ['A', 'B', 'C'] + }]; + Plotly.newPlot(gd, data).then(done); + }); + + afterAll(destroyGraphDiv); + + function _hover(gd, xval, yval, hovermode) { + var cd = gd.calcdata; + var ternary = gd._fullLayout.ternary._subplot; + + var pointData = { + index: false, + distance: 20, + cd: cd[0], + trace: cd[0][0].trace, + xa: ternary.xaxis, + ya: ternary.yaxis, + subplot: ternary + }; + + return ScatterTernary.hoverPoints(pointData, xval, yval, hovermode); + } + + it('should generate extra text field on hover', function(done) { + var xval = 0.42; + var yval = 0.37; + var hovermode = 'closest'; + var scatterPointData; + + scatterPointData = _hover(gd, xval, yval, hovermode); + + expect(scatterPointData[0].extraText).toEqual( + 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' + ); + + expect(scatterPointData[0].xLabelVal).toBeUndefined(); + expect(scatterPointData[0].yLabelVal).toBeUndefined(); + expect(scatterPointData[0].text).toEqual('C'); + + Plotly.restyle(gd, { + text: null, + hovertext: [['apple', 'banana', 'orange']] + }) + .then(function() { + scatterPointData = _hover(gd, xval, yval, hovermode); + + expect(scatterPointData[0].extraText).toEqual( + 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' + ); + + expect(scatterPointData[0].xLabelVal).toBeUndefined(); + expect(scatterPointData[0].yLabelVal).toBeUndefined(); + expect(scatterPointData[0].text).toEqual('orange'); + }) + .then(done, done.fail); + }); + + it('should pass along hovertemplate on hover', function(done) { + var xval = 0.42; + var yval = 0.37; + var hovermode = 'closest'; + var scatterPointData; + Plotly.restyle(gd, { + hovertemplate: 'tpl' + }) + .then(function() { + scatterPointData = _hover(gd, xval, yval, hovermode); + expect(scatterPointData[0].hovertemplate).toEqual('tpl'); + expect(scatterPointData[0].aLabel).toBe('0.3333333'); + expect(scatterPointData[0].bLabel).toBe('0.1111111'); + expect(scatterPointData[0].cLabel).toBe('0.5555556'); + }) + .then(done, done.fail); + }); + + it('should always display hoverlabel when hovertemplate is defined', function(done) { + var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_simple.json')); + + Plotly.newPlot(gd, fig) + .then(function() { + return Plotly.restyle(gd, { + hovertemplate: '%{a}, %{b}, %{c}', + name: '', + text: null, + hovertext: null + }); + }) + .then(function() { + check([380, 210], ['0.5, 0.25, 0.25']); + }) + .then(done, done.fail); + }); +}); + +describe('Test scatterternary *cliponaxis*', function() { + afterEach(destroyGraphDiv); + + it('should show/hide point/text/errorbars in clipped and non-clipped layers', function(done) { + var gd = createGraphDiv(); + var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_markers.json')); + // use simple markers here + delete fig.data[0].marker; + + function _assert(layerClips, nodeDisplays, lineClips) { + var frontLayer = d3Select('.frontplot'); + var scatterLayer = d3Select('.scatterlayer'); + + assertClip(frontLayer, layerClips[0], 1, 'front layer'); + assertClip(scatterLayer, layerClips[1], 1, 'scatter layer'); + + assertNodeDisplay( + scatterLayer.selectAll('.point'), + nodeDisplays, + 'scatter points' + ); + assertNodeDisplay( + scatterLayer.selectAll('.textpoint'), + nodeDisplays, + 'scatter text points' + ); + + assertClip( + scatterLayer.selectAll('.js-line'), + lineClips[0], lineClips[1], + 'line clips' + ); + } + + Plotly.newPlot(gd, fig) + .then(function() { + _assert( + [false, false], + [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.restyle(gd, 'visible', 'legendonly'); + }) + .then(function() { + _assert( + [false, false], + [], + [false, 0] + ); + return Plotly.restyle(gd, {visible: true, cliponaxis: null}); + }) + .then(function() { + _assert( + [true, false], + [null, null, null, null, null, null, null, null, null, null, null], + [false, 1] + ); + return Plotly.restyle(gd, 'cliponaxis', false); + }) + .then(function() { + _assert( + [false, false], + [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, 'ternary.aaxis.min', 20); + }) + .then(function() { + _assert( + [false, false], + [null, 'none', null, 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, 'ternary.baxis.min', 40); + }) + .then(function() { + _assert( + [false, false], + ['none', 'none', 'none', 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, 'ternary.caxis.min', 30); + }) + .then(function() { + _assert( + [false, false], + ['none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, { + 'ternary.aaxis.min': null, + 'ternary.baxis.min': null, + 'ternary.caxis.min': null + }); + }) + .then(function() { + _assert( + [false, false], + [null, null, null, null, null, null, null, null, null, null, null], + [true, 1] + ); + }) + .then(done, done.fail); + }); +}); + +describe('Test scatterternary texttemplate:', function() { + checkTextTemplate([{ + type: 'scatterternary', + a: [3, 2, 5], + b: [2, 5, 2], + c: [5, 2, 2 ], + mode: 'markers+text', + text: ['A', 'B', 'C'] + }], 'g.textpoint', [ + ['%{text} (%{a:.1f}, %{b:.1f}, %{c:.1f})', ['A (3.0, 2.0, 5.0)', 'B (2.0, 5.0, 2.0)', 'C (5.0, 2.0, 2.0)']] + ]); + + checkTextTemplate({ + data: [{ + type: 'scatterternary', + mode: 'text', + a: [3, 2, 5], + b: [2, 5, 2], + c: [5, 2, 2] + }], + layout: { + ternary: { + aaxis: { tickprefix: '*', ticksuffix: '*' }, + baxis: { tickprefix: '$', ticksuffix: ' !', tickformat: '.2f'}, + caxis: { tickprefix: '#', ticksuffix: '^'} + } + } + }, '.textpoint', [ + ['%{a} is %{b} is %{c}', [ + '*0.3* is $0.20 ! is #0.5^', + '*0.2222222* is $0.56 ! is #0.2222222^', + '*0.5555556* is $0.22 ! is #0.2222222^' + ]] + ]); +}); diff --git a/test/plot-schema.json b/test/plot-schema.json index 3f8728d1b01..ff446f9ea8a 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -71299,6 +71299,80 @@ "editType": "style", "valType": "color" }, + "fillpattern": { + "bgcolor": { + "arrayOk": true, + "description": "When there is no colorscale sets the color of background pattern fill. Defaults to a `marker.color` background when `fillmode` is *overlay*. Otherwise, defaults to a transparent background.", + "editType": "style", + "valType": "color" + }, + "description": "Sets the pattern within the marker.", + "editType": "style", + "fgcolor": { + "arrayOk": true, + "description": "When there is no colorscale sets the color of foreground pattern fill. Defaults to a `marker.color` background when `fillmode` is *replace*. Otherwise, defaults to dark grey or white to increase contrast with the `bgcolor`.", + "editType": "style", + "valType": "color" + }, + "fgopacity": { + "description": "Sets the opacity of the foreground pattern fill. Defaults to a 0.5 when `fillmode` is *overlay*. Otherwise, defaults to 1.", + "editType": "style", + "max": 1, + "min": 0, + "valType": "number" + }, + "fillmode": { + "description": "Determines whether `marker.color` should be used as a default to `bgcolor` or a `fgcolor`.", + "dflt": "replace", + "editType": "style", + "valType": "enumerated", + "values": [ + "replace", + "overlay" + ] + }, + "path": { + "arrayOk": true, + "description": "Sets a custom path for pattern fill. Use with no `shape` or `solidity`, provide an SVG path string for the regions of the square from (0,0) to (`size`,`size`) to color.", + "editType": "style", + "valType": "string" + }, + "role": "object", + "shape": { + "arrayOk": true, + "description": "Sets the shape of the pattern fill. By default, no pattern is used for filling the area.", + "dflt": "", + "editType": "style", + "valType": "enumerated", + "values": [ + "", + "/", + "\\", + "x", + "-", + "|", + "+", + "." + ] + }, + "size": { + "arrayOk": true, + "description": "Sets the size of unit squares of the pattern fill in pixels, which corresponds to the interval of repetition of the pattern.", + "dflt": 8, + "editType": "style", + "min": 0, + "valType": "number" + }, + "solidity": { + "arrayOk": true, + "description": "Sets the solidity of the pattern fill. Solidity is roughly the fraction of the area filled by the pattern. Solidity of 0 shows only the background color without pattern and solidty of 1 shows only the foreground color without pattern.", + "dflt": 0.3, + "editType": "style", + "max": 1, + "min": 0, + "valType": "number" + } + }, "hoverinfo": { "arrayOk": true, "description": "Determines what trace information appears on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired.", From 65c64af624f2b2c04d4bdb2e6341ed596a2b090f Mon Sep 17 00:00:00 2001 From: Lexachoc <20377719+Lexachoc@users.noreply.github.com> Date: Mon, 28 Sep 2026 23:35:46 +0200 Subject: [PATCH 2/5] add draftlog --- draftlogs/8084_add.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/8084_add.md diff --git a/draftlogs/8084_add.md b/draftlogs/8084_add.md new file mode 100644 index 00000000000..e2ac4a59a54 --- /dev/null +++ b/draftlogs/8084_add.md @@ -0,0 +1 @@ + - Add `fillpattern` support for `scatterternary` trace [[#8084](https://github.com/plotly/plotly.js/pull/8084)] \ No newline at end of file From 70e9b4bb3badc73397c98740f6c60947f14c47cf Mon Sep 17 00:00:00 2001 From: Lexachoc <20377719+Lexachoc@users.noreply.github.com> Date: Mon, 28 Sep 2026 23:48:21 +0200 Subject: [PATCH 3/5] update baseline from CI artifacts --- test/image/baselines/ternary_fill_pattern.png | Bin 58164 -> 61537 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/image/baselines/ternary_fill_pattern.png b/test/image/baselines/ternary_fill_pattern.png index e3a2df343fa74c2884ddd69bbe56b1a39bd94432..9bb80a62ad2edb9e5743e391902d3e41760ac82c 100644 GIT binary patch literal 61537 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 literal 58164 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 z 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 g(9qCRi)jzdlKruH#)?Q4aE3 Date: Tue, 29 Sep 2026 00:09:09 +0200 Subject: [PATCH 4/5] update line separators because of Windows problem --- src/traces/scatterternary/attributes.js | 306 ++++++++++++------------ src/traces/scatterternary/defaults.js | 196 +++++++-------- 2 files changed, 251 insertions(+), 251 deletions(-) diff --git a/src/traces/scatterternary/attributes.js b/src/traces/scatterternary/attributes.js index f4a087248fc..2fb604b9c04 100644 --- a/src/traces/scatterternary/attributes.js +++ b/src/traces/scatterternary/attributes.js @@ -1,153 +1,153 @@ -'use strict'; - -const { hovertemplateAttrs, texttemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes'); -var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); -var scatterAttrs = require('../scatter/attributes'); -var baseAttrs = require('../../plots/attributes'); -var colorScaleAttrs = require('../../components/colorscale/attributes'); -var dash = require('../../components/drawing/attributes').dash; - -var extendFlat = require('../../lib/extend').extendFlat; - -var scatterMarkerAttrs = scatterAttrs.marker; -var scatterLineAttrs = scatterAttrs.line; -var scatterMarkerLineAttrs = scatterMarkerAttrs.line; - -module.exports = { - a: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Sets the quantity of component `a` in each data point.', - 'If `a`, `b`, and `c` are all provided, they need not be', - 'normalized, only the relative values matter. If only two', - 'arrays are provided they must be normalized to match', - '`ternary.sum`.' - ].join(' ') - }, - b: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Sets the quantity of component `a` in each data point.', - 'If `a`, `b`, and `c` are all provided, they need not be', - 'normalized, only the relative values matter. If only two', - 'arrays are provided they must be normalized to match', - '`ternary.sum`.' - ].join(' ') - }, - c: { - valType: 'data_array', - editType: 'calc', - description: [ - 'Sets the quantity of component `a` in each data point.', - 'If `a`, `b`, and `c` are all provided, they need not be', - 'normalized, only the relative values matter. If only two', - 'arrays are provided they must be normalized to match', - '`ternary.sum`.' - ].join(' ') - }, - sum: { - valType: 'number', - dflt: 0, - min: 0, - editType: 'calc', - description: [ - 'The number each triplet should sum to,', - 'if only two of `a`, `b`, and `c` are provided.', - 'This overrides `ternary.sum` to normalize this specific', - 'trace, but does not affect the values displayed on the axes.', - '0 (or missing) means to use ternary.sum' - ].join(' ') - }, - mode: extendFlat({}, scatterAttrs.mode, { dflt: 'markers' }), - text: extendFlat({}, scatterAttrs.text, { - description: [ - 'Sets text elements associated with each (a,b,c) point.', - 'If a single string, the same string appears over', - 'all the data points.', - 'If an array of strings, the items are mapped in order to', - 'the data points in (a,b,c).', - 'If trace `hoverinfo` contains a *text* flag and *hovertext* is not set,', - 'these elements will be seen in the hover labels.' - ].join(' ') - }), - texttemplate: texttemplateAttrs({ editType: 'plot' }, { keys: ['a', 'b', 'c', 'text'] }), - texttemplatefallback: templatefallbackAttrs({ editType: 'plot' }), - hovertext: extendFlat({}, scatterAttrs.hovertext, { - description: [ - 'Sets hover text elements associated with each (a,b,c) point.', - 'If a single string, the same string appears over', - 'all the data points.', - 'If an array of strings, the items are mapped in order to', - 'the data points in (a,b,c).', - 'To be seen, trace `hoverinfo` must contain a *text* flag.' - ].join(' ') - }), - line: { - color: scatterLineAttrs.color, - width: scatterLineAttrs.width, - dash: dash, - backoff: scatterLineAttrs.backoff, - shape: extendFlat({}, scatterLineAttrs.shape, { values: ['linear', 'spline'] }), - smoothing: scatterLineAttrs.smoothing, - editType: 'calc' - }, - connectgaps: scatterAttrs.connectgaps, - cliponaxis: scatterAttrs.cliponaxis, - fill: extendFlat({}, scatterAttrs.fill, { - values: ['none', 'toself', 'tonext'], - dflt: 'none', - description: [ - 'Sets the area to fill with a solid color.', - 'Use with `fillcolor` if not *none*.', - 'scatterternary has a subset of the options available to scatter.', - '*toself* connects the endpoints of the trace (or each segment', - 'of the trace if it has gaps) into a closed shape.', - '*tonext* fills the space between two traces if one completely', - 'encloses the other (eg consecutive contour lines), and behaves like', - '*toself* if there is no trace before it. *tonext* should not be', - 'used if one trace does not enclose the other.' - ].join(' ') - }), - fillcolor: makeFillcolorAttr(), - fillpattern: scatterAttrs.fillpattern, - marker: extendFlat( - { - symbol: scatterMarkerAttrs.symbol, - opacity: scatterMarkerAttrs.opacity, - angle: scatterMarkerAttrs.angle, - angleref: scatterMarkerAttrs.angleref, - standoff: scatterMarkerAttrs.standoff, - maxdisplayed: scatterMarkerAttrs.maxdisplayed, - size: scatterMarkerAttrs.size, - sizeref: scatterMarkerAttrs.sizeref, - sizemin: scatterMarkerAttrs.sizemin, - sizemode: scatterMarkerAttrs.sizemode, - line: extendFlat( - { - width: scatterMarkerLineAttrs.width, - dash: scatterMarkerLineAttrs.dash, - editType: 'calc' - }, - colorScaleAttrs('marker.line') - ), - gradient: scatterMarkerAttrs.gradient, - editType: 'calc' - }, - colorScaleAttrs('marker') - ), - - textfont: scatterAttrs.textfont, - textposition: scatterAttrs.textposition, - - selected: scatterAttrs.selected, - unselected: scatterAttrs.unselected, - - hoverinfo: extendFlat({}, baseAttrs.hoverinfo, { - flags: ['a', 'b', 'c', 'text', 'name'] - }), - hoveron: scatterAttrs.hoveron, - hovertemplate: hovertemplateAttrs(), - hovertemplatefallback: templatefallbackAttrs() -}; +'use strict'; + +const { hovertemplateAttrs, texttemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes'); +var makeFillcolorAttr = require('../scatter/fillcolor_attribute'); +var scatterAttrs = require('../scatter/attributes'); +var baseAttrs = require('../../plots/attributes'); +var colorScaleAttrs = require('../../components/colorscale/attributes'); +var dash = require('../../components/drawing/attributes').dash; + +var extendFlat = require('../../lib/extend').extendFlat; + +var scatterMarkerAttrs = scatterAttrs.marker; +var scatterLineAttrs = scatterAttrs.line; +var scatterMarkerLineAttrs = scatterMarkerAttrs.line; + +module.exports = { + a: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Sets the quantity of component `a` in each data point.', + 'If `a`, `b`, and `c` are all provided, they need not be', + 'normalized, only the relative values matter. If only two', + 'arrays are provided they must be normalized to match', + '`ternary.sum`.' + ].join(' ') + }, + b: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Sets the quantity of component `a` in each data point.', + 'If `a`, `b`, and `c` are all provided, they need not be', + 'normalized, only the relative values matter. If only two', + 'arrays are provided they must be normalized to match', + '`ternary.sum`.' + ].join(' ') + }, + c: { + valType: 'data_array', + editType: 'calc', + description: [ + 'Sets the quantity of component `a` in each data point.', + 'If `a`, `b`, and `c` are all provided, they need not be', + 'normalized, only the relative values matter. If only two', + 'arrays are provided they must be normalized to match', + '`ternary.sum`.' + ].join(' ') + }, + sum: { + valType: 'number', + dflt: 0, + min: 0, + editType: 'calc', + description: [ + 'The number each triplet should sum to,', + 'if only two of `a`, `b`, and `c` are provided.', + 'This overrides `ternary.sum` to normalize this specific', + 'trace, but does not affect the values displayed on the axes.', + '0 (or missing) means to use ternary.sum' + ].join(' ') + }, + mode: extendFlat({}, scatterAttrs.mode, { dflt: 'markers' }), + text: extendFlat({}, scatterAttrs.text, { + description: [ + 'Sets text elements associated with each (a,b,c) point.', + 'If a single string, the same string appears over', + 'all the data points.', + 'If an array of strings, the items are mapped in order to', + 'the data points in (a,b,c).', + 'If trace `hoverinfo` contains a *text* flag and *hovertext* is not set,', + 'these elements will be seen in the hover labels.' + ].join(' ') + }), + texttemplate: texttemplateAttrs({ editType: 'plot' }, { keys: ['a', 'b', 'c', 'text'] }), + texttemplatefallback: templatefallbackAttrs({ editType: 'plot' }), + hovertext: extendFlat({}, scatterAttrs.hovertext, { + description: [ + 'Sets hover text elements associated with each (a,b,c) point.', + 'If a single string, the same string appears over', + 'all the data points.', + 'If an array of strings, the items are mapped in order to', + 'the data points in (a,b,c).', + 'To be seen, trace `hoverinfo` must contain a *text* flag.' + ].join(' ') + }), + line: { + color: scatterLineAttrs.color, + width: scatterLineAttrs.width, + dash: dash, + backoff: scatterLineAttrs.backoff, + shape: extendFlat({}, scatterLineAttrs.shape, { values: ['linear', 'spline'] }), + smoothing: scatterLineAttrs.smoothing, + editType: 'calc' + }, + connectgaps: scatterAttrs.connectgaps, + cliponaxis: scatterAttrs.cliponaxis, + fill: extendFlat({}, scatterAttrs.fill, { + values: ['none', 'toself', 'tonext'], + dflt: 'none', + description: [ + 'Sets the area to fill with a solid color.', + 'Use with `fillcolor` if not *none*.', + 'scatterternary has a subset of the options available to scatter.', + '*toself* connects the endpoints of the trace (or each segment', + 'of the trace if it has gaps) into a closed shape.', + '*tonext* fills the space between two traces if one completely', + 'encloses the other (eg consecutive contour lines), and behaves like', + '*toself* if there is no trace before it. *tonext* should not be', + 'used if one trace does not enclose the other.' + ].join(' ') + }), + fillcolor: makeFillcolorAttr(), + fillpattern: scatterAttrs.fillpattern, + marker: extendFlat( + { + symbol: scatterMarkerAttrs.symbol, + opacity: scatterMarkerAttrs.opacity, + angle: scatterMarkerAttrs.angle, + angleref: scatterMarkerAttrs.angleref, + standoff: scatterMarkerAttrs.standoff, + maxdisplayed: scatterMarkerAttrs.maxdisplayed, + size: scatterMarkerAttrs.size, + sizeref: scatterMarkerAttrs.sizeref, + sizemin: scatterMarkerAttrs.sizemin, + sizemode: scatterMarkerAttrs.sizemode, + line: extendFlat( + { + width: scatterMarkerLineAttrs.width, + dash: scatterMarkerLineAttrs.dash, + editType: 'calc' + }, + colorScaleAttrs('marker.line') + ), + gradient: scatterMarkerAttrs.gradient, + editType: 'calc' + }, + colorScaleAttrs('marker') + ), + + textfont: scatterAttrs.textfont, + textposition: scatterAttrs.textposition, + + selected: scatterAttrs.selected, + unselected: scatterAttrs.unselected, + + hoverinfo: extendFlat({}, baseAttrs.hoverinfo, { + flags: ['a', 'b', 'c', 'text', 'name'] + }), + hoveron: scatterAttrs.hoveron, + hovertemplate: hovertemplateAttrs(), + hovertemplatefallback: templatefallbackAttrs() +}; diff --git a/src/traces/scatterternary/defaults.js b/src/traces/scatterternary/defaults.js index a10297c8da3..6ea22affdda 100644 --- a/src/traces/scatterternary/defaults.js +++ b/src/traces/scatterternary/defaults.js @@ -1,98 +1,98 @@ -'use strict'; - -var Lib = require('../../lib'); -var coercePattern = require('../../lib').coercePattern; - -var constants = require('../scatter/constants'); -var subTypes = require('../scatter/subtypes'); -var handleMarkerDefaults = require('../scatter/marker_defaults'); -var handleLineDefaults = require('../scatter/line_defaults'); -var handleLineShapeDefaults = require('../scatter/line_shape_defaults'); -var handleTextDefaults = require('../scatter/text_defaults'); -var handleFillColorDefaults = require('../scatter/fillcolor_defaults'); - -var attributes = require('./attributes'); - -module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { - function coerce(attr, dflt) { - return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); - } - - var a = coerce('a'); - var b = coerce('b'); - var c = coerce('c'); - var len; - - // allow any one array to be missing, len is the minimum length of those - // present. Note that after coerce data_array's are either Arrays (which - // are truthy even if empty) or undefined. As in scatter, an empty array - // is different from undefined, because it can signify that this data is - // not known yet but expected in the future - if (a) { - len = a.length; - if (b) { - len = Math.min(len, b.length); - if (c) len = Math.min(len, c.length); - } else if (c) len = Math.min(len, c.length); - else len = 0; - } else if (b && c) { - len = Math.min(b.length, c.length); - } - - if (!len) { - traceOut.visible = false; - return; - } - - traceOut._length = len; - - coerce('sum'); - - coerce('text'); - coerce('hovertext'); - if (traceOut.hoveron !== 'fills') { - coerce('hovertemplate'); - coerce('hovertemplatefallback'); - } - - var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines'; - coerce('mode', defaultMode); - - if (subTypes.hasMarkers(traceOut)) { - handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, { gradient: true }); - } - - if (subTypes.hasLines(traceOut)) { - handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, { backoff: true }); - handleLineShapeDefaults(traceIn, traceOut, coerce); - coerce('connectgaps'); - } - - if (subTypes.hasText(traceOut)) { - coerce('texttemplate'); - coerce('texttemplatefallback'); - handleTextDefaults(traceIn, traceOut, layout, coerce); - } - - var dfltHoverOn = []; - - if (subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) { - coerce('cliponaxis'); - coerce('marker.maxdisplayed'); - dfltHoverOn.push('points'); - } - - coerce('fill'); - if (traceOut.fill !== 'none') { - handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce); - if (!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce); - coercePattern(coerce, 'fillpattern', traceOut.fillcolor, false); - } - - if (traceOut.fill === 'tonext' || traceOut.fill === 'toself') { - dfltHoverOn.push('fills'); - } - coerce('hoveron', dfltHoverOn.join('+') || 'points'); - - Lib.coerceSelectionMarkerOpacity(traceOut, coerce); -}; +'use strict'; + +var Lib = require('../../lib'); +var coercePattern = require('../../lib').coercePattern; + +var constants = require('../scatter/constants'); +var subTypes = require('../scatter/subtypes'); +var handleMarkerDefaults = require('../scatter/marker_defaults'); +var handleLineDefaults = require('../scatter/line_defaults'); +var handleLineShapeDefaults = require('../scatter/line_shape_defaults'); +var handleTextDefaults = require('../scatter/text_defaults'); +var handleFillColorDefaults = require('../scatter/fillcolor_defaults'); + +var attributes = require('./attributes'); + +module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { + function coerce(attr, dflt) { + return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); + } + + var a = coerce('a'); + var b = coerce('b'); + var c = coerce('c'); + var len; + + // allow any one array to be missing, len is the minimum length of those + // present. Note that after coerce data_array's are either Arrays (which + // are truthy even if empty) or undefined. As in scatter, an empty array + // is different from undefined, because it can signify that this data is + // not known yet but expected in the future + if (a) { + len = a.length; + if (b) { + len = Math.min(len, b.length); + if (c) len = Math.min(len, c.length); + } else if (c) len = Math.min(len, c.length); + else len = 0; + } else if (b && c) { + len = Math.min(b.length, c.length); + } + + if (!len) { + traceOut.visible = false; + return; + } + + traceOut._length = len; + + coerce('sum'); + + coerce('text'); + coerce('hovertext'); + if (traceOut.hoveron !== 'fills') { + coerce('hovertemplate'); + coerce('hovertemplatefallback'); + } + + var defaultMode = len < constants.PTS_LINESONLY ? 'lines+markers' : 'lines'; + coerce('mode', defaultMode); + + if (subTypes.hasMarkers(traceOut)) { + handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, { gradient: true }); + } + + if (subTypes.hasLines(traceOut)) { + handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, { backoff: true }); + handleLineShapeDefaults(traceIn, traceOut, coerce); + coerce('connectgaps'); + } + + if (subTypes.hasText(traceOut)) { + coerce('texttemplate'); + coerce('texttemplatefallback'); + handleTextDefaults(traceIn, traceOut, layout, coerce); + } + + var dfltHoverOn = []; + + if (subTypes.hasMarkers(traceOut) || subTypes.hasText(traceOut)) { + coerce('cliponaxis'); + coerce('marker.maxdisplayed'); + dfltHoverOn.push('points'); + } + + coerce('fill'); + if (traceOut.fill !== 'none') { + handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce); + if (!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce); + coercePattern(coerce, 'fillpattern', traceOut.fillcolor, false); + } + + if (traceOut.fill === 'tonext' || traceOut.fill === 'toself') { + dfltHoverOn.push('fills'); + } + coerce('hoveron', dfltHoverOn.join('+') || 'points'); + + Lib.coerceSelectionMarkerOpacity(traceOut, coerce); +}; From ecdb7528cb07893e7faa47b61194896edf96e454 Mon Sep 17 00:00:00 2001 From: Lexachoc <20377719+Lexachoc@users.noreply.github.com> Date: Tue, 29 Sep 2026 21:08:27 +0200 Subject: [PATCH 5/5] update line separators because of Windows problem --- test/jasmine/tests/scatterternary_test.js | 1356 ++++++++++----------- 1 file changed, 678 insertions(+), 678 deletions(-) diff --git a/test/jasmine/tests/scatterternary_test.js b/test/jasmine/tests/scatterternary_test.js index 03908e53064..233edfdc398 100644 --- a/test/jasmine/tests/scatterternary_test.js +++ b/test/jasmine/tests/scatterternary_test.js @@ -1,678 +1,678 @@ -var Plotly = require('../../../lib/index'); -var Lib = require('../../../src/lib'); -var ScatterTernary = require('../../../src/traces/scatterternary'); - -var d3Select = require('../../strict-d3').select; -var d3SelectAll = require('../../strict-d3').selectAll; -var createGraphDiv = require('../assets/create_graph_div'); -var destroyGraphDiv = require('../assets/destroy_graph_div'); - -var customAssertions = require('../assets/custom_assertions'); -var supplyAllDefaults = require('../assets/supply_defaults'); - -var mouseEvent = require('../assets/mouse_event'); -var assertHoverLabelContent = customAssertions.assertHoverLabelContent; -var checkTextTemplate = require('../assets/check_texttemplate'); - -var assertClip = customAssertions.assertClip; -var assertNodeDisplay = customAssertions.assertNodeDisplay; - -describe('scatterternary defaults', function() { - 'use strict'; - - var supplyDefaults = ScatterTernary.supplyDefaults; - - var traceIn, traceOut; - - var defaultColor = '#444'; - var layout = {}; - - beforeEach(function() { - traceOut = {}; - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (base case)', function() { - traceIn = { - a: [1, 2, 3], - b: [1, 2, 3], - c: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).not.toBe(true); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'c\' is missing case)', function() { - traceIn = { - a: [1, 2, 3], - b: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).not.toBe(true); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'b\' is missing case)', function() { - traceIn = { - a: [1, 2, 3], - c: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).not.toBe(true); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\' is missing case)', function() { - traceIn = { - b: [1, 2, 3], - c: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).not.toBe(true); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'b\ and \'c\' are missing case)', function() { - traceIn = { - a: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\ and \'c\' are missing case)', function() { - traceIn = { - b: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\ and \'b\' are missing case)', function() { - traceIn = { - c: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should allow one of \'a\', \'b\' or \'c\' to be missing (all are missing case)', function() { - traceIn = {}; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should not truncate data arrays to the same length (\'c\' is shortest case)', function() { - // this is handled at the calc step now via _length. - traceIn = { - a: [1, 2, 3], - b: [1, 2], - c: [1] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.a).toEqual([1, 2, 3]); - expect(traceOut.b).toEqual([1, 2]); - expect(traceOut.c).toEqual([1]); - expect(traceOut._length).toBe(1); - }); - - it('should not truncate data arrays to the same length (\'a\' is shortest case)', function() { - // this is handled at the calc step now via _length. - traceIn = { - a: [1], - b: [1, 2, 3], - c: [1, 2] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.a).toEqual([1]); - expect(traceOut.b).toEqual([1, 2, 3]); - expect(traceOut.c).toEqual([1, 2]); - expect(traceOut._length).toBe(1); - }); - - it('should not truncate data arrays to the same length (\'a\' is shortest case)', function() { - // this is handled at the calc step now via _length. - traceIn = { - a: [1, 2], - b: [1], - c: [1, 2, 3] - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.a).toEqual([1, 2]); - expect(traceOut.b).toEqual([1]); - expect(traceOut.c).toEqual([1, 2, 3]); - expect(traceOut._length).toBe(1); - }); - - it('is set visible: false if a, b, or c is empty', function() { - var trace0 = { - a: [1, 2], - b: [2, 1], - c: [2, 2] - }; - - ['a', 'b', 'c'].forEach(function(letter) { - traceIn = Lib.extendDeep({}, trace0); - traceIn[letter] = []; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false, letter); - }); - }); - - it('should include \'name\' in \'hoverinfo\' default if multi trace graph', function() { - traceIn = { - type: 'scatterternary', - a: [1, 2, 3], - b: [1, 2, 3], - c: [1, 2, 3] - }; - - var gd = {data: [traceIn, {}]}; - supplyAllDefaults(gd); - - expect(gd._fullData[0].hoverinfo).toBe('all'); - }); - - it('should not include \'name\' in \'hoverinfo\' default if single trace graph', function() { - traceIn = { - type: 'scatterternary', - a: [1, 2, 3], - b: [1, 2, 3], - c: [1, 2, 3] - }; - - var gd = {data: [traceIn]}; - supplyAllDefaults(gd); - - expect(gd._fullData[0].hoverinfo).toBe('a+b+c+text'); - }); - - it('should correctly assign \'hoveron\' default', function() { - traceIn = { - a: [1, 2, 3], - b: [1, 2, 3], - c: [1, 2, 3], - mode: 'lines+markers', - fill: 'tonext' - }; - - // fills and markers, you get both hover types - // you need visible: true here, as that normally gets set - // outside of the module supplyDefaults - traceOut = {visible: true}; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.hoveron).toBe('points+fills'); - - // but with only lines (or just fill) and fill tonext or toself - // you get fills - traceIn.mode = 'lines'; - traceOut = {visible: true}; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.hoveron).toBe('fills'); - - // without a fill you always get points. For scatterternary, unlike - // scatter, every allowed fill but 'none' is an area fill (rather than - // a vertical / horizontal fill) so they all should default to - // hoveron points. - traceIn.fill = 'none'; - traceOut = {visible: true}; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.hoveron).toBe('points'); - }); - - it('should coerce \'fillpattern\' defaults with *replace* fillpattern.fillmode', function() { - traceIn = { - a: [3, 1, 1], - b: [1, 3, 1], - c: [1, 1, 3], - mode: 'lines', - fill: 'toself', - fillcolor: 'green', - fillpattern: {shape: '+'} - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - - expect(traceOut.fillpattern.shape).toBe('+'); - expect(traceOut.fillpattern.fillmode).toBe('replace'); - expect(traceOut.fillpattern.bgcolor).toBeUndefined('transparent background'); - expect(traceOut.fillpattern.fgcolor).toBe('green'); - expect(traceOut.fillpattern.fgopacity).toBe(1); - expect(traceOut.fillpattern.size).toBe(8); - expect(traceOut.fillpattern.solidity).toBe(0.3); - }); - - it('should coerce \'fillpattern\' defaults with *overlay* fillpattern.fillmode', function() { - traceIn = { - a: [3, 1, 1], - b: [1, 3, 1], - c: [1, 1, 3], - mode: 'lines', - fill: 'toself', - fillcolor: 'green', - fillpattern: { - fillmode: 'overlay', - shape: '+' - } - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - - expect(traceOut.fillpattern.shape).toBe('+'); - expect(traceOut.fillpattern.bgcolor).toBe('green'); - expect(traceOut.fillpattern.fgcolor).toBe('rgb(255, 255, 255)'); - expect(traceOut.fillpattern.fgopacity).toBe(0.5); - }); - - it('should support a custom \'fillpattern.path\'', function() { - traceIn = { - a: [1, 2, 3], - b: [3, 2, 1], - c: [2, 2, 2], - mode: 'lines', - fill: 'toself', - fillcolor: 'green', - fillpattern: { - path: 'M0,0L8,0L8,4L0,4Z', - size: 12, - bgcolor: 'blue', - fgcolor: 'red', - fgopacity: 0.6 - } - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - - expect(traceOut.fillpattern.path).toBe('M0,0L8,0L8,4L0,4Z'); - expect(traceOut.fillpattern.size).toBe(12); - expect(traceOut.fillpattern.bgcolor).toBe('blue'); - expect(traceOut.fillpattern.fgcolor).toBe('red'); - expect(traceOut.fillpattern.fgopacity).toBe(0.6); - expect(traceOut.fillpattern.solidity).toBeUndefined(); - }); - - it('should not coerce \'fillpattern\' when \'fill\' is *none*', function() { - traceIn = { - a: [1, 2, 3], - b: [3, 2, 1], - c: [2, 2, 2], - mode: 'lines', - fill: 'none', - fillpattern: {shape: '+'} - }; - - supplyDefaults(traceIn, traceOut, defaultColor, layout); - - expect(traceOut.fillpattern).toBeUndefined(); - }); -}); - -describe('scatterternary calc', function() { - 'use strict'; - - var calc = ScatterTernary.calc; - - var gd, trace, cd; - - beforeEach(function() { - gd = { - _fullLayout: { - ternary: { sum: 1 } - } - }; - - trace = { - subplot: 'ternary', - sum: 1, - _length: 3 - }; - }); - - function get(cd, component) { - return cd.map(function(v) { - return v[component]; - }); - } - - it('should fill in missing component (case \'c\')', function() { - trace.a = [0.1, 0.3, 0.6]; - trace.b = [0.3, 0.6, 0.1]; - - cd = calc(gd, trace); - expect(get(cd, 'c')).toBeCloseToArray([0.6, 0.1, 0.3]); - }); - - it('should fill in missing component (case \'b\')', function() { - trace.a = [0.1, 0.3, 0.6]; - trace.c = [0.1, 0.3, 0.2]; - - cd = calc(gd, trace); - expect(get(cd, 'b')).toBeCloseToArray([0.8, 0.4, 0.2]); - }); - - it('should fill in missing component (case \'a\')', function() { - trace.b = [0.1, 0.3, 0.6]; - trace.c = [0.8, 0.4, 0.1]; - - cd = calc(gd, trace); - expect(get(cd, 'a')).toBeCloseToArray([0.1, 0.3, 0.3]); - }); - - it('should skip over non-numeric values', function() { - trace.a = [0.1, 'a', 0.6]; - trace.b = [0.1, 0.3, null]; - trace.c = [8, 0.4, 0.1]; - - cd = calc(gd, trace).map(function(obj) { delete obj.i; return obj; }); - - expect(objectToArray(cd[0])).toBeCloseToArray([ - 0.963414634, 0.012195121, 0.012195121, 0.012195121, 0.975609756 - ]); - expect(cd[1]).toEqual({ x: false, y: false }); - expect(cd[2]).toEqual({ x: false, y: false }); - }); - - function objectToArray(obj) { - return Object.keys(obj).map(function(k) { - return obj[k]; - }); - } -}); - -describe('scatterternary plot and hover', function() { - 'use strict'; - - var mock = require('../../image/mocks/ternary_simple.json'); - - afterAll(destroyGraphDiv); - - beforeAll(function(done) { - var gd = createGraphDiv(); - var mockCopy = Lib.extendDeep({}, mock); - - Plotly.newPlot(gd, mockCopy.data, mockCopy.layout).then(done); - }); - - it('should put scatterternary trace in \'frontplot\' node', function() { - var nodes = d3Select('.frontplot').selectAll('.scatter'); - - expect(nodes.size()).toEqual(1); - }); - - it('should generate one line path per trace', function() { - var nodes = d3SelectAll('path.js-line'); - - expect(nodes.size()).toEqual(mock.data.length); - }); - - it('should generate as many points as there are data points', function() { - var nodes = d3SelectAll('path.point'); - - expect(nodes.size()).toEqual(mock.data[0].a.length); - }); -}); - -describe('scatterternary hover', function() { - 'use strict'; - - var gd; - - function check(pos, content) { - mouseEvent('mousemove', pos[0], pos[1]); - - assertHoverLabelContent({ - nums: content[0], - name: content[1] - }); - } - - beforeAll(function(done) { - gd = createGraphDiv(); - var data = [{ - type: 'scatterternary', - a: [0.1, 0.2, 0.3], - b: [0.3, 0.2, 0.1], - c: [0.1, 0.4, 0.5], - text: ['A', 'B', 'C'] - }]; - Plotly.newPlot(gd, data).then(done); - }); - - afterAll(destroyGraphDiv); - - function _hover(gd, xval, yval, hovermode) { - var cd = gd.calcdata; - var ternary = gd._fullLayout.ternary._subplot; - - var pointData = { - index: false, - distance: 20, - cd: cd[0], - trace: cd[0][0].trace, - xa: ternary.xaxis, - ya: ternary.yaxis, - subplot: ternary - }; - - return ScatterTernary.hoverPoints(pointData, xval, yval, hovermode); - } - - it('should generate extra text field on hover', function(done) { - var xval = 0.42; - var yval = 0.37; - var hovermode = 'closest'; - var scatterPointData; - - scatterPointData = _hover(gd, xval, yval, hovermode); - - expect(scatterPointData[0].extraText).toEqual( - 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' - ); - - expect(scatterPointData[0].xLabelVal).toBeUndefined(); - expect(scatterPointData[0].yLabelVal).toBeUndefined(); - expect(scatterPointData[0].text).toEqual('C'); - - Plotly.restyle(gd, { - text: null, - hovertext: [['apple', 'banana', 'orange']] - }) - .then(function() { - scatterPointData = _hover(gd, xval, yval, hovermode); - - expect(scatterPointData[0].extraText).toEqual( - 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' - ); - - expect(scatterPointData[0].xLabelVal).toBeUndefined(); - expect(scatterPointData[0].yLabelVal).toBeUndefined(); - expect(scatterPointData[0].text).toEqual('orange'); - }) - .then(done, done.fail); - }); - - it('should pass along hovertemplate on hover', function(done) { - var xval = 0.42; - var yval = 0.37; - var hovermode = 'closest'; - var scatterPointData; - Plotly.restyle(gd, { - hovertemplate: 'tpl' - }) - .then(function() { - scatterPointData = _hover(gd, xval, yval, hovermode); - expect(scatterPointData[0].hovertemplate).toEqual('tpl'); - expect(scatterPointData[0].aLabel).toBe('0.3333333'); - expect(scatterPointData[0].bLabel).toBe('0.1111111'); - expect(scatterPointData[0].cLabel).toBe('0.5555556'); - }) - .then(done, done.fail); - }); - - it('should always display hoverlabel when hovertemplate is defined', function(done) { - var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_simple.json')); - - Plotly.newPlot(gd, fig) - .then(function() { - return Plotly.restyle(gd, { - hovertemplate: '%{a}, %{b}, %{c}', - name: '', - text: null, - hovertext: null - }); - }) - .then(function() { - check([380, 210], ['0.5, 0.25, 0.25']); - }) - .then(done, done.fail); - }); -}); - -describe('Test scatterternary *cliponaxis*', function() { - afterEach(destroyGraphDiv); - - it('should show/hide point/text/errorbars in clipped and non-clipped layers', function(done) { - var gd = createGraphDiv(); - var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_markers.json')); - // use simple markers here - delete fig.data[0].marker; - - function _assert(layerClips, nodeDisplays, lineClips) { - var frontLayer = d3Select('.frontplot'); - var scatterLayer = d3Select('.scatterlayer'); - - assertClip(frontLayer, layerClips[0], 1, 'front layer'); - assertClip(scatterLayer, layerClips[1], 1, 'scatter layer'); - - assertNodeDisplay( - scatterLayer.selectAll('.point'), - nodeDisplays, - 'scatter points' - ); - assertNodeDisplay( - scatterLayer.selectAll('.textpoint'), - nodeDisplays, - 'scatter text points' - ); - - assertClip( - scatterLayer.selectAll('.js-line'), - lineClips[0], lineClips[1], - 'line clips' - ); - } - - Plotly.newPlot(gd, fig) - .then(function() { - _assert( - [false, false], - [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.restyle(gd, 'visible', 'legendonly'); - }) - .then(function() { - _assert( - [false, false], - [], - [false, 0] - ); - return Plotly.restyle(gd, {visible: true, cliponaxis: null}); - }) - .then(function() { - _assert( - [true, false], - [null, null, null, null, null, null, null, null, null, null, null], - [false, 1] - ); - return Plotly.restyle(gd, 'cliponaxis', false); - }) - .then(function() { - _assert( - [false, false], - [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, 'ternary.aaxis.min', 20); - }) - .then(function() { - _assert( - [false, false], - [null, 'none', null, 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, 'ternary.baxis.min', 40); - }) - .then(function() { - _assert( - [false, false], - ['none', 'none', 'none', 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, 'ternary.caxis.min', 30); - }) - .then(function() { - _assert( - [false, false], - ['none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none'], - [true, 1] - ); - return Plotly.relayout(gd, { - 'ternary.aaxis.min': null, - 'ternary.baxis.min': null, - 'ternary.caxis.min': null - }); - }) - .then(function() { - _assert( - [false, false], - [null, null, null, null, null, null, null, null, null, null, null], - [true, 1] - ); - }) - .then(done, done.fail); - }); -}); - -describe('Test scatterternary texttemplate:', function() { - checkTextTemplate([{ - type: 'scatterternary', - a: [3, 2, 5], - b: [2, 5, 2], - c: [5, 2, 2 ], - mode: 'markers+text', - text: ['A', 'B', 'C'] - }], 'g.textpoint', [ - ['%{text} (%{a:.1f}, %{b:.1f}, %{c:.1f})', ['A (3.0, 2.0, 5.0)', 'B (2.0, 5.0, 2.0)', 'C (5.0, 2.0, 2.0)']] - ]); - - checkTextTemplate({ - data: [{ - type: 'scatterternary', - mode: 'text', - a: [3, 2, 5], - b: [2, 5, 2], - c: [5, 2, 2] - }], - layout: { - ternary: { - aaxis: { tickprefix: '*', ticksuffix: '*' }, - baxis: { tickprefix: '$', ticksuffix: ' !', tickformat: '.2f'}, - caxis: { tickprefix: '#', ticksuffix: '^'} - } - } - }, '.textpoint', [ - ['%{a} is %{b} is %{c}', [ - '*0.3* is $0.20 ! is #0.5^', - '*0.2222222* is $0.56 ! is #0.2222222^', - '*0.5555556* is $0.22 ! is #0.2222222^' - ]] - ]); -}); +var Plotly = require('../../../lib/index'); +var Lib = require('../../../src/lib'); +var ScatterTernary = require('../../../src/traces/scatterternary'); + +var d3Select = require('../../strict-d3').select; +var d3SelectAll = require('../../strict-d3').selectAll; +var createGraphDiv = require('../assets/create_graph_div'); +var destroyGraphDiv = require('../assets/destroy_graph_div'); + +var customAssertions = require('../assets/custom_assertions'); +var supplyAllDefaults = require('../assets/supply_defaults'); + +var mouseEvent = require('../assets/mouse_event'); +var assertHoverLabelContent = customAssertions.assertHoverLabelContent; +var checkTextTemplate = require('../assets/check_texttemplate'); + +var assertClip = customAssertions.assertClip; +var assertNodeDisplay = customAssertions.assertNodeDisplay; + +describe('scatterternary defaults', function() { + 'use strict'; + + var supplyDefaults = ScatterTernary.supplyDefaults; + + var traceIn, traceOut; + + var defaultColor = '#444'; + var layout = {}; + + beforeEach(function() { + traceOut = {}; + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (base case)', function() { + traceIn = { + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'c\' is missing case)', function() { + traceIn = { + a: [1, 2, 3], + b: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'b\' is missing case)', function() { + traceIn = { + a: [1, 2, 3], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\' is missing case)', function() { + traceIn = { + b: [1, 2, 3], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(true); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'b\ and \'c\' are missing case)', function() { + traceIn = { + a: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\ and \'c\' are missing case)', function() { + traceIn = { + b: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (\'a\ and \'b\' are missing case)', function() { + traceIn = { + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should allow one of \'a\', \'b\' or \'c\' to be missing (all are missing case)', function() { + traceIn = {}; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + + it('should not truncate data arrays to the same length (\'c\' is shortest case)', function() { + // this is handled at the calc step now via _length. + traceIn = { + a: [1, 2, 3], + b: [1, 2], + c: [1] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.a).toEqual([1, 2, 3]); + expect(traceOut.b).toEqual([1, 2]); + expect(traceOut.c).toEqual([1]); + expect(traceOut._length).toBe(1); + }); + + it('should not truncate data arrays to the same length (\'a\' is shortest case)', function() { + // this is handled at the calc step now via _length. + traceIn = { + a: [1], + b: [1, 2, 3], + c: [1, 2] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.a).toEqual([1]); + expect(traceOut.b).toEqual([1, 2, 3]); + expect(traceOut.c).toEqual([1, 2]); + expect(traceOut._length).toBe(1); + }); + + it('should not truncate data arrays to the same length (\'a\' is shortest case)', function() { + // this is handled at the calc step now via _length. + traceIn = { + a: [1, 2], + b: [1], + c: [1, 2, 3] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.a).toEqual([1, 2]); + expect(traceOut.b).toEqual([1]); + expect(traceOut.c).toEqual([1, 2, 3]); + expect(traceOut._length).toBe(1); + }); + + it('is set visible: false if a, b, or c is empty', function() { + var trace0 = { + a: [1, 2], + b: [2, 1], + c: [2, 2] + }; + + ['a', 'b', 'c'].forEach(function(letter) { + traceIn = Lib.extendDeep({}, trace0); + traceIn[letter] = []; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false, letter); + }); + }); + + it('should include \'name\' in \'hoverinfo\' default if multi trace graph', function() { + traceIn = { + type: 'scatterternary', + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3] + }; + + var gd = {data: [traceIn, {}]}; + supplyAllDefaults(gd); + + expect(gd._fullData[0].hoverinfo).toBe('all'); + }); + + it('should not include \'name\' in \'hoverinfo\' default if single trace graph', function() { + traceIn = { + type: 'scatterternary', + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3] + }; + + var gd = {data: [traceIn]}; + supplyAllDefaults(gd); + + expect(gd._fullData[0].hoverinfo).toBe('a+b+c+text'); + }); + + it('should correctly assign \'hoveron\' default', function() { + traceIn = { + a: [1, 2, 3], + b: [1, 2, 3], + c: [1, 2, 3], + mode: 'lines+markers', + fill: 'tonext' + }; + + // fills and markers, you get both hover types + // you need visible: true here, as that normally gets set + // outside of the module supplyDefaults + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.hoveron).toBe('points+fills'); + + // but with only lines (or just fill) and fill tonext or toself + // you get fills + traceIn.mode = 'lines'; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.hoveron).toBe('fills'); + + // without a fill you always get points. For scatterternary, unlike + // scatter, every allowed fill but 'none' is an area fill (rather than + // a vertical / horizontal fill) so they all should default to + // hoveron points. + traceIn.fill = 'none'; + traceOut = {visible: true}; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.hoveron).toBe('points'); + }); + + it('should coerce \'fillpattern\' defaults with *replace* fillpattern.fillmode', function() { + traceIn = { + a: [3, 1, 1], + b: [1, 3, 1], + c: [1, 1, 3], + mode: 'lines', + fill: 'toself', + fillcolor: 'green', + fillpattern: {shape: '+'} + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern.shape).toBe('+'); + expect(traceOut.fillpattern.fillmode).toBe('replace'); + expect(traceOut.fillpattern.bgcolor).toBeUndefined('transparent background'); + expect(traceOut.fillpattern.fgcolor).toBe('green'); + expect(traceOut.fillpattern.fgopacity).toBe(1); + expect(traceOut.fillpattern.size).toBe(8); + expect(traceOut.fillpattern.solidity).toBe(0.3); + }); + + it('should coerce \'fillpattern\' defaults with *overlay* fillpattern.fillmode', function() { + traceIn = { + a: [3, 1, 1], + b: [1, 3, 1], + c: [1, 1, 3], + mode: 'lines', + fill: 'toself', + fillcolor: 'green', + fillpattern: { + fillmode: 'overlay', + shape: '+' + } + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern.shape).toBe('+'); + expect(traceOut.fillpattern.bgcolor).toBe('green'); + expect(traceOut.fillpattern.fgcolor).toBe('rgb(255, 255, 255)'); + expect(traceOut.fillpattern.fgopacity).toBe(0.5); + }); + + it('should support a custom \'fillpattern.path\'', function() { + traceIn = { + a: [1, 2, 3], + b: [3, 2, 1], + c: [2, 2, 2], + mode: 'lines', + fill: 'toself', + fillcolor: 'green', + fillpattern: { + path: 'M0,0L8,0L8,4L0,4Z', + size: 12, + bgcolor: 'blue', + fgcolor: 'red', + fgopacity: 0.6 + } + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern.path).toBe('M0,0L8,0L8,4L0,4Z'); + expect(traceOut.fillpattern.size).toBe(12); + expect(traceOut.fillpattern.bgcolor).toBe('blue'); + expect(traceOut.fillpattern.fgcolor).toBe('red'); + expect(traceOut.fillpattern.fgopacity).toBe(0.6); + expect(traceOut.fillpattern.solidity).toBeUndefined(); + }); + + it('should not coerce \'fillpattern\' when \'fill\' is *none*', function() { + traceIn = { + a: [1, 2, 3], + b: [3, 2, 1], + c: [2, 2, 2], + mode: 'lines', + fill: 'none', + fillpattern: {shape: '+'} + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + + expect(traceOut.fillpattern).toBeUndefined(); + }); +}); + +describe('scatterternary calc', function() { + 'use strict'; + + var calc = ScatterTernary.calc; + + var gd, trace, cd; + + beforeEach(function() { + gd = { + _fullLayout: { + ternary: { sum: 1 } + } + }; + + trace = { + subplot: 'ternary', + sum: 1, + _length: 3 + }; + }); + + function get(cd, component) { + return cd.map(function(v) { + return v[component]; + }); + } + + it('should fill in missing component (case \'c\')', function() { + trace.a = [0.1, 0.3, 0.6]; + trace.b = [0.3, 0.6, 0.1]; + + cd = calc(gd, trace); + expect(get(cd, 'c')).toBeCloseToArray([0.6, 0.1, 0.3]); + }); + + it('should fill in missing component (case \'b\')', function() { + trace.a = [0.1, 0.3, 0.6]; + trace.c = [0.1, 0.3, 0.2]; + + cd = calc(gd, trace); + expect(get(cd, 'b')).toBeCloseToArray([0.8, 0.4, 0.2]); + }); + + it('should fill in missing component (case \'a\')', function() { + trace.b = [0.1, 0.3, 0.6]; + trace.c = [0.8, 0.4, 0.1]; + + cd = calc(gd, trace); + expect(get(cd, 'a')).toBeCloseToArray([0.1, 0.3, 0.3]); + }); + + it('should skip over non-numeric values', function() { + trace.a = [0.1, 'a', 0.6]; + trace.b = [0.1, 0.3, null]; + trace.c = [8, 0.4, 0.1]; + + cd = calc(gd, trace).map(function(obj) { delete obj.i; return obj; }); + + expect(objectToArray(cd[0])).toBeCloseToArray([ + 0.963414634, 0.012195121, 0.012195121, 0.012195121, 0.975609756 + ]); + expect(cd[1]).toEqual({ x: false, y: false }); + expect(cd[2]).toEqual({ x: false, y: false }); + }); + + function objectToArray(obj) { + return Object.keys(obj).map(function(k) { + return obj[k]; + }); + } +}); + +describe('scatterternary plot and hover', function() { + 'use strict'; + + var mock = require('../../image/mocks/ternary_simple.json'); + + afterAll(destroyGraphDiv); + + beforeAll(function(done) { + var gd = createGraphDiv(); + var mockCopy = Lib.extendDeep({}, mock); + + Plotly.newPlot(gd, mockCopy.data, mockCopy.layout).then(done); + }); + + it('should put scatterternary trace in \'frontplot\' node', function() { + var nodes = d3Select('.frontplot').selectAll('.scatter'); + + expect(nodes.size()).toEqual(1); + }); + + it('should generate one line path per trace', function() { + var nodes = d3SelectAll('path.js-line'); + + expect(nodes.size()).toEqual(mock.data.length); + }); + + it('should generate as many points as there are data points', function() { + var nodes = d3SelectAll('path.point'); + + expect(nodes.size()).toEqual(mock.data[0].a.length); + }); +}); + +describe('scatterternary hover', function() { + 'use strict'; + + var gd; + + function check(pos, content) { + mouseEvent('mousemove', pos[0], pos[1]); + + assertHoverLabelContent({ + nums: content[0], + name: content[1] + }); + } + + beforeAll(function(done) { + gd = createGraphDiv(); + var data = [{ + type: 'scatterternary', + a: [0.1, 0.2, 0.3], + b: [0.3, 0.2, 0.1], + c: [0.1, 0.4, 0.5], + text: ['A', 'B', 'C'] + }]; + Plotly.newPlot(gd, data).then(done); + }); + + afterAll(destroyGraphDiv); + + function _hover(gd, xval, yval, hovermode) { + var cd = gd.calcdata; + var ternary = gd._fullLayout.ternary._subplot; + + var pointData = { + index: false, + distance: 20, + cd: cd[0], + trace: cd[0][0].trace, + xa: ternary.xaxis, + ya: ternary.yaxis, + subplot: ternary + }; + + return ScatterTernary.hoverPoints(pointData, xval, yval, hovermode); + } + + it('should generate extra text field on hover', function(done) { + var xval = 0.42; + var yval = 0.37; + var hovermode = 'closest'; + var scatterPointData; + + scatterPointData = _hover(gd, xval, yval, hovermode); + + expect(scatterPointData[0].extraText).toEqual( + 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' + ); + + expect(scatterPointData[0].xLabelVal).toBeUndefined(); + expect(scatterPointData[0].yLabelVal).toBeUndefined(); + expect(scatterPointData[0].text).toEqual('C'); + + Plotly.restyle(gd, { + text: null, + hovertext: [['apple', 'banana', 'orange']] + }) + .then(function() { + scatterPointData = _hover(gd, xval, yval, hovermode); + + expect(scatterPointData[0].extraText).toEqual( + 'Component A: 0.3333333
Component B: 0.1111111
Component C: 0.5555556' + ); + + expect(scatterPointData[0].xLabelVal).toBeUndefined(); + expect(scatterPointData[0].yLabelVal).toBeUndefined(); + expect(scatterPointData[0].text).toEqual('orange'); + }) + .then(done, done.fail); + }); + + it('should pass along hovertemplate on hover', function(done) { + var xval = 0.42; + var yval = 0.37; + var hovermode = 'closest'; + var scatterPointData; + Plotly.restyle(gd, { + hovertemplate: 'tpl' + }) + .then(function() { + scatterPointData = _hover(gd, xval, yval, hovermode); + expect(scatterPointData[0].hovertemplate).toEqual('tpl'); + expect(scatterPointData[0].aLabel).toBe('0.3333333'); + expect(scatterPointData[0].bLabel).toBe('0.1111111'); + expect(scatterPointData[0].cLabel).toBe('0.5555556'); + }) + .then(done, done.fail); + }); + + it('should always display hoverlabel when hovertemplate is defined', function(done) { + var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_simple.json')); + + Plotly.newPlot(gd, fig) + .then(function() { + return Plotly.restyle(gd, { + hovertemplate: '%{a}, %{b}, %{c}', + name: '', + text: null, + hovertext: null + }); + }) + .then(function() { + check([380, 210], ['0.5, 0.25, 0.25']); + }) + .then(done, done.fail); + }); +}); + +describe('Test scatterternary *cliponaxis*', function() { + afterEach(destroyGraphDiv); + + it('should show/hide point/text/errorbars in clipped and non-clipped layers', function(done) { + var gd = createGraphDiv(); + var fig = Lib.extendDeep({}, require('../../image/mocks/ternary_markers.json')); + // use simple markers here + delete fig.data[0].marker; + + function _assert(layerClips, nodeDisplays, lineClips) { + var frontLayer = d3Select('.frontplot'); + var scatterLayer = d3Select('.scatterlayer'); + + assertClip(frontLayer, layerClips[0], 1, 'front layer'); + assertClip(scatterLayer, layerClips[1], 1, 'scatter layer'); + + assertNodeDisplay( + scatterLayer.selectAll('.point'), + nodeDisplays, + 'scatter points' + ); + assertNodeDisplay( + scatterLayer.selectAll('.textpoint'), + nodeDisplays, + 'scatter text points' + ); + + assertClip( + scatterLayer.selectAll('.js-line'), + lineClips[0], lineClips[1], + 'line clips' + ); + } + + Plotly.newPlot(gd, fig) + .then(function() { + _assert( + [false, false], + [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.restyle(gd, 'visible', 'legendonly'); + }) + .then(function() { + _assert( + [false, false], + [], + [false, 0] + ); + return Plotly.restyle(gd, {visible: true, cliponaxis: null}); + }) + .then(function() { + _assert( + [true, false], + [null, null, null, null, null, null, null, null, null, null, null], + [false, 1] + ); + return Plotly.restyle(gd, 'cliponaxis', false); + }) + .then(function() { + _assert( + [false, false], + [null, 'none', null, null, null, null, null, null, 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, 'ternary.aaxis.min', 20); + }) + .then(function() { + _assert( + [false, false], + [null, 'none', null, 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, 'ternary.baxis.min', 40); + }) + .then(function() { + _assert( + [false, false], + ['none', 'none', 'none', 'none', 'none', 'none', null, 'none', 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, 'ternary.caxis.min', 30); + }) + .then(function() { + _assert( + [false, false], + ['none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none'], + [true, 1] + ); + return Plotly.relayout(gd, { + 'ternary.aaxis.min': null, + 'ternary.baxis.min': null, + 'ternary.caxis.min': null + }); + }) + .then(function() { + _assert( + [false, false], + [null, null, null, null, null, null, null, null, null, null, null], + [true, 1] + ); + }) + .then(done, done.fail); + }); +}); + +describe('Test scatterternary texttemplate:', function() { + checkTextTemplate([{ + type: 'scatterternary', + a: [3, 2, 5], + b: [2, 5, 2], + c: [5, 2, 2 ], + mode: 'markers+text', + text: ['A', 'B', 'C'] + }], 'g.textpoint', [ + ['%{text} (%{a:.1f}, %{b:.1f}, %{c:.1f})', ['A (3.0, 2.0, 5.0)', 'B (2.0, 5.0, 2.0)', 'C (5.0, 2.0, 2.0)']] + ]); + + checkTextTemplate({ + data: [{ + type: 'scatterternary', + mode: 'text', + a: [3, 2, 5], + b: [2, 5, 2], + c: [5, 2, 2] + }], + layout: { + ternary: { + aaxis: { tickprefix: '*', ticksuffix: '*' }, + baxis: { tickprefix: '$', ticksuffix: ' !', tickformat: '.2f'}, + caxis: { tickprefix: '#', ticksuffix: '^'} + } + } + }, '.textpoint', [ + ['%{a} is %{b} is %{c}', [ + '*0.3* is $0.20 ! is #0.5^', + '*0.2222222* is $0.56 ! is #0.2222222^', + '*0.5555556* is $0.22 ! is #0.2222222^' + ]] + ]); +});