From 06ece4b4b8360ccddd80be87ad7828f6a4700513 Mon Sep 17 00:00:00 2001 From: Emily KL <4672118+emilykl@users.noreply.github.com> Date: Wed, 12 Nov 2025 01:36:56 -0500 Subject: [PATCH 01/10] run formatter --- src/traces/candlestick/attributes.js | 2 +- src/traces/candlestick/defaults.js | 4 +- src/traces/ohlc/attributes.js | 20 +- src/traces/ohlc/defaults.js | 4 +- test/jasmine/tests/finance_test.js | 1296 ++++++++++++++------------ 5 files changed, 697 insertions(+), 629 deletions(-) diff --git a/src/traces/candlestick/attributes.js b/src/traces/candlestick/attributes.js index 4cfde82c30c..fe6a49970c1 100644 --- a/src/traces/candlestick/attributes.js +++ b/src/traces/candlestick/attributes.js @@ -8,7 +8,7 @@ var boxAttrs = require('../box/attributes'); function directionAttrs(lineColorDefault) { return { line: { - color: extendFlat({}, boxAttrs.line.color, {dflt: lineColorDefault}), + color: extendFlat({}, boxAttrs.line.color, { dflt: lineColorDefault }), width: boxAttrs.line.width, editType: 'style' }, diff --git a/src/traces/candlestick/defaults.js b/src/traces/candlestick/defaults.js index e8e44b4ed5b..107991c9d21 100644 --- a/src/traces/candlestick/defaults.js +++ b/src/traces/candlestick/defaults.js @@ -12,12 +12,12 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } var len = handleOHLC(traceIn, traceOut, coerce, layout); - if(!len) { + if (!len) { traceOut.visible = false; return; } - handlePeriodDefaults(traceIn, traceOut, layout, coerce, {x: true}); + handlePeriodDefaults(traceIn, traceOut, layout, coerce, { x: true }); coerce('xhoverformat'); coerce('yhoverformat'); diff --git a/src/traces/ohlc/attributes.js b/src/traces/ohlc/attributes.js index e5305791d4f..72e5df8c8a6 100644 --- a/src/traces/ohlc/attributes.js +++ b/src/traces/ohlc/attributes.js @@ -15,7 +15,7 @@ var lineAttrs = scatterAttrs.line; function directionAttrs(lineColorDefault) { return { line: { - color: extendFlat({}, lineAttrs.color, {dflt: lineColorDefault}), + color: extendFlat({}, lineAttrs.color, { dflt: lineColorDefault }), width: lineAttrs.width, dash: dash, editType: 'style' @@ -25,7 +25,6 @@ function directionAttrs(lineColorDefault) { } module.exports = { - xperiod: scatterAttrs.xperiod, xperiod0: scatterAttrs.xperiod0, xperiodalignment: scatterAttrs.xperiodalignment, @@ -35,10 +34,7 @@ module.exports = { x: { valType: 'data_array', editType: 'calc+clearAxisTypes', - description: [ - 'Sets the x coordinates.', - 'If absent, linear coordinate will be generated.' - ].join(' ') + description: ['Sets the x coordinates.', 'If absent, linear coordinate will be generated.'].join(' ') }, open: { @@ -99,7 +95,7 @@ module.exports = { 'If a single string, the same string appears over', 'all the data points.', 'If an array of string, the items are mapped in order to', - 'this trace\'s sample points.' + "this trace's sample points." ].join(' ') }, hovertext: { @@ -116,10 +112,7 @@ module.exports = { max: 0.5, dflt: 0.3, editType: 'calc', - description: [ - 'Sets the width of the open/close tick marks', - 'relative to the *x* minimal interval.' - ].join(' ') + description: ['Sets the width of the open/close tick marks', 'relative to the *x* minimal interval.'].join(' ') }, hoverlabel: extendFlat({}, fxAttrs.hoverlabel, { @@ -127,10 +120,7 @@ module.exports = { valType: 'boolean', dflt: false, editType: 'style', - description: [ - 'Show hover information (open, close, high, low) in', - 'separate labels.' - ].join(' ') + description: ['Show hover information (open, close, high, low) in', 'separate labels.'].join(' ') } }), diff --git a/src/traces/ohlc/defaults.js b/src/traces/ohlc/defaults.js index 2557ecea8ee..26c27dde6d6 100644 --- a/src/traces/ohlc/defaults.js +++ b/src/traces/ohlc/defaults.js @@ -11,12 +11,12 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } var len = handleOHLC(traceIn, traceOut, coerce, layout); - if(!len) { + if (!len) { traceOut.visible = false; return; } - handlePeriodDefaults(traceIn, traceOut, layout, coerce, {x: true}); + handlePeriodDefaults(traceIn, traceOut, layout, coerce, { x: true }); coerce('xhoverformat'); coerce('yhoverformat'); diff --git a/test/jasmine/tests/finance_test.js b/test/jasmine/tests/finance_test.js index bf0bc8ef3fd..5f5723924c4 100644 --- a/test/jasmine/tests/finance_test.js +++ b/test/jasmine/tests/finance_test.js @@ -10,22 +10,18 @@ var supplyAllDefaults = require('../assets/supply_defaults'); var hover = require('../assets/hover'); var assertHoverLabelContent = require('../assets/custom_assertions').assertHoverLabelContent; - var mock0 = { - open: [33.01, 33.31, 33.50, 32.06, 34.12, 33.05, 33.31, 33.50], - high: [34.20, 34.37, 33.62, 34.25, 35.18, 33.25, 35.37, 34.62], - low: [31.70, 30.75, 32.87, 31.62, 30.81, 32.75, 32.75, 32.87], - close: [34.10, 31.93, 33.37, 33.18, 31.18, 33.10, 32.93, 33.70] + open: [33.01, 33.31, 33.5, 32.06, 34.12, 33.05, 33.31, 33.5], + high: [34.2, 34.37, 33.62, 34.25, 35.18, 33.25, 35.37, 34.62], + low: [31.7, 30.75, 32.87, 31.62, 30.81, 32.75, 32.75, 32.87], + close: [34.1, 31.93, 33.37, 33.18, 31.18, 33.1, 32.93, 33.7] }; var mock1 = Lib.extendDeep({}, mock0, { - x: [ - '2016-09-01', '2016-09-02', '2016-09-03', '2016-09-04', - '2016-09-05', '2016-09-06', '2016-09-07', '2016-09-10' - ] + x: ['2016-09-01', '2016-09-02', '2016-09-03', '2016-09-04', '2016-09-05', '2016-09-06', '2016-09-07', '2016-09-10'] }); -describe('finance charts defaults:', function() { +describe('finance charts defaults:', function () { 'use strict'; function _supply(data, layout) { @@ -39,7 +35,7 @@ describe('finance charts defaults:', function() { return gd; } - it('should generated the correct number of full traces', function() { + it('should generated the correct number of full traces', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); @@ -55,7 +51,7 @@ describe('finance charts defaults:', function() { expect(out._fullData.length).toEqual(2); }); - it('should not slice data arrays but record minimum supplied length', function() { + it('should not slice data arrays but record minimum supplied length', function () { function assertDataLength(trace, fullTrace, len) { expect(fullTrace.visible).toBe(true); @@ -68,7 +64,7 @@ describe('finance charts defaults:', function() { } var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); - trace0.open = [33.01, 33.31, 33.50, 32.06, 34.12]; + trace0.open = [33.01, 33.31, 33.5, 32.06, 34.12]; var trace1 = Lib.extendDeep({}, mock1, { type: 'candlestick' }); trace1.x = ['2016-09-01', '2016-09-02', '2016-09-03', '2016-09-04']; @@ -82,7 +78,7 @@ describe('finance charts defaults:', function() { expect(out._fullData[1]._fullInput.x).toBeDefined(); }); - it('should set visible to *false* when a component (other than x) is missing', function() { + it('should set visible to *false* when a component (other than x) is missing', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); trace0.close = undefined; @@ -94,17 +90,17 @@ describe('finance charts defaults:', function() { expect(out.data.length).toEqual(2); expect(out._fullData.length).toEqual(2); - var visibilities = out._fullData.map(function(fullTrace) { + var visibilities = out._fullData.map(function (fullTrace) { return fullTrace.visible; }); expect(visibilities).toEqual([false, false]); }); - it('should return visible: false if any data component is empty', function() { - ['ohlc', 'candlestick'].forEach(function(type) { - ['open', 'high', 'low', 'close', 'x'].forEach(function(attr) { - var trace = Lib.extendDeep({}, mock1, {type: type}); + it('should return visible: false if any data component is empty', function () { + ['ohlc', 'candlestick'].forEach(function (type) { + ['open', 'high', 'low', 'close', 'x'].forEach(function (attr) { + var trace = Lib.extendDeep({}, mock1, { type: type }); trace[attr] = []; var out = _supply([trace]); expect(out._fullData[0].visible).toBe(false, type + ' - ' + attr); @@ -112,10 +108,10 @@ describe('finance charts defaults:', function() { }); }); - it('direction *showlegend* should be inherited from trace-wide *showlegend*', function() { + it('direction *showlegend* should be inherited from trace-wide *showlegend*', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc', - showlegend: false, + showlegend: false }); var trace1 = Lib.extendDeep({}, mock1, { @@ -127,14 +123,14 @@ describe('finance charts defaults:', function() { var out = _supply([trace0, trace1]); - var visibilities = out._fullData.map(function(fullTrace) { + var visibilities = out._fullData.map(function (fullTrace) { return fullTrace.showlegend; }); expect(visibilities).toEqual([false, false]); }); - it('direction *name* should be ignored if there\'s a trace-wide *name*', function() { + it("direction *name* should be ignored if there's a trace-wide *name*", function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc', name: 'Company A' @@ -149,17 +145,14 @@ describe('finance charts defaults:', function() { var out = _supply([trace0, trace1]); - var names = out._fullData.map(function(fullTrace) { + var names = out._fullData.map(function (fullTrace) { return fullTrace.name; }); - expect(names).toEqual([ - 'Company A', - 'Company B' - ]); + expect(names).toEqual(['Company A', 'Company B']); }); - it('trace *name* default should make reference to user data trace indices', function() { + it('trace *name* default should make reference to user data trace indices', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); @@ -167,29 +160,24 @@ describe('finance charts defaults:', function() { var trace1 = { type: 'scatter' }; var trace2 = Lib.extendDeep({}, mock1, { - type: 'candlestick', + type: 'candlestick' }); var trace3 = { type: 'bar' }; var out = _supply([trace0, trace1, trace2, trace3]); - var names = out._fullData.map(function(fullTrace) { + var names = out._fullData.map(function (fullTrace) { return fullTrace.name; }); - expect(names).toEqual([ - 'trace 0', - 'trace 1', - 'trace 2', - 'trace 3' - ]); + expect(names).toEqual(['trace 0', 'trace 1', 'trace 2', 'trace 3']); }); - it('trace-wide styling should set default for corresponding per-direction styling', function() { + it('trace-wide styling should set default for corresponding per-direction styling', function () { function assertLine(cont, width, dash) { expect(cont.line.width).toEqual(width); - if(dash) expect(cont.line.dash).toEqual(dash); + if (dash) expect(cont.line.dash).toEqual(dash); } var trace0 = Lib.extendDeep({}, mock0, { @@ -213,7 +201,7 @@ describe('finance charts defaults:', function() { assertLine(fullData[1].decreasing, 3); }); - it('trace-wide *visible* should work', function() { + it('trace-wide *visible* should work', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc', visible: 'legendonly' @@ -226,7 +214,7 @@ describe('finance charts defaults:', function() { var out = _supply([trace0, trace1]); - var visibilities = out._fullData.map(function(fullTrace) { + var visibilities = out._fullData.map(function (fullTrace) { return fullTrace.visible; }); @@ -235,7 +223,7 @@ describe('finance charts defaults:', function() { expect(visibilities).toEqual(['legendonly', false]); }); - it('should add a few layout settings by default', function() { + it('should add a few layout settings by default', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); @@ -252,7 +240,7 @@ describe('finance charts defaults:', function() { }); var layout1 = { - xaxis: { rangeslider: { visible: false }} + xaxis: { rangeslider: { visible: false } } }; var out1 = _supply([trace1], layout1); @@ -261,7 +249,7 @@ describe('finance charts defaults:', function() { expect(out1._fullLayout.xaxis.rangeslider.visible).toBe(false); }); - it('pushes layout.calendar to all output traces', function() { + it('pushes layout.calendar to all output traces', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); @@ -270,15 +258,14 @@ describe('finance charts defaults:', function() { type: 'candlestick' }); - var out = _supply([trace0, trace1], {calendar: 'nanakshahi'}); + var out = _supply([trace0, trace1], { calendar: 'nanakshahi' }); - - out._fullData.forEach(function(fullTrace) { + out._fullData.forEach(function (fullTrace) { expect(fullTrace.xcalendar).toBe('nanakshahi'); }); }); - it('accepts a calendar per input trace', function() { + it('accepts a calendar per input trace', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc', xcalendar: 'hebrew' @@ -289,15 +276,14 @@ describe('finance charts defaults:', function() { xcalendar: 'julian' }); - var out = _supply([trace0, trace1], {calendar: 'nanakshahi'}); - + var out = _supply([trace0, trace1], { calendar: 'nanakshahi' }); - out._fullData.forEach(function(fullTrace, i) { + out._fullData.forEach(function (fullTrace, i) { expect(fullTrace.xcalendar).toBe(i < 1 ? 'hebrew' : 'julian'); }); }); - it('should make empty candlestick traces autotype to *linear* (as opposed to real box traces)', function() { + it('should make empty candlestick traces autotype to *linear* (as opposed to real box traces)', function () { var trace0 = { type: 'candlestick' }; var out = _supply([trace0], { xaxis: {} }); @@ -305,7 +291,7 @@ describe('finance charts defaults:', function() { }); }); -describe('finance charts calc', function() { +describe('finance charts calc', function () { 'use strict'; function calcDatatoTrace(calcTrace) { @@ -320,9 +306,9 @@ describe('finance charts calc', function() { supplyAllDefaults(gd); Plots.doCalcdata(gd); - gd.calcdata.forEach(function(cd) { + gd.calcdata.forEach(function (cd) { // fill in some stuff that happens during crossTraceCalc or plot - if(cd[0].trace.type === 'candlestick') { + if (cd[0].trace.type === 'candlestick') { var diff = cd[1].pos - cd[0].pos; cd[0].t.wHover = diff / 2; cd[0].t.bdPos = diff / 4; @@ -343,7 +329,7 @@ describe('finance charts calc', function() { // one of o, h, l, c is not numeric function addJunk(trace) { // x filtering happens in other ways - if(trace.x) trace.x.push(1, 1, 1, 1); + if (trace.x) trace.x.push(1, 1, 1, 1); trace.open.push('', 1, 1, 1); trace.high.push(1, null, 1, 1); @@ -352,17 +338,19 @@ describe('finance charts calc', function() { } function mapGet(array, attr) { - return array.map(function(di) { return di[attr]; }); + return array.map(function (di) { + return di[attr]; + }); } - it('should fill when *x* is not present', function() { + it('should fill when *x* is not present', function () { var trace0 = Lib.extendDeep({}, mock0, { - type: 'ohlc', + type: 'ohlc' }); addJunk(trace0); var trace1 = Lib.extendDeep({}, mock0, { - type: 'candlestick', + type: 'candlestick' }); addJunk(trace1); @@ -372,9 +360,18 @@ describe('finance charts calc', function() { var d = 'decreasing'; var directions = [i, d, d, i, d, i, d, i, undefined, undefined, undefined, undefined]; var empties = [ - undefined, undefined, undefined, undefined, - undefined, undefined, undefined, undefined, - true, true, true, true + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + true, + true, + true, + true ]; expect(mapGet(out[0], 'pos')).toEqual(indices); @@ -385,7 +382,7 @@ describe('finance charts calc', function() { expect(mapGet(out[1], 'empty')).toEqual(empties); }); - it('should use the smallest trace minimum x difference to convert *tickwidth* to data coords for all traces attached to a given x-axis', function() { + it('should use the smallest trace minimum x difference to convert *tickwidth* to data coords for all traces attached to a given x-axis', function () { var trace0 = Lib.extendDeep({}, mock1, { type: 'ohlc' }); @@ -393,7 +390,9 @@ describe('finance charts calc', function() { var trace1 = Lib.extendDeep({}, mock1, { type: 'ohlc', // shift time coordinates by 10 hours - x: mock1.x.map(function(d) { return d + ' 10:00'; }) + x: mock1.x.map(function (d) { + return d + ' 10:00'; + }) }); var out = _calcRaw([trace0, trace1]); @@ -405,7 +404,7 @@ describe('finance charts calc', function() { expect(out[1][0].t.wHover).toBe(out[0][0].t.wHover); }); - it('works with category x data', function() { + it('works with category x data', function () { // see https://github.com/plotly/plotly.js/issues/2004 // fixed automatically as part of the refactor to a non-transform trace var trace0 = Lib.extendDeep({}, mock0, { @@ -419,7 +418,7 @@ describe('finance charts calc', function() { expect(out[0][0].t.wHover).toBeCloseTo(0.5, 5); }); - it('should fallback to a spacing of 1 in one-item traces', function() { + it('should fallback to a spacing of 1 in one-item traces', function () { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc', x: ['2016-01-01'] @@ -438,36 +437,43 @@ describe('finance charts calc', function() { expect(out[1][0].t.wHover).toBeCloseTo(0.5, 5); }); - it('should handle cases where \'open\' and \'close\' entries are equal', function() { - var out = _calcRaw([{ - type: 'ohlc', - open: [0, 1, 0, 2, 1, 1, 2, 2], - high: [3, 3, 3, 3, 3, 3, 3, 3], - low: [-1, -1, -1, -1, -1, -1, -1, -1], - close: [0, 2, 0, 1, 1, 1, 2, 2], - tickwidth: 0 - }, { - type: 'candlestick', - open: [0, 2, 0, 1], - high: [3, 3, 3, 3], - low: [-1, -1, -1, -1], - close: [0, 1, 0, 2] - }]); + it("should handle cases where 'open' and 'close' entries are equal", function () { + var out = _calcRaw([ + { + type: 'ohlc', + open: [0, 1, 0, 2, 1, 1, 2, 2], + high: [3, 3, 3, 3, 3, 3, 3, 3], + low: [-1, -1, -1, -1, -1, -1, -1, -1], + close: [0, 2, 0, 1, 1, 1, 2, 2], + tickwidth: 0 + }, + { + type: 'candlestick', + open: [0, 2, 0, 1], + high: [3, 3, 3, 3], + low: [-1, -1, -1, -1], + close: [0, 1, 0, 2] + } + ]); expect(mapGet(out[0], 'dir')).toEqual([ - 'increasing', 'increasing', 'decreasing', 'decreasing', - 'decreasing', 'decreasing', 'increasing', 'increasing' + 'increasing', + 'increasing', + 'decreasing', + 'decreasing', + 'decreasing', + 'decreasing', + 'increasing', + 'increasing' ]); - expect(mapGet(out[1], 'dir')).toEqual([ - 'increasing', 'decreasing', 'decreasing', 'increasing' - ]); + expect(mapGet(out[1], 'dir')).toEqual(['increasing', 'decreasing', 'decreasing', 'increasing']); }); - it('should include finance hover labels prefix in calcdata', function() { - ['candlestick', 'ohlc'].forEach(function(type) { + it('should include finance hover labels prefix in calcdata', function () { + ['candlestick', 'ohlc'].forEach(function (type) { var trace0 = Lib.extendDeep({}, mock0, { - type: type, + type: type }); var out = _calcRaw([trace0]); @@ -481,14 +487,16 @@ describe('finance charts calc', function() { }); }); -describe('finance charts auto-range', function() { +describe('finance charts auto-range', function () { var gd; - beforeEach(function() { gd = createGraphDiv(); }); + beforeEach(function () { + gd = createGraphDiv(); + }); afterEach(destroyGraphDiv); - describe('should give correct results with trailing nulls', function() { + describe('should give correct results with trailing nulls', function () { var base = { x: ['time1', 'time2', 'time3'], high: [10, 11, null], @@ -497,36 +505,38 @@ describe('finance charts auto-range', function() { open: [4, 4, null] }; - it('- ohlc case', function(done) { - var trace = Lib.extendDeep({}, base, {type: 'ohlc'}); + it('- ohlc case', function (done) { + var trace = Lib.extendDeep({}, base, { type: 'ohlc' }); - Plotly.newPlot(gd, [trace]).then(function() { - expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.5, 2.5], 1); - }) - .then(done, done.fail); + Plotly.newPlot(gd, [trace]) + .then(function () { + expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.5, 2.5], 1); + }) + .then(done, done.fail); }); - it('- candlestick case', function(done) { - var trace = Lib.extendDeep({}, base, {type: 'candlestick'}); + it('- candlestick case', function (done) { + var trace = Lib.extendDeep({}, base, { type: 'candlestick' }); - Plotly.newPlot(gd, [trace]).then(function() { - expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.5, 2.5], 1); - }) - .then(done, done.fail); + Plotly.newPlot(gd, [trace]) + .then(function () { + expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.5, 2.5], 1); + }) + .then(done, done.fail); }); }); }); -describe('finance charts updates:', function() { +describe('finance charts updates:', function () { 'use strict'; var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); - afterEach(function() { + afterEach(function () { Plotly.purge(gd); destroyGraphDiv(); }); @@ -543,186 +553,190 @@ describe('finance charts updates:', function() { return d3Select('g.rangeslider-rangeplot').size(); } - it('Plotly.restyle should work', function(done) { + it('Plotly.restyle should work', function (done) { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); var path0; - Plotly.newPlot(gd, [trace0]).then(function() { - expect(gd.calcdata[0][0].t.tickLen).toBeCloseTo(0.3, 5); - expect(gd.calcdata[0][0].o).toEqual(33.01); + Plotly.newPlot(gd, [trace0]) + .then(function () { + expect(gd.calcdata[0][0].t.tickLen).toBeCloseTo(0.3, 5); + expect(gd.calcdata[0][0].o).toEqual(33.01); - return Plotly.restyle(gd, 'tickwidth', 0.5); - }) - .then(function() { - expect(gd.calcdata[0][0].t.tickLen).toBeCloseTo(0.5, 5); + return Plotly.restyle(gd, 'tickwidth', 0.5); + }) + .then(function () { + expect(gd.calcdata[0][0].t.tickLen).toBeCloseTo(0.5, 5); - return Plotly.restyle(gd, 'open', [[0, 30.75, 32.87, 31.62, 30.81, 32.75, 32.75, 32.87]]); - }) - .then(function() { - expect(gd.calcdata[0][0].o).toEqual(0); + return Plotly.restyle(gd, 'open', [[0, 30.75, 32.87, 31.62, 30.81, 32.75, 32.75, 32.87]]); + }) + .then(function () { + expect(gd.calcdata[0][0].o).toEqual(0); - return Plotly.restyle(gd, { - type: 'candlestick', - open: [[33.01, 33.31, 33.50, 32.06, 34.12, 33.05, 33.31, 33.50]] - }); - }) - .then(function() { - path0 = d3Select('path.box').attr('d'); - expect(path0).toBeDefined(); + return Plotly.restyle(gd, { + type: 'candlestick', + open: [[33.01, 33.31, 33.5, 32.06, 34.12, 33.05, 33.31, 33.5]] + }); + }) + .then(function () { + path0 = d3Select('path.box').attr('d'); + expect(path0).toBeDefined(); - return Plotly.restyle(gd, 'whiskerwidth', 0.2); - }) - .then(function() { - expect(d3Select('path.box').attr('d')).not.toEqual(path0); - }) - .then(done, done.fail); + return Plotly.restyle(gd, 'whiskerwidth', 0.2); + }) + .then(function () { + expect(d3Select('path.box').attr('d')).not.toEqual(path0); + }) + .then(done, done.fail); }); - it('should be able to toggle visibility', function(done) { - var data = [ - Lib.extendDeep({}, mock0, { type: 'ohlc' }), - Lib.extendDeep({}, mock0, { type: 'candlestick' }), - ]; + it('should be able to toggle visibility', function (done) { + var data = [Lib.extendDeep({}, mock0, { type: 'ohlc' }), Lib.extendDeep({}, mock0, { type: 'candlestick' })]; - Plotly.newPlot(gd, data).then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(1); + Plotly.newPlot(gd, data) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(1); - return Plotly.restyle(gd, 'visible', false); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(0); + return Plotly.restyle(gd, 'visible', false); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(0); - return Plotly.restyle(gd, 'visible', 'legendonly', [1]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(0); + return Plotly.restyle(gd, 'visible', 'legendonly', [1]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(0); - return Plotly.restyle(gd, 'visible', true, [1]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(1); + return Plotly.restyle(gd, 'visible', true, [1]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(1); - return Plotly.restyle(gd, 'visible', true, [0]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(1); + return Plotly.restyle(gd, 'visible', true, [0]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(1); - return Plotly.restyle(gd, 'visible', 'legendonly', [0]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(1); + return Plotly.restyle(gd, 'visible', 'legendonly', [0]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(1); - return Plotly.restyle(gd, 'visible', true); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(1); - }) - .then(done, done.fail); + return Plotly.restyle(gd, 'visible', true); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(1); + }) + .then(done, done.fail); }); - it('Plotly.relayout should work', function(done) { + it('Plotly.relayout should work', function (done) { var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); - Plotly.newPlot(gd, [trace0]).then(function() { - expect(countRangeSliders()).toEqual(1); + Plotly.newPlot(gd, [trace0]) + .then(function () { + expect(countRangeSliders()).toEqual(1); - return Plotly.relayout(gd, 'xaxis.rangeslider.visible', false); - }) - .then(function() { - expect(countRangeSliders()).toEqual(0); - }) - .then(done, done.fail); + return Plotly.relayout(gd, 'xaxis.rangeslider.visible', false); + }) + .then(function () { + expect(countRangeSliders()).toEqual(0); + }) + .then(done, done.fail); }); - it('Plotly.extendTraces should work', function(done) { - var data = [ - Lib.extendDeep({}, mock0, { type: 'ohlc' }), - Lib.extendDeep({}, mock0, { type: 'candlestick' }), - ]; - - Plotly.newPlot(gd, data).then(function() { - expect(gd.calcdata[0].length).toEqual(8); - expect(gd.calcdata[1].length).toEqual(8); - - return Plotly.extendTraces(gd, { - open: [[ 34, 35 ]], - high: [[ 40, 41 ]], - low: [[ 32, 33 ]], - close: [[ 38, 39 ]] - }, [1]); - }) - .then(function() { - expect(gd.calcdata[0].length).toEqual(8); - expect(gd.calcdata[1].length).toEqual(10); - - return Plotly.extendTraces(gd, { - open: [[ 34, 35 ]], - high: [[ 40, 41 ]], - low: [[ 32, 33 ]], - close: [[ 38, 39 ]] - }, [0]); - }) - .then(function() { - expect(gd.calcdata[0].length).toEqual(10); - expect(gd.calcdata[1].length).toEqual(10); - }) - .then(done, done.fail); + it('Plotly.extendTraces should work', function (done) { + var data = [Lib.extendDeep({}, mock0, { type: 'ohlc' }), Lib.extendDeep({}, mock0, { type: 'candlestick' })]; + + Plotly.newPlot(gd, data) + .then(function () { + expect(gd.calcdata[0].length).toEqual(8); + expect(gd.calcdata[1].length).toEqual(8); + + return Plotly.extendTraces( + gd, + { + open: [[34, 35]], + high: [[40, 41]], + low: [[32, 33]], + close: [[38, 39]] + }, + [1] + ); + }) + .then(function () { + expect(gd.calcdata[0].length).toEqual(8); + expect(gd.calcdata[1].length).toEqual(10); + + return Plotly.extendTraces( + gd, + { + open: [[34, 35]], + high: [[40, 41]], + low: [[32, 33]], + close: [[38, 39]] + }, + [0] + ); + }) + .then(function () { + expect(gd.calcdata[0].length).toEqual(10); + expect(gd.calcdata[1].length).toEqual(10); + }) + .then(done, done.fail); }); - it('Plotly.deleteTraces / addTraces should work', function(done) { - var data = [ - Lib.extendDeep({}, mock0, { type: 'ohlc' }), - Lib.extendDeep({}, mock0, { type: 'candlestick' }), - ]; + it('Plotly.deleteTraces / addTraces should work', function (done) { + var data = [Lib.extendDeep({}, mock0, { type: 'ohlc' }), Lib.extendDeep({}, mock0, { type: 'candlestick' })]; - Plotly.newPlot(gd, data).then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(1); + Plotly.newPlot(gd, data) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(1); - return Plotly.deleteTraces(gd, [1]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(0); + return Plotly.deleteTraces(gd, [1]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(0); - return Plotly.deleteTraces(gd, [0]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(0); + return Plotly.deleteTraces(gd, [0]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(0); - var trace = Lib.extendDeep({}, mock0, { type: 'candlestick' }); + var trace = Lib.extendDeep({}, mock0, { type: 'candlestick' }); - return Plotly.addTraces(gd, [trace]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(1); + return Plotly.addTraces(gd, [trace]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(1); - var trace = Lib.extendDeep({}, mock0, { type: 'ohlc' }); + var trace = Lib.extendDeep({}, mock0, { type: 'ohlc' }); - return Plotly.addTraces(gd, [trace]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(1); - }) - .then(done, done.fail); + return Plotly.addTraces(gd, [trace]); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(1); + }) + .then(done, done.fail); }); - it('Plotly.addTraces + Plotly.relayout should update candlestick box position values', function(done) { + it('Plotly.addTraces + Plotly.relayout should update candlestick box position values', function (done) { function assertBoxPosFields(bPos) { expect(gd.calcdata.length).toEqual(bPos.length); - gd.calcdata.forEach(function(calcTrace, i) { + gd.calcdata.forEach(function (calcTrace, i) { expect(calcTrace[0].t.bPos).toBeCloseTo(bPos[i], 0); }); } @@ -736,123 +750,133 @@ describe('finance charts updates:', function() { close: [2, 3] }; - Plotly.newPlot(gd, [trace0], {boxmode: 'group'}) - .then(function() { - assertBoxPosFields([0]); + Plotly.newPlot(gd, [trace0], { boxmode: 'group' }) + .then(function () { + assertBoxPosFields([0]); - return Plotly.addTraces(gd, [Lib.extendDeep({}, trace0)]); - }) - .then(function() { - assertBoxPosFields([-15120000, 15120000]); + return Plotly.addTraces(gd, [Lib.extendDeep({}, trace0)]); + }) + .then(function () { + assertBoxPosFields([-15120000, 15120000]); + + var update = { + type: 'candlestick', + x: [ + ['2011-01-01', '2011-01-05'], + ['2011-01-01', '2011-01-03'] + ], + open: [[1, 0]], + high: [[3, 2]], + low: [[0, -1]], + close: [[2, 1]] + }; - var update = { - type: 'candlestick', - x: [['2011-01-01', '2011-01-05'], ['2011-01-01', '2011-01-03']], - open: [[1, 0]], - high: [[3, 2]], - low: [[0, -1]], - close: [[2, 1]] - }; - - return Plotly.restyle(gd, update); - }) - .then(function() { - assertBoxPosFields([-30240000, 30240000]); - }) - .then(done, done.fail); + return Plotly.restyle(gd, update); + }) + .then(function () { + assertBoxPosFields([-30240000, 30240000]); + }) + .then(done, done.fail); }); - it('Plotly.newPlot with data-less trace and adding with Plotly.restyle', function(done) { - var data = [ - { type: 'candlestick' }, - { type: 'ohlc' }, - { type: 'bar', y: [2, 1, 2] } - ]; - - Plotly.newPlot(gd, data).then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(0); - expect(countRangeSliders()).toEqual(0); - - return Plotly.restyle(gd, { - open: [mock0.open], - high: [mock0.high], - low: [mock0.low], - close: [mock0.close] - }, [0]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(0); - expect(countBoxTraces()).toEqual(1); - expect(countRangeSliders()).toEqual(1); - - return Plotly.restyle(gd, { - open: [mock0.open], - high: [mock0.high], - low: [mock0.low], - close: [mock0.close] - }, [1]); - }) - .then(function() { - expect(countOHLCTraces()).toEqual(1); - expect(countBoxTraces()).toEqual(1); - expect(countRangeSliders()).toEqual(1); - }) - .then(done, done.fail); + it('Plotly.newPlot with data-less trace and adding with Plotly.restyle', function (done) { + var data = [{ type: 'candlestick' }, { type: 'ohlc' }, { type: 'bar', y: [2, 1, 2] }]; + + Plotly.newPlot(gd, data) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(0); + expect(countRangeSliders()).toEqual(0); + + return Plotly.restyle( + gd, + { + open: [mock0.open], + high: [mock0.high], + low: [mock0.low], + close: [mock0.close] + }, + [0] + ); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(0); + expect(countBoxTraces()).toEqual(1); + expect(countRangeSliders()).toEqual(1); + + return Plotly.restyle( + gd, + { + open: [mock0.open], + high: [mock0.high], + low: [mock0.low], + close: [mock0.close] + }, + [1] + ); + }) + .then(function () { + expect(countOHLCTraces()).toEqual(1); + expect(countBoxTraces()).toEqual(1); + expect(countRangeSliders()).toEqual(1); + }) + .then(done, done.fail); }); - it('should be able to update ohlc tickwidth', function(done) { - var trace0 = Lib.extendDeep({}, mock0, {type: 'ohlc'}); + it('should be able to update ohlc tickwidth', function (done) { + var trace0 = Lib.extendDeep({}, mock0, { type: 'ohlc' }); function _assert(msg, exp) { var tickLen = gd.calcdata[0][0].t.tickLen; - expect(tickLen) - .toBe(exp.tickLen, 'tickLen val in calcdata - ' + msg); + expect(tickLen).toBe(exp.tickLen, 'tickLen val in calcdata - ' + msg); var pathd = d3Select(gd).select('.ohlc > path').attr('d'); - expect(pathd) - .toBe(exp.pathd, 'path d attr - ' + msg); + expect(pathd).toBe(exp.pathd, 'path d attr - ' + msg); } Plotly.newPlot(gd, [trace0], { - xaxis: { rangeslider: {visible: false} } - }) - .then(function() { - _assert('auto rng / base tickwidth', { - tickLen: 0.3, - pathd: 'M13.5,137.63H33.75M33.75,75.04V206.53M54,80.3H33.75' - }); - return Plotly.restyle(gd, 'tickwidth', 0); + xaxis: { rangeslider: { visible: false } } }) - .then(function() { - _assert('auto rng / no tickwidth', { - tickLen: 0, - pathd: 'M33.75,137.63H33.75M33.75,75.04V206.53M33.75,80.3H33.75' - }); + .then(function () { + _assert('auto rng / base tickwidth', { + tickLen: 0.3, + pathd: 'M13.5,137.63H33.75M33.75,75.04V206.53M54,80.3H33.75' + }); + return Plotly.restyle(gd, 'tickwidth', 0); + }) + .then(function () { + _assert('auto rng / no tickwidth', { + tickLen: 0, + pathd: 'M33.75,137.63H33.75M33.75,75.04V206.53M33.75,80.3H33.75' + }); - return Plotly.update(gd, { - tickwidth: null - }, { - 'xaxis.range': [0, 8], - 'yaxis.range': [30, 36] - }); - }) - .then(function() { - _assert('set rng / base tickwidth', { - tickLen: 0.3, - pathd: 'M-20.25,134.55H0M0,81V193.5M20.25,85.5H0' - }); - return Plotly.restyle(gd, 'tickwidth', 0); - }) - .then(function() { - _assert('set rng / no tickwidth', { - tickLen: 0, - pathd: 'M0,134.55H0M0,81V193.5M0,85.5H0' - }); - }) - .then(done, done.fail); + return Plotly.update( + gd, + { + tickwidth: null + }, + { + 'xaxis.range': [0, 8], + 'yaxis.range': [30, 36] + } + ); + }) + .then(function () { + _assert('set rng / base tickwidth', { + tickLen: 0.3, + pathd: 'M-20.25,134.55H0M0,81V193.5M20.25,85.5H0' + }); + return Plotly.restyle(gd, 'tickwidth', 0); + }) + .then(function () { + _assert('set rng / no tickwidth', { + tickLen: 0, + pathd: 'M0,134.55H0M0,81V193.5M0,85.5H0' + }); + }) + .then(done, done.fail); }); - it('should work with typed array', function(done) { + it('should work with typed array', function (done) { var mockTA = { open: new Float32Array(mock0.open), high: new Float32Array(mock0.high), @@ -861,82 +885,87 @@ describe('finance charts updates:', function() { }; var dataTA = [ - Lib.extendDeep({}, mockTA, {type: 'ohlc'}), - Lib.extendDeep({}, mockTA, {type: 'candlestick'}), + Lib.extendDeep({}, mockTA, { type: 'ohlc' }), + Lib.extendDeep({}, mockTA, { type: 'candlestick' }) ]; - var data0 = [ - Lib.extendDeep({}, mock0, {type: 'ohlc'}), - Lib.extendDeep({}, mock0, {type: 'candlestick'}), - ]; + var data0 = [Lib.extendDeep({}, mock0, { type: 'ohlc' }), Lib.extendDeep({}, mock0, { type: 'candlestick' })]; Plotly.newPlot(gd, dataTA) - .then(function() { - expect(countOHLCTraces()).toBe(1, '# of ohlc traces'); - expect(countBoxTraces()).toBe(1, '# of candlestick traces'); - }) - .then(function() { return Plotly.react(gd, data0); }) - .then(function() { - expect(countOHLCTraces()).toBe(1, '# of ohlc traces'); - expect(countBoxTraces()).toBe(1, '# of candlestick traces'); - }) - .then(done, done.fail); + .then(function () { + expect(countOHLCTraces()).toBe(1, '# of ohlc traces'); + expect(countBoxTraces()).toBe(1, '# of candlestick traces'); + }) + .then(function () { + return Plotly.react(gd, data0); + }) + .then(function () { + expect(countOHLCTraces()).toBe(1, '# of ohlc traces'); + expect(countBoxTraces()).toBe(1, '# of candlestick traces'); + }) + .then(done, done.fail); }); - it('should clear empty candlestick boxes using react', function(done) { + it('should clear empty candlestick boxes using react', function (done) { var type = 'candlestick'; var x = [0, 1]; - var steps = [{ - data: [{ - close: [132, null], - high: [204, 20], - low: [30, 193], - open: [78, 79], - type: type, - x: x - }], - layout: {} - }, - { - data: [{ - close: [140, 78], - high: [91, 117], - low: [115, 78], - open: [null, 97], - type: type, - x: x - }], - layout: {} - }]; + var steps = [ + { + data: [ + { + close: [132, null], + high: [204, 20], + low: [30, 193], + open: [78, 79], + type: type, + x: x + } + ], + layout: {} + }, + { + data: [ + { + close: [140, 78], + high: [91, 117], + low: [115, 78], + open: [null, 97], + type: type, + x: x + } + ], + layout: {} + } + ]; Plotly.newPlot(gd, steps[0]) - .then(function() { - return Plotly.react(gd, steps[1]); - }).then(function() { - expect( - d3Select('g.cartesianlayer') - .selectAll('g.trace.boxes') - .selectAll('path') - .node() - .getAttribute('d') - ).toEqual('M0,0Z'); - }) - .then(done, done.fail); + .then(function () { + return Plotly.react(gd, steps[1]); + }) + .then(function () { + expect( + d3Select('g.cartesianlayer').selectAll('g.trace.boxes').selectAll('path').node().getAttribute('d') + ).toEqual('M0,0Z'); + }) + .then(done, done.fail); }); }); -describe('finance charts *special* handlers:', function() { +describe('finance charts *special* handlers:', function () { // not special anymore - just test that they work as normal afterEach(destroyGraphDiv); - it('`editable: true` handlers should work', function(done) { + it('`editable: true` handlers should work', function (done) { var gd = createGraphDiv(); function editText(itemNumber, newText) { var textNode = d3SelectAll('text.legendtext') - .filter(function(_, i) { return i === itemNumber; }).node(); + .filter(function (_, i) { + return i === itemNumber; + }) + .node(); textNode.dispatchEvent(new window.MouseEvent('click')); var editNode = d3Select('.plugin-editable.editable').node(); @@ -952,42 +981,46 @@ describe('finance charts *special* handlers:', function() { // of the rendering queue to make sure the edit